summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:00:07 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:00:07 +0000
commit7fe2412222a5198f9e169ce0effa8318320fe3ad (patch)
treea7ce485be0cac8f35324dc264f433104555c8424
parent4f97d6740411fb53a4fb5f6e1af03e1f1b28c1ba (diff)
parent8d2c5b2edb9023b91d79709f2900ee1b643a3127 (diff)
downloadadhd-aml_tz2_305400100.tar.gz
Change-Id: I127ce133361317d9ebfb8ef2a903afdd64a6feeb
-rw-r--r--.github/workflows/codeql-analysis.yml65
-rw-r--r--Android.bp52
-rw-r--r--METADATA3
-rw-r--r--Makefile10
-rw-r--r--OWNERS.fuzz5
-rw-r--r--PRESUBMIT.cfg7
-rw-r--r--alsa-module-config/alsa-cid.conf1
-rw-r--r--alsa-module-config/alsa-falco.conf1
-rw-r--r--alsa-module-config/alsa-jecht.conf1
-rw-r--r--alsa-module-config/alsa-leon.conf1
-rw-r--r--alsa-module-config/alsa-mccloud.conf1
-rw-r--r--alsa-module-config/alsa-monroe.conf1
-rw-r--r--alsa-module-config/alsa-peppy.conf1
-rw-r--r--alsa-module-config/alsa-rikku.conf1
-rw-r--r--alsa-module-config/alsa-stout.conf2
-rw-r--r--alsa-module-config/alsa-stout32.conf2
-rw-r--r--alsa-module-config/alsa-tidus.conf1
-rw-r--r--alsa-module-config/alsa-tricky.conf1
-rw-r--r--alsa-module-config/alsa-wolf.conf1
-rw-r--r--alsa-module-config/alsa-zako.conf1
-rw-r--r--alsa-module-config/cid_alsa.fw9
-rw-r--r--alsa-module-config/falco_alsa.fw9
-rw-r--r--alsa-module-config/jecht_alsa.fw9
-rw-r--r--alsa-module-config/leon_alsa.fw9
-rw-r--r--alsa-module-config/mccloud_alsa.fw9
-rw-r--r--alsa-module-config/monroe_alsa.fw9
-rw-r--r--alsa-module-config/peppy_alsa.fw9
-rw-r--r--alsa-module-config/rikku_alsa.fw9
-rw-r--r--alsa-module-config/stout32_alsa.fw9
-rw-r--r--alsa-module-config/stout_alsa.fw9
-rw-r--r--alsa-module-config/tidus_alsa.fw9
-rw-r--r--alsa-module-config/tricky_alsa.fw9
-rw-r--r--alsa-module-config/wolf_alsa.fw9
-rw-r--r--alsa-module-config/zako_alsa.fw9
-rw-r--r--audio_streams/.gitignore2
-rw-r--r--audio_streams/Android.bp53
-rw-r--r--audio_streams/Cargo.toml2
-rw-r--r--audio_streams/README.md2
-rw-r--r--audio_streams/src/audio_streams.rs216
-rw-r--r--audio_streams/src/capture.rs77
-rw-r--r--audio_streams/src/shm_streams.rs568
-rw-r--r--cras-config/bolt/HDA Intel PCH107
-rw-r--r--cras-config/cid/HDA Intel PCH107
-rwxr-xr-xcras-config/daisy/DAISY-I2S107
-rwxr-xr-xcras-config/daisy/DAISY-I2S-98090206
-rw-r--r--cras-config/daisy/dsp.ini46
-rw-r--r--cras-config/daisy_skate/dsp.ini111
-rwxr-xr-xcras-config/daisy_spring/DAISY-I2S206
-rw-r--r--cras-config/daisy_spring/dsp.ini95
-rw-r--r--cras-config/device_blacklist (renamed from cras-config/device_blocklist)0
-rw-r--r--cras-config/falco/HDA Intel PCH107
-rw-r--r--cras-config/falco/dsp.ini111
-rw-r--r--cras-config/leon/HDA Intel PCH107
-rw-r--r--cras-config/leon/dsp.ini79
-rw-r--r--cras-config/link/HDA Intel PCH107
-rw-r--r--cras-config/peppy/HDA Intel PCH107
-rw-r--r--cras-config/peppy/dsp.ini119
-rw-r--r--cras-config/stout/HDA Intel PCH107
l---------cras-config/veryon_jerry-kernelnext1
-rw-r--r--cras-config/veyron_jaq/ROCKCHIP-I2S107
-rw-r--r--cras-config/veyron_jaq/VEYRON-I2S107
-rw-r--r--cras-config/veyron_jaq/dsp.ini119
-rw-r--r--cras-config/veyron_jerry/ROCKCHIP-I2S107
-rw-r--r--cras-config/veyron_jerry/VEYRON-I2S107
-rw-r--r--cras-config/veyron_jerry/dsp.ini79
-rw-r--r--cras-config/veyron_mighty/ROCKCHIP-I2S107
-rw-r--r--cras-config/veyron_mighty/VEYRON-I2S107
-rw-r--r--cras-config/veyron_mighty/dsp.ini119
l---------cras-config/veyron_minnie-kernelnext1
-rw-r--r--cras-config/veyron_minnie/ROCKCHIP-I2S107
-rw-r--r--cras-config/veyron_minnie/VEYRON-I2S107
-rw-r--r--cras-config/veyron_minnie/dsp.ini79
-rw-r--r--cras-config/veyron_speedy/ROCKCHIP-I2S107
-rw-r--r--cras-config/veyron_speedy/VEYRON-I2S107
-rw-r--r--cras-config/veyron_speedy/dsp.ini79
-rw-r--r--cras-config/whirlwind/dsp.ini95
-rw-r--r--cras-config/wolf/HDA Intel PCH107
-rw-r--r--cras-config/wolf/dsp.ini103
-rw-r--r--cras/Makefile.am7
-rw-r--r--cras/README (renamed from cras/README.md)105
-rw-r--r--cras/README.dbus-api22
-rw-r--r--cras/client/cras-sys/.gitignore4
-rw-r--r--cras/client/cras-sys/Android.bp50
-rw-r--r--cras/client/cras-sys/Cargo.toml3
-rw-r--r--cras/client/cras-sys/generator/src/main.rs7
-rw-r--r--cras/client/cras-sys/src/gen.rs942
-rw-r--r--cras/client/cras-sys/src/lib.rs623
-rw-r--r--cras/client/cras_tests/Cargo.toml8
-rw-r--r--cras/client/cras_tests/src/arguments.rs462
-rw-r--r--cras/client/cras_tests/src/audio.rs414
-rw-r--r--cras/client/cras_tests/src/audio_options.rs194
-rw-r--r--cras/client/cras_tests/src/control.rs106
-rw-r--r--cras/client/cras_tests/src/main.rs155
-rw-r--r--cras/client/libcras/.gitignore5
-rw-r--r--cras/client/libcras/Android.bp53
-rw-r--r--cras/client/libcras/Cargo.toml4
-rw-r--r--cras/client/libcras/src/cras_client_message.rs71
-rw-r--r--cras/client/libcras/src/cras_server_socket.rs72
-rw-r--r--cras/client/libcras/src/cras_shm.rs439
-rw-r--r--cras/client/libcras/src/cras_shm_stream.rs191
-rw-r--r--cras/client/libcras/src/cras_stream.rs182
-rw-r--r--cras/client/libcras/src/libcras.rs491
-rw-r--r--cras/configure.ac42
-rwxr-xr-xcras/install_deps.sh51
-rw-r--r--cras/src/Android.bp10
-rw-r--r--cras/src/Makefile.am159
-rw-r--r--cras/src/alsa_plugin/ctl_cras.c78
-rw-r--r--cras/src/alsa_plugin/pcm_cras.c4
-rw-r--r--cras/src/common/bluetooth.h8
-rw-r--r--cras/src/common/cras_audio_format.c15
-rw-r--r--cras/src/common/cras_audio_format.h19
-rw-r--r--cras/src/common/cras_config.c12
-rw-r--r--cras/src/common/cras_config.h7
-rw-r--r--cras/src/common/cras_file_wait.c2
-rw-r--r--cras/src/common/cras_iodev_info.h6
-rw-r--r--cras/src/common/cras_messages.h74
-rw-r--r--cras/src/common/cras_observer_ops.h7
-rw-r--r--cras/src/common/cras_shm.c33
-rw-r--r--cras/src/common/cras_shm.h13
-rw-r--r--cras/src/common/cras_types.h124
-rw-r--r--cras/src/common/cras_util.h27
-rw-r--r--cras/src/common/dumper.c15
-rw-r--r--cras/src/common/packet_status_logger.c35
-rw-r--r--cras/src/common/packet_status_logger.h127
-rw-r--r--cras/src/common/utlist.h1
-rw-r--r--cras/src/dsp/drc.c2
-rw-r--r--cras/src/dsp/drc_kernel.c24
-rw-r--r--cras/src/dsp/drc_kernel.h2
-rw-r--r--cras/src/fuzz/Dockerfile56
-rw-r--r--cras/src/fuzz/README.md20
-rwxr-xr-xcras/src/fuzz/build.sh30
-rw-r--r--cras/src/fuzz/cras_hfp_slc.cc66
-rw-r--r--cras/src/fuzz/cras_hfp_slc.dict23
-rw-r--r--cras/src/fuzz/rclient_message.cc26
-rw-r--r--cras/src/libcras/cras_client.c648
-rw-r--r--cras/src/libcras/cras_client.h786
-rw-r--r--cras/src/plc/cras_plc.c119
-rw-r--r--cras/src/plc/cras_plc_test.c138
-rwxr-xr-xcras/src/plc/parse_sco.py107
-rw-r--r--cras/src/server/audio_thread.c102
-rw-r--r--cras/src/server/audio_thread.h42
-rw-r--r--cras/src/server/config/cras_board_config.c62
-rw-r--r--cras/src/server/config/cras_board_config.h4
-rw-r--r--cras/src/server/config/cras_card_config.c34
-rw-r--r--cras/src/server/config/cras_device_blacklist.c60
-rw-r--r--cras/src/server/config/cras_device_blacklist.h (renamed from cras/src/server/config/cras_device_blocklist.h)30
-rw-r--r--cras/src/server/config/cras_device_blocklist.c56
-rw-r--r--cras/src/server/cras.c4
-rw-r--r--cras/src/server/cras_a2dp_info.c5
-rw-r--r--cras/src/server/cras_a2dp_info.h6
-rw-r--r--cras/src/server/cras_a2dp_iodev.c444
-rw-r--r--cras/src/server/cras_alsa_card.c81
-rw-r--r--cras/src/server/cras_alsa_card.h6
-rw-r--r--cras/src/server/cras_alsa_helpers.c63
-rw-r--r--cras/src/server/cras_alsa_helpers.h5
-rw-r--r--cras/src/server/cras_alsa_io.c462
-rw-r--r--cras/src/server/cras_alsa_io.h7
-rw-r--r--cras/src/server/cras_alsa_jack.c101
-rw-r--r--cras/src/server/cras_alsa_mixer.c16
-rw-r--r--cras/src/server/cras_alsa_mixer.h5
-rw-r--r--cras/src/server/cras_alsa_plugin_io.c265
-rw-r--r--cras/src/server/cras_alsa_plugin_io.h20
-rw-r--r--cras/src/server/cras_alsa_ucm.c669
-rw-r--r--cras/src/server/cras_alsa_ucm.h165
-rw-r--r--cras/src/server/cras_alsa_ucm_section.c21
-rw-r--r--cras/src/server/cras_alsa_ucm_section.h12
-rw-r--r--cras/src/server/cras_apm_list.c197
-rw-r--r--cras/src/server/cras_apm_list.h86
-rw-r--r--cras/src/server/cras_audio_thread_monitor.c15
-rw-r--r--cras/src/server/cras_audio_thread_monitor.h15
-rw-r--r--cras/src/server/cras_bt_battery_provider.c371
-rw-r--r--cras/src/server/cras_bt_battery_provider.h47
-rw-r--r--cras/src/server/cras_bt_constants.h34
-rw-r--r--cras/src/server/cras_bt_device.c334
-rw-r--r--cras/src/server/cras_bt_device.h26
-rw-r--r--cras/src/server/cras_bt_io.c179
-rw-r--r--cras/src/server/cras_bt_io.h6
-rw-r--r--cras/src/server/cras_bt_manager.c56
-rw-r--r--cras/src/server/cras_bt_player.c328
-rw-r--r--cras/src/server/cras_bt_player.h53
-rw-r--r--cras/src/server/cras_bt_profile.c53
-rw-r--r--cras/src/server/cras_bt_profile.h23
-rw-r--r--cras/src/server/cras_bt_transport.c38
-rw-r--r--cras/src/server/cras_capture_rclient.c76
-rw-r--r--cras/src/server/cras_control_rclient.c95
-rw-r--r--cras/src/server/cras_dbus.c5
-rw-r--r--cras/src/server/cras_dbus_control.c409
-rw-r--r--cras/src/server/cras_device_monitor.c20
-rw-r--r--cras/src/server/cras_device_monitor.h4
-rw-r--r--cras/src/server/cras_dsp.c43
-rw-r--r--cras/src/server/cras_dsp.h6
-rw-r--r--cras/src/server/cras_dsp_ini.c23
-rw-r--r--cras/src/server/cras_dsp_ini.h8
-rw-r--r--cras/src/server/cras_dsp_pipeline.c35
-rw-r--r--cras/src/server/cras_empty_iodev.c15
-rw-r--r--cras/src/server/cras_fmt_conv.c149
-rw-r--r--cras/src/server/cras_fmt_conv_ops.c149
-rw-r--r--cras/src/server/cras_fmt_conv_ops.h21
-rw-r--r--cras/src/server/cras_hfp_ag_profile.c47
-rw-r--r--cras/src/server/cras_hfp_ag_profile.h17
-rw-r--r--cras/src/server/cras_hfp_alsa_iodev.c96
-rw-r--r--cras/src/server/cras_hfp_info.c328
-rw-r--r--cras/src/server/cras_hfp_info.h12
-rw-r--r--cras/src/server/cras_hfp_iodev.c47
-rw-r--r--cras/src/server/cras_hfp_iodev.h7
-rw-r--r--cras/src/server/cras_hfp_slc.c748
-rw-r--r--cras/src/server/cras_hfp_slc.h47
-rw-r--r--cras/src/server/cras_iodev.c246
-rw-r--r--cras/src/server/cras_iodev.h135
-rw-r--r--cras/src/server/cras_iodev_list.c375
-rw-r--r--cras/src/server/cras_iodev_list.h5
-rw-r--r--cras/src/server/cras_loopback_iodev.c46
-rw-r--r--cras/src/server/cras_main_message.c5
-rw-r--r--cras/src/server/cras_main_thread_log.h64
-rw-r--r--cras/src/server/cras_observer.c74
-rw-r--r--cras/src/server/cras_observer.h8
-rw-r--r--cras/src/server/cras_playback_rclient.c76
-rw-r--r--cras/src/server/cras_ramp.c6
-rw-r--r--cras/src/server/cras_rclient.c20
-rw-r--r--cras/src/server/cras_rclient.h4
-rw-r--r--cras/src/server/cras_rclient_util.c124
-rw-r--r--cras/src/server/cras_rclient_util.h56
-rw-r--r--cras/src/server/cras_rstream.c200
-rw-r--r--cras/src/server/cras_rstream.h102
-rw-r--r--cras/src/server/cras_rstream_config.c77
-rw-r--r--cras/src/server/cras_rstream_config.h101
-rw-r--r--cras/src/server/cras_server.c26
-rw-r--r--cras/src/server/cras_server_metrics.c513
-rw-r--r--cras/src/server/cras_server_metrics.h51
-rw-r--r--cras/src/server/cras_system_state.c218
-rw-r--r--cras/src/server/cras_system_state.h79
-rw-r--r--cras/src/server/cras_telephony.c52
-rw-r--r--cras/src/server/cras_udev.c9
-rw-r--r--cras/src/server/cras_unified_rclient.c37
-rw-r--r--cras/src/server/cras_unified_rclient.h21
-rw-r--r--cras/src/server/dev_io.c356
-rw-r--r--cras/src/server/dev_io.h14
-rw-r--r--cras/src/server/dev_stream.c40
-rw-r--r--cras/src/server/dev_stream.h27
-rw-r--r--cras/src/server/ewma_power.c81
-rw-r--r--cras/src/server/ewma_power.h65
-rw-r--r--cras/src/server/float_buffer.h2
-rw-r--r--cras/src/server/iniparser_wrapper.h8
-rw-r--r--cras/src/server/input_data.c23
-rw-r--r--cras/src/server/input_data.h17
-rw-r--r--cras/src/server/rate_estimator.c109
-rw-r--r--cras/src/server/rate_estimator.h86
-rw-r--r--cras/src/server/rust/.gitignore1
-rw-r--r--cras/src/server/rust/Cargo.toml17
-rw-r--r--cras/src/server/rust/binding_generator/Cargo.toml8
-rw-r--r--cras/src/server/rust/binding_generator/src/main.rs27
-rw-r--r--cras/src/server/rust/src/headers/rate_estimator.h85
-rw-r--r--cras/src/server/rust/src/rate_estimator.rs188
-rw-r--r--cras/src/server/rust/src/rate_estimator_bindings.rs110
-rw-r--r--cras/src/server/server_stream.c23
-rw-r--r--cras/src/server/server_stream.h4
-rw-r--r--cras/src/server/stream_list.c41
-rw-r--r--cras/src/server/stream_list.h15
-rw-r--r--cras/src/server/test_iodev.c18
-rw-r--r--cras/src/tests/a2dp_info_unittest.cc4
-rw-r--r--cras/src/tests/a2dp_iodev_unittest.cc684
-rw-r--r--cras/src/tests/alsa_card_unittest.cc176
-rw-r--r--cras/src/tests/alsa_helpers_unittest.cc34
-rw-r--r--cras/src/tests/alsa_io_unittest.cc594
-rw-r--r--cras/src/tests/alsa_jack_unittest.cc47
-rw-r--r--cras/src/tests/alsa_mixer_unittest.cc47
-rw-r--r--cras/src/tests/alsa_ucm_unittest.cc437
-rw-r--r--cras/src/tests/apm_list_unittest.cc192
-rw-r--r--cras/src/tests/audio_thread_unittest.cc31
-rw-r--r--cras/src/tests/audio_thread_unittest_obsolete.cc52
-rw-r--r--cras/src/tests/bt_device_unittest.cc202
-rw-r--r--cras/src/tests/bt_io_unittest.cc49
-rw-r--r--cras/src/tests/capture_rclient_unittest.cc87
-rw-r--r--cras/src/tests/control_rclient_unittest.cc152
-rw-r--r--cras/src/tests/cras_abi_unittest.cc139
-rw-r--r--cras/src/tests/dev_io_stubs.cc5
-rw-r--r--cras/src/tests/dev_io_unittest.cc209
-rw-r--r--cras/src/tests/dev_stream_unittest.cc91
-rw-r--r--cras/src/tests/device_blacklist_unittest.cc88
-rw-r--r--cras/src/tests/device_blocklist_unittest.cc88
-rw-r--r--cras/src/tests/empty_iodev_unittest.cc4
-rw-r--r--cras/src/tests/ewma_power_unittest.cc129
-rw-r--r--cras/src/tests/fmt_conv_ops_unittest.cc187
-rw-r--r--cras/src/tests/fmt_conv_unittest.cc76
-rw-r--r--cras/src/tests/hfp_ag_profile_unittest.cc46
-rw-r--r--cras/src/tests/hfp_alsa_iodev_unittest.cc64
-rw-r--r--cras/src/tests/hfp_info_unittest.cc154
-rw-r--r--cras/src/tests/hfp_iodev_unittest.cc41
-rw-r--r--cras/src/tests/hfp_slc_unittest.cc169
-rw-r--r--cras/src/tests/input_data_unittest.cc54
-rw-r--r--cras/src/tests/iodev_list_unittest.cc527
-rw-r--r--cras/src/tests/iodev_stub.cc40
-rw-r--r--cras/src/tests/iodev_stub.h6
-rw-r--r--cras/src/tests/iodev_unittest.cc160
-rw-r--r--cras/src/tests/loopback_iodev_unittest.cc26
-rw-r--r--cras/src/tests/metrics_stub.cc19
-rw-r--r--cras/src/tests/observer_unittest.cc69
-rw-r--r--cras/src/tests/playback_rclient_unittest.cc85
-rw-r--r--cras/src/tests/polled_interval_checker_unittest.cc4
-rw-r--r--cras/src/tests/ramp_unittest.cc38
-rw-r--r--cras/src/tests/rate_estimator_unittest.cc6
-rw-r--r--cras/src/tests/rstream_unittest.cc35
-rw-r--r--cras/src/tests/server_metrics_unittest.cc176
-rw-r--r--cras/src/tests/stream_list_unittest.cc129
-rw-r--r--cras/src/tests/system_state_unittest.cc157
-rw-r--r--cras/src/tests/timing_unittest.cc98
-rw-r--r--cras/src/tools/cras_monitor/cras_monitor.c7
-rw-r--r--cras/src/tools/cras_test_client/cras_test_client.c430
-rw-r--r--cros_alsa/.gitignore3
-rw-r--r--cros_alsa/.rustfmt.toml2
-rw-r--r--cros_alsa/Cargo.toml15
-rw-r--r--cros_alsa/cros_alsa_derive/Cargo.toml14
-rw-r--r--cros_alsa/cros_alsa_derive/src/common.rs77
-rw-r--r--cros_alsa/cros_alsa_derive/src/control.rs40
-rw-r--r--cros_alsa/cros_alsa_derive/src/lib.rs26
-rw-r--r--cros_alsa/src/card.rs117
-rw-r--r--cros_alsa/src/control.rs297
-rw-r--r--cros_alsa/src/control_primitive.rs406
-rw-r--r--cros_alsa/src/control_tlv.rs313
-rw-r--r--cros_alsa/src/elem.rs204
-rw-r--r--cros_alsa/src/lib.rs61
-rw-r--r--init/cras.conf17
-rw-r--r--init/cras.sh8
-rwxr-xr-xscripts/asoc_dapm_graph2
-rwxr-xr-xscripts/audio_diagnostics99
-rw-r--r--scripts/audio_tuning/frontend/audio.js12
-rw-r--r--scripts/volume_tuning/volume.js2
-rw-r--r--seccomp/cras-seccomp-amd64.policy7
-rw-r--r--seccomp/cras-seccomp-arm.policy12
-rw-r--r--seccomp/cras-seccomp-arm64.policy6
-rw-r--r--sof_sys/.gitignore2
-rw-r--r--sof_sys/.rustfmt.toml2
-rw-r--r--sof_sys/Cargo.toml4
-rw-r--r--sof_sys/generator/.gitignore1
-rw-r--r--sof_sys/generator/Cargo.toml6
-rw-r--r--sof_sys/generator/README.md1
-rw-r--r--sof_sys/generator/src/main.rs42
-rw-r--r--sof_sys/generator/wrapper.h5
-rw-r--r--sof_sys/src/bindings.rs154
-rw-r--r--sof_sys/src/lib.rs12
-rw-r--r--sound_card_init/.gitignore6
-rw-r--r--sound_card_init/99-sound_card_init.rules13
-rw-r--r--sound_card_init/Cargo.lock286
-rw-r--r--sound_card_init/Cargo.toml33
-rw-r--r--sound_card_init/amp/Cargo.lock254
-rw-r--r--sound_card_init/amp/Cargo.toml16
-rw-r--r--sound_card_init/amp/src/lib.rs58
-rw-r--r--sound_card_init/amp/src/max98373d/dsm_param.rs211
-rw-r--r--sound_card_init/amp/src/max98373d/mod.rs274
-rw-r--r--sound_card_init/amp/src/max98373d/settings.rs41
-rw-r--r--sound_card_init/amp/src/max98390d/mod.rs213
-rw-r--r--sound_card_init/amp/src/max98390d/settings.rs51
-rw-r--r--sound_card_init/dsm/Cargo.lock229
-rw-r--r--sound_card_init/dsm/Cargo.toml15
-rw-r--r--sound_card_init/dsm/src/datastore.rs72
-rw-r--r--sound_card_init/dsm/src/error.rs128
-rw-r--r--sound_card_init/dsm/src/lib.rs335
-rw-r--r--sound_card_init/dsm/src/utils.rs82
-rw-r--r--sound_card_init/dsm/src/vpd.rs41
-rw-r--r--sound_card_init/dsm/src/zero_player.rs209
-rw-r--r--sound_card_init/seccomp/sound_card_init-seccomp-amd64.policy82
-rw-r--r--sound_card_init/sound_card_init.conf80
-rw-r--r--sound_card_init/src/main.rs131
-rw-r--r--ucm-config/bolt/HDA Intel PCH/HDA Intel PCH.conf (renamed from ucm-config/for_all_boards/Pixel USB-C earbuds/Pixel USB-C earbuds.conf)2
-rw-r--r--ucm-config/bolt/HDA Intel PCH/HiFi.conf67
l---------ucm-config/chell1
-rw-r--r--ucm-config/cid/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/cid/HDA Intel PCH/HiFi.conf55
-rw-r--r--ucm-config/daisy/DAISY-I2S-98090/DAISY-I2S-98090.conf (renamed from ucm-config/for_all_boards/Dell AC511 USB SoundBar/Dell AC511 USB SoundBar.conf)2
-rw-r--r--ucm-config/daisy/DAISY-I2S-98090/HiFi.conf107
-rw-r--r--ucm-config/daisy/DAISY-I2S/DAISY-I2S.conf (renamed from ucm-config/for_all_boards/PCP-USB/PCP-USB.conf)2
-rw-r--r--ucm-config/daisy/DAISY-I2S/HiFi.conf142
-rw-r--r--ucm-config/daisy_skate/DAISY-I2S/DAISY-I2S.conf6
-rw-r--r--ucm-config/daisy_skate/DAISY-I2S/HiFi.conf70
-rw-r--r--ucm-config/daisy_spring/DAISY-I2S/DAISY-I2S.conf (renamed from ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HUAWEI USB-C HEADSET.conf)2
-rw-r--r--ucm-config/daisy_spring/DAISY-I2S/HiFi.conf90
-rw-r--r--ucm-config/falco/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/falco/HDA Intel PCH/HiFi.conf55
-rw-r--r--ucm-config/for_all_boards/C505 HD Webcam/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/Chat 150 C/HiFi.conf2
-rw-r--r--ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/DELL PROFESSIONAL SOUND BAR AE5.conf6
-rw-r--r--ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/HiFi.conf27
-rw-r--r--ucm-config/for_all_boards/Dell AC511 USB SoundBar/HiFi.conf30
-rw-r--r--ucm-config/for_all_boards/Dell-WD15-Dock/Dell-WD15-Dock.conf5
-rw-r--r--ucm-config/for_all_boards/Dell-WD15-Dock/HiFi.conf40
-rw-r--r--ucm-config/for_all_boards/HD Pro Webcam C920/HD Pro Webcam C920.conf6
-rw-r--r--ucm-config/for_all_boards/HD Pro Webcam C920/HiFi.conf28
-rw-r--r--ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/ICUSBAUDIO7D/HiFi.conf132
-rw-r--r--ucm-config/for_all_boards/Jabra SPEAK 810/HiFi.conf2
-rw-r--r--ucm-config/for_all_boards/Logitech BRIO/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/Logitech Webcam C930e/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/Logitech Webcam C930e/Logitech Webcam C930e.conf6
-rw-r--r--ucm-config/for_all_boards/Loopback/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/Mi Dual Driver Earphones Type-C.conf6
-rw-r--r--ucm-config/for_all_boards/PCP-USB/HiFi.conf20
-rw-r--r--ucm-config/for_all_boards/Pixel USB-C earbuds/HiFi.conf24
-rw-r--r--ucm-config/for_all_boards/Plankton Captured HDMI Audio/HiFi.conf24
-rw-r--r--ucm-config/for_all_boards/Plankton Captured HDMI Audio/Plankton Captured HDMI Audio.conf6
-rw-r--r--ucm-config/for_all_boards/Plantronics DA70/HiFi.conf28
-rw-r--r--ucm-config/for_all_boards/README8
-rw-r--r--ucm-config/for_all_boards/Scarlett 2i2 USB/HiFi.conf27
-rw-r--r--ucm-config/for_all_boards/Scarlett 2i4 USB/HiFi.conf27
-rw-r--r--ucm-config/for_all_boards/Scarlett 2i4 USB/Scarlett 2i4 USB.conf5
-rw-r--r--ucm-config/for_all_boards/USB 2.0 Camera/HiFi.conf25
-rw-r--r--ucm-config/for_all_boards/USB 2.0 Camera/USB 2.0 Camera6
-rw-r--r--ucm-config/glados/sklnau8825adi/HiFi.conf512
-rw-r--r--ucm-config/glados/sklnau8825adi/sklnau8825adi.conf (renamed from ucm-config/for_all_boards/C505 HD Webcam/C505 HD Webcam.conf)2
-rw-r--r--ucm-config/jecht/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/jecht/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/leon/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/leon/HDA Intel PCH/HiFi.conf55
-rw-r--r--ucm-config/link/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/link/HDA Intel PCH/HiFi.conf70
-rw-r--r--ucm-config/mccloud/HDA Intel PCH/HDA Intel PCH.conf (renamed from ucm-config/for_all_boards/ICUSBAUDIO7D/ICUSBAUDIO7D.conf)2
-rw-r--r--ucm-config/mccloud/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/monroe/HDA Intel MID/HDA Intel MID.conf (renamed from ucm-config/for_all_boards/Plantronics DA70/Plantronics DA70.conf)2
-rw-r--r--ucm-config/monroe/HDA Intel MID/HiFi.conf15
-rw-r--r--ucm-config/monroe/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/monroe/HDA Intel PCH/HiFi.conf37
-rw-r--r--ucm-config/panther/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/panther/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/peppy/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/peppy/HDA Intel PCH/HiFi.conf55
-rw-r--r--ucm-config/rikku/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/rikku/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/stout/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/stout/HDA Intel PCH/HiFi.conf62
-rw-r--r--ucm-config/strago/chtrt5645/HiFi.conf121
-rw-r--r--ucm-config/strago/chtrt5645/chtrt5645.conf6
-rw-r--r--ucm-config/strago/chtrt5650/HiFi.conf129
-rw-r--r--ucm-config/strago/chtrt5650/chtrt5650.conf6
-rw-r--r--ucm-config/strago/chtrt5676/HiFi.conf106
-rw-r--r--ucm-config/strago/chtrt5676/chtrt5676.conf6
-rw-r--r--ucm-config/tidus/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/tidus/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/tricky/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/tricky/HDA Intel PCH/HiFi.conf32
-rw-r--r--ucm-config/veyron/ROCKCHIP-I2S/HiFi.conf137
-rw-r--r--ucm-config/veyron/ROCKCHIP-I2S/ROCKCHIP-I2S.conf (renamed from ucm-config/for_all_boards/Logitech BRIO/Logitech BRIO.conf)2
-rw-r--r--ucm-config/veyron/RockchipHDMI/HiFi.conf12
-rw-r--r--ucm-config/veyron/RockchipHDMI/RockchipHDMI.conf6
-rw-r--r--ucm-config/veyron/VEYRON-I2S/HiFi.conf158
-rw-r--r--ucm-config/veyron/VEYRON-I2S/VEYRON-I2S.conf (renamed from ucm-config/for_all_boards/Loopback/Loopback.conf)2
-rw-r--r--ucm-config/veyron_fievel/ROCKCHIP-I2S/HiFi.conf103
-rw-r--r--ucm-config/veyron_fievel/ROCKCHIP-I2S/ROCKCHIP-I2S.conf (renamed from ucm-config/for_all_boards/Scarlett 2i2 USB/Scarlett 2i2 USB.conf)3
-rw-r--r--ucm-config/veyron_fievel/RockchipHDMI/HiFi.conf12
-rw-r--r--ucm-config/veyron_fievel/RockchipHDMI/RockchipHDMI.conf6
-rw-r--r--ucm-config/veyron_fievel/VEYRON-I2S/HiFi.conf120
-rw-r--r--ucm-config/veyron_fievel/VEYRON-I2S/VEYRON-I2S.conf6
-rw-r--r--ucm-config/veyron_jaq/ROCKCHIP-I2S/HiFi.conf142
-rw-r--r--ucm-config/veyron_jaq/ROCKCHIP-I2S/ROCKCHIP-I2S.conf6
-rw-r--r--ucm-config/veyron_jaq/RockchipHDMI/HiFi.conf12
-rw-r--r--ucm-config/veyron_jaq/RockchipHDMI/RockchipHDMI.conf6
-rw-r--r--ucm-config/veyron_jaq/VEYRON-I2S/HiFi.conf158
-rw-r--r--ucm-config/veyron_jaq/VEYRON-I2S/VEYRON-I2S.conf6
l---------ucm-config/veyron_minnie-kernelnext1
-rw-r--r--ucm-config/veyron_minnie/ROCKCHIP-I2S/HiFi.conf137
-rw-r--r--ucm-config/veyron_minnie/ROCKCHIP-I2S/ROCKCHIP-I2S.conf6
-rw-r--r--ucm-config/veyron_minnie/RockchipHDMI/HiFi.conf12
-rw-r--r--ucm-config/veyron_minnie/RockchipHDMI/RockchipHDMI.conf6
-rw-r--r--ucm-config/veyron_minnie/VEYRON-I2S/HiFi.conf158
-rw-r--r--ucm-config/veyron_minnie/VEYRON-I2S/VEYRON-I2S.conf6
-rw-r--r--ucm-config/veyron_speedy/ROCKCHIP-I2S/HiFi.conf137
-rw-r--r--ucm-config/veyron_speedy/ROCKCHIP-I2S/ROCKCHIP-I2S.conf6
-rw-r--r--ucm-config/veyron_speedy/RockchipHDMI/HiFi.conf12
-rw-r--r--ucm-config/veyron_speedy/RockchipHDMI/RockchipHDMI.conf6
-rw-r--r--ucm-config/veyron_speedy/VEYRON-I2S/HiFi.conf158
-rw-r--r--ucm-config/veyron_speedy/VEYRON-I2S/VEYRON-I2S.conf6
-rw-r--r--ucm-config/wolf/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/wolf/HDA Intel PCH/HiFi.conf55
-rw-r--r--ucm-config/zako/HDA Intel PCH/HDA Intel PCH.conf6
-rw-r--r--ucm-config/zako/HDA Intel PCH/HiFi.conf32
-rw-r--r--unblocked_terms.txt10
475 files changed, 13587 insertions, 25455 deletions
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index e8af785b..00000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,65 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-name: "CodeQL"
-
-on:
- push:
- branches: [main]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [main]
- schedule:
- - cron: '0 11 * * 1'
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
-
- strategy:
- fail-fast: false
- matrix:
- # Override automatic language detection by changing the below list
- # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
- language: ['cpp']
- # Learn more...
- # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v2
- with:
- # We must fetch at least the immediate parents so that if this is
- # a pull request then we can checkout the head.
- fetch-depth: 2
-
- # If this run was triggered by a pull request event, then checkout
- # the head of the pull request instead of the merge commit.
- - run: git checkout HEAD^2
- if: ${{ github.event_name == 'pull_request' }}
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v1
- with:
- languages: ${{ matrix.language }}
-
- # Command-line programs to run using the OS shell.
- # https://git.io/JvXDl
-
- - name: Install cras deps
- working-directory: ./cras
- run: sudo ./install_deps.sh
-
- - name: Build
- working-directory: ./cras
- run: |
- ./git_prepare.sh
- ./configure
- make
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 4cb9810f..00000000
--- a/Android.bp
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package {
- default_applicable_licenses: ["external_adhd_license"],
-}
-
-// Added automatically by a large-scale-change that took the approach of
-// 'apply every license found to every target'. While this makes sure we respect
-// every license restriction, it may not be entirely correct.
-//
-// e.g. GPL in an MIT project might only apply to the contrib/ directory.
-//
-// Please consider splitting the single license below into multiple licenses,
-// taking care not to lose any license_kind information, and overriding the
-// default license using the 'licenses: [...]' property on targets as needed.
-//
-// For unused files, consider creating a 'fileGroup' with "//visibility:private"
-// to attach the license to, and including a comment whether the files may be
-// used in the current project.
-//
-// large-scale-change included anything that looked like it might be a license
-// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
-//
-// Please consider removing redundant or irrelevant files from 'license_text:'.
-// See: http://go/android-license-faq
-license {
- name: "external_adhd_license",
- visibility: [":__subpackages__"],
- license_kinds: [
- "SPDX-license-identifier-BSD",
- "SPDX-license-identifier-LGPL",
- ],
- license_text: [
- "LICENSE.SUPERFASTHASH",
- "LICENSE.UTLIST",
- "LICENSE.WEBKIT",
- "NOTICE",
- ],
-}
diff --git a/METADATA b/METADATA
deleted file mode 100644
index 6d8601bb..00000000
--- a/METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-third_party {
- license_type: RESTRICTED
-}
diff --git a/Makefile b/Makefile
index 9693cabb..798f576a 100644
--- a/Makefile
+++ b/Makefile
@@ -15,11 +15,11 @@ cras_install:
cras-scripts:
$(ECHO) "Installing cras scripts"
- $(INSTALL) --mode 755 -d $(DESTDIR)/usr/bin/
+ $(INSTALL) --mode 755 -d $(DESTDIR)usr/bin/
$(INSTALL) --mode 755 -D $(ADHD_DIR)/scripts/audio_diagnostics \
- $(DESTDIR)/usr/bin/
+ $(DESTDIR)usr/bin/
$(INSTALL) --mode 755 -D $(ADHD_DIR)/scripts/asoc_dapm_graph \
- $(DESTDIR)/usr/bin/
+ $(DESTDIR)usr/bin/
cras_init_upstart: $(ADHD_DIR)/init/cras.conf
$(ECHO) "Installing upstart file"
@@ -52,7 +52,7 @@ cras_init: cras_init_upstart cras_init_scripts
endif
-$(DESTDIR)/etc/cras/device_blocklist: $(ADHD_DIR)/cras-config/device_blocklist
+$(DESTDIR)/etc/cras/device_blacklist: $(ADHD_DIR)/cras-config/device_blacklist
$(ECHO) "Installing '$<' to '$@'"
$(INSTALL) --mode 644 -D $< $@
@@ -83,7 +83,7 @@ install: $(DESTDIR)/lib/firmware/$(BOARD)_alsa.fw
endif
-install: $(DESTDIR)/etc/cras/device_blocklist \
+install: $(DESTDIR)/etc/cras/device_blacklist \
cras-scripts \
cras_install \
cras_init
diff --git a/OWNERS.fuzz b/OWNERS.fuzz
deleted file mode 100644
index 8c7567ff..00000000
--- a/OWNERS.fuzz
+++ /dev/null
@@ -1,5 +0,0 @@
-cychiang@chromium.org
-dgreid@chromium.org
-enshuo@chromium.org
-paulhsia@chromium.org
-chromeos-audio-bugs@google.com
diff --git a/PRESUBMIT.cfg b/PRESUBMIT.cfg
index e85e5dc2..c0e6ae9e 100644
--- a/PRESUBMIT.cfg
+++ b/PRESUBMIT.cfg
@@ -1,7 +1,6 @@
[Hook Overrides]
tab_check: false
clang_format_check: true
-cargo_clippy_check: true
# On by default, but required for options below.
cros_license_check: true
@@ -11,9 +10,3 @@ cros_license_check: true
cros_license_check: --exclude_regex=HiFi\.conf$
clang_format_check:
cras/
-cargo_clippy_check:
- --project=audio_streams
- --project=cras/client/cras-sys
- --project=cras/client/cras_tests
- --project=cras/client/libcras
- --project=cras/src/server/rust
diff --git a/alsa-module-config/alsa-cid.conf b/alsa-module-config/alsa-cid.conf
new file mode 100644
index 00000000..92544684
--- /dev/null
+++ b/alsa-module-config/alsa-cid.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=cid patch=,cid_alsa.fw
diff --git a/alsa-module-config/alsa-falco.conf b/alsa-module-config/alsa-falco.conf
new file mode 100644
index 00000000..2a5fcda3
--- /dev/null
+++ b/alsa-module-config/alsa-falco.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=falco patch=,falco_alsa.fw
diff --git a/alsa-module-config/alsa-jecht.conf b/alsa-module-config/alsa-jecht.conf
new file mode 100644
index 00000000..550a387f
--- /dev/null
+++ b/alsa-module-config/alsa-jecht.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=jecht patch=,jecht_alsa.fw
diff --git a/alsa-module-config/alsa-leon.conf b/alsa-module-config/alsa-leon.conf
new file mode 100644
index 00000000..d3a6af37
--- /dev/null
+++ b/alsa-module-config/alsa-leon.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=leon patch=,leon_alsa.fw
diff --git a/alsa-module-config/alsa-mccloud.conf b/alsa-module-config/alsa-mccloud.conf
new file mode 100644
index 00000000..f06a52ad
--- /dev/null
+++ b/alsa-module-config/alsa-mccloud.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=mccloud patch=,mccloud_alsa.fw
diff --git a/alsa-module-config/alsa-monroe.conf b/alsa-module-config/alsa-monroe.conf
new file mode 100644
index 00000000..620f8db3
--- /dev/null
+++ b/alsa-module-config/alsa-monroe.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=monroe patch=,monroe_alsa.fw
diff --git a/alsa-module-config/alsa-peppy.conf b/alsa-module-config/alsa-peppy.conf
new file mode 100644
index 00000000..482df733
--- /dev/null
+++ b/alsa-module-config/alsa-peppy.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=peppy patch=,peppy_alsa.fw
diff --git a/alsa-module-config/alsa-rikku.conf b/alsa-module-config/alsa-rikku.conf
new file mode 100644
index 00000000..36dec7f2
--- /dev/null
+++ b/alsa-module-config/alsa-rikku.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=rikku patch=,rikku_alsa.fw
diff --git a/alsa-module-config/alsa-stout.conf b/alsa-module-config/alsa-stout.conf
new file mode 100644
index 00000000..b1170341
--- /dev/null
+++ b/alsa-module-config/alsa-stout.conf
@@ -0,0 +1,2 @@
+# Tell patch_realtek that it is running on a stout.
+options snd_hda_intel model=stout patch=stout_alsa.fw
diff --git a/alsa-module-config/alsa-stout32.conf b/alsa-module-config/alsa-stout32.conf
new file mode 100644
index 00000000..847501d1
--- /dev/null
+++ b/alsa-module-config/alsa-stout32.conf
@@ -0,0 +1,2 @@
+# Tell patch_realtek that it is running on a stout.
+options snd_hda_intel model=stout patch=stout32_alsa.fw
diff --git a/alsa-module-config/alsa-tidus.conf b/alsa-module-config/alsa-tidus.conf
new file mode 100644
index 00000000..868d61e2
--- /dev/null
+++ b/alsa-module-config/alsa-tidus.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=tidus patch=,tidus_alsa.fw
diff --git a/alsa-module-config/alsa-tricky.conf b/alsa-module-config/alsa-tricky.conf
new file mode 100644
index 00000000..ba28ce58
--- /dev/null
+++ b/alsa-module-config/alsa-tricky.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=tricky patch=,tricky_alsa.fw
diff --git a/alsa-module-config/alsa-wolf.conf b/alsa-module-config/alsa-wolf.conf
new file mode 100644
index 00000000..c7f4f0fc
--- /dev/null
+++ b/alsa-module-config/alsa-wolf.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=wolf patch=,wolf_alsa.fw
diff --git a/alsa-module-config/alsa-zako.conf b/alsa-module-config/alsa-zako.conf
new file mode 100644
index 00000000..fcd6372a
--- /dev/null
+++ b/alsa-module-config/alsa-zako.conf
@@ -0,0 +1 @@
+options snd_hda_intel model=zako patch=,zako_alsa.fw
diff --git a/alsa-module-config/cid_alsa.fw b/alsa-module-config/cid_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/cid_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/falco_alsa.fw b/alsa-module-config/falco_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/falco_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/jecht_alsa.fw b/alsa-module-config/jecht_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/jecht_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/leon_alsa.fw b/alsa-module-config/leon_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/leon_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/mccloud_alsa.fw b/alsa-module-config/mccloud_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/mccloud_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/monroe_alsa.fw b/alsa-module-config/monroe_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/monroe_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/peppy_alsa.fw b/alsa-module-config/peppy_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/peppy_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/rikku_alsa.fw b/alsa-module-config/rikku_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/rikku_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/stout32_alsa.fw b/alsa-module-config/stout32_alsa.fw
new file mode 100644
index 00000000..2ba7aa2a
--- /dev/null
+++ b/alsa-module-config/stout32_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0269 0x17aa21fe 0
+
+[model]
+stout
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/stout_alsa.fw b/alsa-module-config/stout_alsa.fw
new file mode 100644
index 00000000..2ba7aa2a
--- /dev/null
+++ b/alsa-module-config/stout_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0269 0x17aa21fe 0
+
+[model]
+stout
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/tidus_alsa.fw b/alsa-module-config/tidus_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/tidus_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/tricky_alsa.fw b/alsa-module-config/tricky_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/tricky_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/wolf_alsa.fw b/alsa-module-config/wolf_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/wolf_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/alsa-module-config/zako_alsa.fw b/alsa-module-config/zako_alsa.fw
new file mode 100644
index 00000000..40ac817e
--- /dev/null
+++ b/alsa-module-config/zako_alsa.fw
@@ -0,0 +1,9 @@
+[codec]
+0x10ec0283 0x10ec0283 0
+
+[model]
+alc283-dac-wcaps
+
+[hint]
+auto_mute = no
+auto_mic = no
diff --git a/audio_streams/.gitignore b/audio_streams/.gitignore
deleted file mode 100644
index fa8d85ac..00000000
--- a/audio_streams/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Cargo.lock
-target
diff --git a/audio_streams/Android.bp b/audio_streams/Android.bp
index 2909b544..cbb67437 100644
--- a/audio_streams/Android.bp
+++ b/audio_streams/Android.bp
@@ -1,61 +1,18 @@
-// This file is generated by cargo2android.py --run --device --test --global_defaults=crosvm_defaults --dependencies.
+// This file is generated by cargo2android.py, added defaults.
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_adhd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-BSD
- default_applicable_licenses: ["external_adhd_license"],
-}
-
-rust_defaults {
- name: "audio_streams_defaults",
+rust_test_host {
+ name: "audio_streams_tests_audio_streams",
defaults: ["crosvm_defaults"],
crate_name: "audio_streams",
srcs: ["src/audio_streams.rs"],
+ relative_install_path: "audio_streams_tests",
test_suites: ["general-tests"],
auto_gen_config: true,
- edition: "2018",
- rustlibs: [
- "libsync_rust",
- "libsys_util",
- ],
}
-rust_test_host {
- name: "audio_streams_host_test_src_audio_streams",
- defaults: ["audio_streams_defaults"],
-}
-
-rust_test {
- name: "audio_streams_device_test_src_audio_streams",
- defaults: ["audio_streams_defaults"],
-}
-
-rust_library {
+rust_library_host_rlib {
name: "libaudio_streams",
defaults: ["crosvm_defaults"],
- host_supported: true,
crate_name: "audio_streams",
srcs: ["src/audio_streams.rs"],
- edition: "2018",
- rustlibs: [
- "libsync_rust",
- "libsys_util",
- ],
}
-
-// dependent_library ["feature_list"]
-// ../../crosvm/assertions/src/lib.rs
-// ../../crosvm/data_model/src/lib.rs
-// ../../crosvm/sync/src/lib.rs
-// ../../crosvm/sys_util/poll_token_derive/poll_token_derive.rs
-// ../../crosvm/sys_util/src/lib.rs
-// ../../crosvm/syscall_defines/src/lib.rs
-// ../../crosvm/tempfile/src/lib.rs
-// libc-0.2.76 "default,std"
-// proc-macro2-1.0.19 "default,proc-macro"
-// quote-1.0.7 "default,proc-macro"
-// syn-1.0.39 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
-// unicode-xid-0.2.1 "default"
diff --git a/audio_streams/Cargo.toml b/audio_streams/Cargo.toml
index dd169c7f..54e6af63 100644
--- a/audio_streams/Cargo.toml
+++ b/audio_streams/Cargo.toml
@@ -8,5 +8,3 @@ edition = "2018"
path = "src/audio_streams.rs"
[dependencies]
-sync = { path = "../../crosvm/sync" } # provided by ebuild
-sys_util = { path = "../../crosvm/sys_util" } # provided by ebuild
diff --git a/audio_streams/README.md b/audio_streams/README.md
index d3a02e8f..b62c2946 100644
--- a/audio_streams/README.md
+++ b/audio_streams/README.md
@@ -2,5 +2,5 @@
The `audio_streams` crate provides a basic interface for playing audio.
This will be used to enable playback to various audio subsystems such as
-Alsa and cras. To start, an empty playback example `NoopStreamSource`
+Alsa and cras. To start, an empty playback example `DummyStreamSource`
is provided.
diff --git a/audio_streams/src/audio_streams.rs b/audio_streams/src/audio_streams.rs
index e5fc83cb..672034b7 100644
--- a/audio_streams/src/audio_streams.rs
+++ b/audio_streams/src/audio_streams.rs
@@ -13,158 +13,67 @@
//! the samples written to it are committed to the `PlaybackBufferStream` it came from.
//!
//! ```
-//! use audio_streams::{BoxError, SampleFormat, StreamSource, NoopStreamSource};
+//! use audio_streams::{StreamSource, DummyStreamSource};
//! use std::io::Write;
//!
//! const buffer_size: usize = 120;
//! const num_channels: usize = 2;
+//! const frame_size: usize = num_channels * 2; // 16-bit samples are two bytes.
//!
-//! # fn main() -> std::result::Result<(), BoxError> {
-//! let mut stream_source = NoopStreamSource::new();
-//! let sample_format = SampleFormat::S16LE;
-//! let frame_size = num_channels * sample_format.sample_bytes();
+//! # fn main() -> std::result::Result<(), Box<std::error::Error>> {
+//! let mut stream_source = DummyStreamSource::new();
//!
//! let (_, mut stream) = stream_source
-//! .new_playback_stream(num_channels, sample_format, 48000, buffer_size)?;
+//! .new_playback_stream(num_channels, 48000, buffer_size)?;
//! // Play 10 buffers of DC.
-//! let mut buf = Vec::new();
-//! buf.resize(buffer_size * frame_size, 0xa5u8);
-//! for _ in 0..10 {
+//! let pb_bufs = [[0xa5u8; buffer_size * frame_size]; 10];
+//! for pb_buf in &pb_bufs {
//! let mut stream_buffer = stream.next_playback_buffer()?;
-//! assert_eq!(stream_buffer.write(&buf)?, buffer_size * frame_size);
+//! assert_eq!(stream_buffer.write(pb_buf)?, buffer_size * frame_size);
//! }
//! # Ok (())
//! # }
//! ```
-use std::cmp::min;
use std::error;
use std::fmt::{self, Display};
use std::io::{self, Write};
use std::os::unix::io::RawFd;
use std::result::Result;
-use std::str::FromStr;
use std::time::{Duration, Instant};
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum SampleFormat {
- U8,
- S16LE,
- S24LE,
- S32LE,
-}
-
-impl SampleFormat {
- pub fn sample_bytes(self) -> usize {
- use SampleFormat::*;
- match self {
- U8 => 1,
- S16LE => 2,
- S24LE => 4, // Not a typo, S24_LE samples are stored in 4 byte chunks.
- S32LE => 4,
- }
- }
-}
-
-impl Display for SampleFormat {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use SampleFormat::*;
- match self {
- U8 => write!(f, "Unsigned 8 bit"),
- S16LE => write!(f, "Signed 16 bit Little Endian"),
- S24LE => write!(f, "Signed 24 bit Little Endian"),
- S32LE => write!(f, "Signed 32 bit Little Endian"),
- }
- }
-}
-
-/// Valid directions of an audio stream.
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum StreamDirection {
- Playback,
- Capture,
-}
-
-/// Valid effects for an audio stream.
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum StreamEffect {
- NoEffect,
- EchoCancellation,
-}
-
pub mod capture;
-pub mod shm_streams;
-
-impl Default for StreamEffect {
- fn default() -> Self {
- StreamEffect::NoEffect
- }
-}
-
-/// Errors that can pass across threads.
-pub type BoxError = Box<dyn error::Error + Send + Sync>;
-
-/// Errors that are possible from a `StreamEffect`.
-#[derive(Debug)]
-pub enum StreamEffectError {
- InvalidEffect,
-}
-
-impl error::Error for StreamEffectError {}
-
-impl Display for StreamEffectError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- StreamEffectError::InvalidEffect => write!(f, "Must be in [EchoCancellation, aec]"),
- }
- }
-}
-
-impl FromStr for StreamEffect {
- type Err = StreamEffectError;
- fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- match s {
- "EchoCancellation" | "aec" => Ok(StreamEffect::EchoCancellation),
- _ => Err(StreamEffectError::InvalidEffect),
- }
- }
-}
/// `StreamSource` creates streams for playback or capture of audio.
pub trait StreamSource: Send {
/// Returns a stream control and buffer generator object. These are separate as the buffer
/// generator might want to be passed to the audio stream.
- #[allow(clippy::type_complexity)]
fn new_playback_stream(
&mut self,
num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
+ frame_rate: usize,
buffer_size: usize,
- ) -> Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>;
+ ) -> Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), Box<dyn error::Error>>;
/// Returns a stream control and buffer generator object. These are separate as the buffer
/// generator might want to be passed to the audio stream.
- /// Default implementation returns `NoopStreamControl` and `NoopCaptureStream`.
- #[allow(clippy::type_complexity)]
+ /// Default implementation returns `DummyStreamControl` and `DummyCaptureStream`.
fn new_capture_stream(
&mut self,
num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
+ frame_rate: usize,
buffer_size: usize,
) -> Result<
(
Box<dyn StreamControl>,
Box<dyn capture::CaptureBufferStream>,
),
- BoxError,
+ Box<dyn error::Error>,
> {
Ok((
- Box::new(NoopStreamControl::new()),
- Box::new(capture::NoopCaptureStream::new(
+ Box::new(DummyStreamControl::new()),
+ Box::new(capture::DummyCaptureStream::new(
num_channels,
- format,
frame_rate,
buffer_size,
)),
@@ -180,7 +89,7 @@ pub trait StreamSource: Send {
/// `PlaybackBufferStream` provides `PlaybackBuffer`s to fill with audio samples for playback.
pub trait PlaybackBufferStream: Send {
- fn next_playback_buffer(&mut self) -> Result<PlaybackBuffer, BoxError>;
+ fn next_playback_buffer<'a>(&'a mut self) -> Result<PlaybackBuffer<'a>, Box<dyn error::Error>>;
}
/// `StreamControl` provides a way to set the volume and mute states of a stream. `StreamControl`
@@ -263,10 +172,7 @@ impl<'a> PlaybackBuffer<'a> {
/// Writes up to `size` bytes directly to this buffer inside of the given callback function.
pub fn copy_cb<F: FnOnce(&mut [u8])>(&mut self, size: usize, cb: F) {
// only write complete frames.
- let len = min(
- size / self.buffer.frame_size * self.buffer.frame_size,
- self.buffer.buffer.len() - self.buffer.offset,
- );
+ let len = size / self.buffer.frame_size * self.buffer.frame_size;
cb(&mut self.buffer.buffer[self.buffer.offset..(self.buffer.offset + len)]);
self.buffer.offset += len;
}
@@ -295,55 +201,51 @@ impl<'a> Drop for PlaybackBuffer<'a> {
}
/// Stream that accepts playback samples but drops them.
-pub struct NoopStream {
+pub struct DummyStream {
buffer: Vec<u8>,
frame_size: usize,
interval: Duration,
next_frame: Duration,
start_time: Option<Instant>,
- buffer_drop: NoopBufferDrop,
+ buffer_drop: DummyBufferDrop,
}
-/// NoopStream data that is needed from the buffer complete callback.
-struct NoopBufferDrop {
+/// DummyStream data that is needed from the buffer complete callback.
+struct DummyBufferDrop {
which_buffer: bool,
}
-impl BufferDrop for NoopBufferDrop {
+impl BufferDrop for DummyBufferDrop {
fn trigger(&mut self, _nwritten: usize) {
// When a buffer completes, switch to the other one.
self.which_buffer ^= true;
}
}
-impl NoopStream {
- pub fn new(
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- ) -> Self {
- let frame_size = format.sample_bytes() * num_channels;
+impl DummyStream {
+ // TODO(allow other formats)
+ pub fn new(num_channels: usize, frame_rate: usize, buffer_size: usize) -> Self {
+ const S16LE_SIZE: usize = 2;
+ let frame_size = S16LE_SIZE * num_channels;
let interval = Duration::from_millis(buffer_size as u64 * 1000 / frame_rate as u64);
- NoopStream {
+ DummyStream {
buffer: vec![0; buffer_size * frame_size],
frame_size,
interval,
next_frame: interval,
start_time: None,
- buffer_drop: NoopBufferDrop {
+ buffer_drop: DummyBufferDrop {
which_buffer: false,
},
}
}
}
-impl PlaybackBufferStream for NoopStream {
- fn next_playback_buffer(&mut self) -> Result<PlaybackBuffer, BoxError> {
+impl PlaybackBufferStream for DummyStream {
+ fn next_playback_buffer<'a>(&'a mut self) -> Result<PlaybackBuffer<'a>, Box<dyn error::Error>> {
if let Some(start_time) = self.start_time {
- let elapsed = start_time.elapsed();
- if elapsed < self.next_frame {
- std::thread::sleep(self.next_frame - elapsed);
+ if start_time.elapsed() < self.next_frame {
+ std::thread::sleep(self.next_frame - start_time.elapsed());
}
self.next_frame += self.interval;
} else {
@@ -358,45 +260,39 @@ impl PlaybackBufferStream for NoopStream {
}
}
-/// No-op control for `NoopStream`s.
+/// No-op control for `DummyStream`s.
#[derive(Default)]
-pub struct NoopStreamControl;
+pub struct DummyStreamControl;
-impl NoopStreamControl {
+impl DummyStreamControl {
pub fn new() -> Self {
- NoopStreamControl {}
+ DummyStreamControl {}
}
}
-impl StreamControl for NoopStreamControl {}
+impl StreamControl for DummyStreamControl {}
-/// Source of `NoopStream` and `NoopStreamControl` objects.
+/// Source of `DummyStream` and `DummyStreamControl` objects.
#[derive(Default)]
-pub struct NoopStreamSource;
+pub struct DummyStreamSource;
-impl NoopStreamSource {
+impl DummyStreamSource {
pub fn new() -> Self {
- NoopStreamSource {}
+ DummyStreamSource {}
}
}
-impl StreamSource for NoopStreamSource {
- #[allow(clippy::type_complexity)]
+impl StreamSource for DummyStreamSource {
fn new_playback_stream(
&mut self,
num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
+ frame_rate: usize,
buffer_size: usize,
- ) -> Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError> {
+ ) -> Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), Box<dyn error::Error>>
+ {
Ok((
- Box::new(NoopStreamControl::new()),
- Box::new(NoopStream::new(
- num_channels,
- format,
- frame_rate,
- buffer_size,
- )),
+ Box::new(DummyStreamControl::new()),
+ Box::new(DummyStream::new(num_channels, frame_rate, buffer_size)),
))
}
}
@@ -409,7 +305,7 @@ mod tests {
fn invalid_buffer_length() {
// Playback buffers can't be created with a size that isn't divisible by the frame size.
let mut pb_buf = [0xa5u8; 480 * 2 * 2 + 1];
- let mut buffer_drop = NoopBufferDrop {
+ let mut buffer_drop = DummyBufferDrop {
which_buffer: false,
};
assert!(PlaybackBuffer::new(2, &mut pb_buf, &mut buffer_drop).is_err());
@@ -430,17 +326,15 @@ mod tests {
const FRAME_SIZE: usize = 4;
let mut buf = [0u8; 480 * FRAME_SIZE];
let mut pb_buf = PlaybackBuffer::new(FRAME_SIZE, &mut buf, &mut test_drop).unwrap();
- pb_buf.write_all(&[0xa5u8; 480 * FRAME_SIZE]).unwrap();
+ pb_buf.write(&[0xa5u8; 480 * FRAME_SIZE]).unwrap();
}
assert_eq!(test_drop.frame_count, 480);
}
#[test]
fn sixteen_bit_stereo() {
- let mut server = NoopStreamSource::new();
- let (_, mut stream) = server
- .new_playback_stream(2, SampleFormat::S16LE, 48000, 480)
- .unwrap();
+ let mut server = DummyStreamSource::new();
+ let (_, mut stream) = server.new_playback_stream(2, 48000, 480).unwrap();
let mut stream_buffer = stream.next_playback_buffer().unwrap();
assert_eq!(stream_buffer.frame_capacity(), 480);
let pb_buf = [0xa5u8; 480 * 2 * 2];
@@ -449,10 +343,8 @@ mod tests {
#[test]
fn consumption_rate() {
- let mut server = NoopStreamSource::new();
- let (_, mut stream) = server
- .new_playback_stream(2, SampleFormat::S16LE, 48000, 480)
- .unwrap();
+ let mut server = DummyStreamSource::new();
+ let (_, mut stream) = server.new_playback_stream(2, 48000, 480).unwrap();
let start = Instant::now();
{
let mut stream_buffer = stream.next_playback_buffer().unwrap();
diff --git a/audio_streams/src/capture.rs b/audio_streams/src/capture.rs
index 6a32cf1a..0e58dc8a 100644
--- a/audio_streams/src/capture.rs
+++ b/audio_streams/src/capture.rs
@@ -2,43 +2,40 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//! ```
-//! use audio_streams::{BoxError, SampleFormat, StreamSource, NoopStreamSource};
+//! use audio_streams::{StreamSource, DummyStreamSource};
//! use std::io::Read;
//!
//! const buffer_size: usize = 120;
//! const num_channels: usize = 2;
+//! const frame_size: usize = num_channels * 2; // 16-bit samples are two bytes.
//!
-//! # fn main() -> std::result::Result<(),BoxError> {
-//! let mut stream_source = NoopStreamSource::new();
-//! let sample_format = SampleFormat::S16LE;
-//! let frame_size = num_channels * sample_format.sample_bytes();
+//! # fn main() -> std::result::Result<(), Box<std::error::Error>> {
+//! let mut stream_source = DummyStreamSource::new();
//!
//! let (_, mut stream) = stream_source
-//! .new_capture_stream(num_channels, sample_format, 48000, buffer_size)?;
+//! .new_capture_stream(num_channels, 48000, buffer_size)?;
//! // Capture 10 buffers of zeros.
-//! let mut buf = Vec::new();
-//! buf.resize(buffer_size * frame_size, 0xa5u8);
-//! for _ in 0..10 {
+//! let mut cp_bufs = [[0xa5u8; buffer_size * frame_size]; 10];
+//! for cp_buf in &mut cp_bufs {
//! let mut stream_buffer = stream.next_capture_buffer()?;
-//! assert_eq!(stream_buffer.read(&mut buf)?, buffer_size * frame_size);
+//! assert_eq!(stream_buffer.read(cp_buf)?, buffer_size * frame_size);
//! }
//! # Ok (())
//! # }
//! ```
use std::{
- cmp::min,
error,
fmt::{self, Display},
io::{self, Read, Write},
time::{Duration, Instant},
};
-use super::{AudioBuffer, BoxError, BufferDrop, NoopBufferDrop, SampleFormat};
+use super::{AudioBuffer, BufferDrop, DummyBufferDrop};
/// `CaptureBufferStream` provides `CaptureBuffer`s to read with audio samples from capture.
pub trait CaptureBufferStream: Send {
- fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, BoxError>;
+ fn next_capture_buffer<'a>(&'a mut self) -> Result<CaptureBuffer<'a>, Box<dyn error::Error>>;
}
/// `CaptureBuffer` contains a block of audio samples got from capture stream. It provides
@@ -97,10 +94,7 @@ impl<'a> CaptureBuffer<'a> {
/// Reads up to `size` bytes directly from this buffer inside of the given callback function.
pub fn copy_cb<F: FnOnce(&[u8])>(&mut self, size: usize, cb: F) {
- let len = min(
- size / self.buffer.frame_size * self.buffer.frame_size,
- self.buffer.buffer.len() - self.buffer.offset,
- );
+ let len = size / self.buffer.frame_size * self.buffer.frame_size;
cb(&self.buffer.buffer[self.buffer.offset..(self.buffer.offset + len)]);
self.buffer.offset += len;
}
@@ -123,43 +117,39 @@ impl<'a> Drop for CaptureBuffer<'a> {
}
/// Stream that provides null capture samples.
-pub struct NoopCaptureStream {
+pub struct DummyCaptureStream {
buffer: Vec<u8>,
frame_size: usize,
interval: Duration,
next_frame: Duration,
start_time: Option<Instant>,
- buffer_drop: NoopBufferDrop,
+ buffer_drop: DummyBufferDrop,
}
-impl NoopCaptureStream {
- pub fn new(
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- ) -> Self {
- let frame_size = format.sample_bytes() * num_channels;
+impl DummyCaptureStream {
+ // TODO(allow other formats)
+ pub fn new(num_channels: usize, frame_rate: usize, buffer_size: usize) -> Self {
+ const S16LE_SIZE: usize = 2;
+ let frame_size = S16LE_SIZE * num_channels;
let interval = Duration::from_millis(buffer_size as u64 * 1000 / frame_rate as u64);
- NoopCaptureStream {
+ DummyCaptureStream {
buffer: vec![0; buffer_size * frame_size],
frame_size,
interval,
next_frame: interval,
start_time: None,
- buffer_drop: NoopBufferDrop {
+ buffer_drop: DummyBufferDrop {
which_buffer: false,
},
}
}
}
-impl CaptureBufferStream for NoopCaptureStream {
- fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, BoxError> {
+impl CaptureBufferStream for DummyCaptureStream {
+ fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, Box<dyn error::Error>> {
if let Some(start_time) = self.start_time {
- let elapsed = start_time.elapsed();
- if elapsed < self.next_frame {
- std::thread::sleep(self.next_frame - elapsed);
+ if start_time.elapsed() < self.next_frame {
+ std::thread::sleep(self.next_frame - start_time.elapsed());
}
self.next_frame += self.interval;
} else {
@@ -183,7 +173,7 @@ mod tests {
fn invalid_buffer_length() {
// Capture buffers can't be created with a size that isn't divisible by the frame size.
let mut cp_buf = [0xa5u8; 480 * 2 * 2 + 1];
- let mut buffer_drop = NoopBufferDrop {
+ let mut buffer_drop = DummyBufferDrop {
which_buffer: false,
};
assert!(CaptureBuffer::new(2, &mut cp_buf, &mut buffer_drop).is_err());
@@ -213,10 +203,8 @@ mod tests {
#[test]
fn sixteen_bit_stereo() {
- let mut server = NoopStreamSource::new();
- let (_, mut stream) = server
- .new_capture_stream(2, SampleFormat::S16LE, 48000, 480)
- .unwrap();
+ let mut server = DummyStreamSource::new();
+ let (_, mut stream) = server.new_capture_stream(2, 48000, 480).unwrap();
let mut stream_buffer = stream.next_capture_buffer().unwrap();
assert_eq!(stream_buffer.frame_capacity(), 480);
let mut pb_buf = [0xa5u8; 480 * 2 * 2];
@@ -225,17 +213,15 @@ mod tests {
#[test]
fn consumption_rate() {
- let mut server = NoopStreamSource::new();
- let (_, mut stream) = server
- .new_capture_stream(2, SampleFormat::S16LE, 48000, 480)
- .unwrap();
+ let mut server = DummyStreamSource::new();
+ let (_, mut stream) = server.new_capture_stream(2, 48000, 480).unwrap();
let start = Instant::now();
{
let mut stream_buffer = stream.next_capture_buffer().unwrap();
let mut cp_buf = [0xa5u8; 480 * 2 * 2];
assert_eq!(stream_buffer.read(&mut cp_buf).unwrap(), 480 * 2 * 2);
- for buf in cp_buf.iter() {
- assert_eq!(*buf, 0, "Read samples should all be zeros.");
+ for i in 0..cp_buf.len() {
+ assert_eq!(cp_buf[i], 0, "Read samples should all be zeros.");
}
}
// The second call should block until the first buffer is consumed.
@@ -247,4 +233,5 @@ mod tests {
elapsed.subsec_millis()
);
}
+
}
diff --git a/audio_streams/src/shm_streams.rs b/audio_streams/src/shm_streams.rs
deleted file mode 100644
index b11626fd..00000000
--- a/audio_streams/src/shm_streams.rs
+++ /dev/null
@@ -1,568 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::error;
-use std::fmt;
-use std::os::unix::io::RawFd;
-use std::sync::Arc;
-use std::time::{Duration, Instant};
-
-use sync::{Condvar, Mutex};
-use sys_util::SharedMemory;
-
-use crate::{BoxError, SampleFormat, StreamDirection, StreamEffect};
-
-type GenericResult<T> = std::result::Result<T, BoxError>;
-
-/// `BufferSet` is used as a callback mechanism for `ServerRequest` objects.
-/// It is meant to be implemented by the audio stream, allowing arbitrary code
-/// to be run after a buffer offset and length is set.
-pub trait BufferSet {
- /// Called when the client sets a buffer offset and length.
- ///
- /// `offset` is the offset within shared memory of the buffer and `frames`
- /// indicates the number of audio frames that can be read from or written to
- /// the buffer.
- fn callback(&mut self, offset: usize, frames: usize) -> GenericResult<()>;
-
- /// Called when the client ignores a request from the server.
- fn ignore(&mut self) -> GenericResult<()>;
-}
-
-#[derive(Debug)]
-pub enum Error {
- TooManyFrames(usize, usize),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Error::TooManyFrames(provided, requested) => write!(
- f,
- "Provided number of frames {} exceeds requested number of frames {}",
- provided, requested
- ),
- }
- }
-}
-
-/// `ServerRequest` represents an active request from the server for the client
-/// to provide a buffer in shared memory to playback from or capture to.
-pub struct ServerRequest<'a> {
- requested_frames: usize,
- buffer_set: &'a mut dyn BufferSet,
-}
-
-impl<'a> ServerRequest<'a> {
- /// Create a new ServerRequest object
- ///
- /// Create a ServerRequest object representing a request from the server
- /// for a buffer `requested_frames` in size.
- ///
- /// When the client responds to this request by calling
- /// [`set_buffer_offset_and_frames`](ServerRequest::set_buffer_offset_and_frames),
- /// BufferSet::callback will be called on `buffer_set`.
- ///
- /// # Arguments
- /// * `requested_frames` - The requested buffer size in frames.
- /// * `buffer_set` - The object implementing the callback for when a buffer is provided.
- pub fn new<D: BufferSet>(requested_frames: usize, buffer_set: &'a mut D) -> Self {
- Self {
- requested_frames,
- buffer_set,
- }
- }
-
- /// Get the number of frames of audio data requested by the server.
- ///
- /// The returned value should never be greater than the `buffer_size`
- /// given in [`new_stream`](ShmStreamSource::new_stream).
- pub fn requested_frames(&self) -> usize {
- self.requested_frames
- }
-
- /// Sets the buffer offset and length for the requested buffer.
- ///
- /// Sets the buffer offset and length of the buffer that fulfills this
- /// server request to `offset` and `length`, respectively. This means that
- /// `length` bytes of audio samples may be read from/written to that
- /// location in `client_shm` for a playback/capture stream, respectively.
- /// This function may only be called once for a `ServerRequest`, at which
- /// point the ServerRequest is dropped and no further calls are possible.
- ///
- /// # Arguments
- ///
- /// * `offset` - The value to use as the new buffer offset for the next buffer.
- /// * `frames` - The length of the next buffer in frames.
- ///
- /// # Errors
- ///
- /// * If `frames` is greater than `requested_frames`.
- pub fn set_buffer_offset_and_frames(self, offset: usize, frames: usize) -> GenericResult<()> {
- if frames > self.requested_frames {
- return Err(Box::new(Error::TooManyFrames(
- frames,
- self.requested_frames,
- )));
- }
-
- self.buffer_set.callback(offset, frames)
- }
-
- /// Ignore this request
- ///
- /// If the client does not intend to respond to this ServerRequest with a
- /// buffer, they should call this function. The stream will be notified that
- /// the request has been ignored and will handle it properly.
- pub fn ignore_request(self) -> GenericResult<()> {
- self.buffer_set.ignore()
- }
-}
-
-/// `ShmStream` allows a client to interact with an active CRAS stream.
-pub trait ShmStream: Send {
- /// Get the size of a frame of audio data for this stream.
- fn frame_size(&self) -> usize;
-
- /// Get the number of channels of audio data for this stream.
- fn num_channels(&self) -> usize;
-
- /// Get the frame rate of audio data for this stream.
- fn frame_rate(&self) -> u32;
-
- /// Waits until the next server message indicating action is required.
- ///
- /// For playback streams, this will be `AUDIO_MESSAGE_REQUEST_DATA`, meaning
- /// that we must set the buffer offset to the next location where playback
- /// data can be found.
- /// For capture streams, this will be `AUDIO_MESSAGE_DATA_READY`, meaning
- /// that we must set the buffer offset to the next location where captured
- /// data can be written to.
- /// Will return early if `timeout` elapses before a message is received.
- ///
- /// # Arguments
- ///
- /// * `timeout` - The amount of time to wait until a message is received.
- ///
- /// # Return value
- ///
- /// Returns `Some(request)` where `request` is an object that implements the
- /// [`ServerRequest`](ServerRequest) trait and which can be used to get the
- /// number of bytes requested for playback streams or that have already been
- /// written to shm for capture streams.
- ///
- /// If the timeout occurs before a message is received, returns `None`.
- ///
- /// # Errors
- ///
- /// * If an invalid message type is received for the stream.
- fn wait_for_next_action_with_timeout(
- &mut self,
- timeout: Duration,
- ) -> GenericResult<Option<ServerRequest>>;
-}
-
-/// `ShmStreamSource` creates streams for playback or capture of audio.
-pub trait ShmStreamSource: Send {
- /// Creates a new [`ShmStream`](ShmStream)
- ///
- /// Creates a new `ShmStream` object, which allows:
- /// * Waiting until the server has communicated that data is ready or
- /// requested that we make more data available.
- /// * Setting the location and length of buffers for reading/writing audio data.
- ///
- /// # Arguments
- ///
- /// * `direction` - The direction of the stream, either `Playback` or `Capture`.
- /// * `num_channels` - The number of audio channels for the stream.
- /// * `format` - The audio format to use for audio samples.
- /// * `frame_rate` - The stream's frame rate in Hz.
- /// * `buffer_size` - The maximum size of an audio buffer. This will be the
- /// size used for transfers of audio data between client
- /// and server.
- /// * `effects` - Audio effects to use for the stream, such as echo-cancellation.
- /// * `client_shm` - The shared memory area that will contain samples.
- /// * `buffer_offsets` - The two initial values to use as buffer offsets
- /// for streams. This way, the server will not write
- /// audio data to an arbitrary offset in `client_shm`
- /// if the client fails to update offsets in time.
- ///
- /// # Errors
- ///
- /// * If sending the connect stream message to the server fails.
- #[allow(clippy::too_many_arguments)]
- fn new_stream(
- &mut self,
- direction: StreamDirection,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- effects: &[StreamEffect],
- client_shm: &SharedMemory,
- buffer_offsets: [u64; 2],
- ) -> GenericResult<Box<dyn ShmStream>>;
-
- /// Get a list of file descriptors used by the implementation.
- ///
- /// Returns any open file descriptors needed by the implementation.
- /// This list helps users of the ShmStreamSource enter Linux jails without
- /// closing needed file descriptors.
- fn keep_fds(&self) -> Vec<RawFd> {
- Vec::new()
- }
-}
-
-/// Class that implements ShmStream trait but does nothing with the samples
-pub struct NullShmStream {
- num_channels: usize,
- frame_rate: u32,
- buffer_size: usize,
- frame_size: usize,
- interval: Duration,
- next_frame: Duration,
- start_time: Instant,
-}
-
-impl NullShmStream {
- /// Attempt to create a new NullShmStream with the given number of channels,
- /// format, frame_rate, and buffer_size.
- pub fn new(
- buffer_size: usize,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- ) -> Self {
- let interval = Duration::from_millis(buffer_size as u64 * 1000 / frame_rate as u64);
- Self {
- num_channels,
- frame_rate,
- buffer_size,
- frame_size: format.sample_bytes() * num_channels,
- interval,
- next_frame: interval,
- start_time: Instant::now(),
- }
- }
-}
-
-impl BufferSet for NullShmStream {
- fn callback(&mut self, _offset: usize, _frames: usize) -> GenericResult<()> {
- Ok(())
- }
-
- fn ignore(&mut self) -> GenericResult<()> {
- Ok(())
- }
-}
-
-impl ShmStream for NullShmStream {
- fn frame_size(&self) -> usize {
- self.frame_size
- }
-
- fn num_channels(&self) -> usize {
- self.num_channels
- }
-
- fn frame_rate(&self) -> u32 {
- self.frame_rate
- }
-
- fn wait_for_next_action_with_timeout(
- &mut self,
- timeout: Duration,
- ) -> GenericResult<Option<ServerRequest>> {
- let elapsed = self.start_time.elapsed();
- if elapsed < self.next_frame {
- if timeout < self.next_frame - elapsed {
- std::thread::sleep(timeout);
- return Ok(None);
- } else {
- std::thread::sleep(self.next_frame - elapsed);
- }
- }
- self.next_frame += self.interval;
- Ok(Some(ServerRequest::new(self.buffer_size, self)))
- }
-}
-
-/// Source of `NullShmStream` objects.
-#[derive(Default)]
-pub struct NullShmStreamSource;
-
-impl NullShmStreamSource {
- pub fn new() -> Self {
- Self::default()
- }
-}
-
-impl ShmStreamSource for NullShmStreamSource {
- fn new_stream(
- &mut self,
- _direction: StreamDirection,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- _effects: &[StreamEffect],
- _client_shm: &SharedMemory,
- _buffer_offsets: [u64; 2],
- ) -> GenericResult<Box<dyn ShmStream>> {
- let new_stream = NullShmStream::new(buffer_size, num_channels, format, frame_rate);
- Ok(Box::new(new_stream))
- }
-}
-
-#[derive(Clone)]
-pub struct MockShmStream {
- num_channels: usize,
- frame_rate: u32,
- request_size: usize,
- frame_size: usize,
- request_notifier: Arc<(Mutex<bool>, Condvar)>,
-}
-
-impl MockShmStream {
- /// Attempt to create a new MockShmStream with the given number of
- /// channels, frame_rate, format, and buffer_size.
- pub fn new(
- num_channels: usize,
- frame_rate: u32,
- format: SampleFormat,
- buffer_size: usize,
- ) -> Self {
- Self {
- num_channels,
- frame_rate,
- request_size: buffer_size,
- frame_size: format.sample_bytes() * num_channels,
- request_notifier: Arc::new((Mutex::new(false), Condvar::new())),
- }
- }
-
- /// Call to request data from the stream, causing it to return from
- /// `wait_for_next_action_with_timeout`. Will block until
- /// `set_buffer_offset_and_frames` is called on the ServerRequest returned
- /// from `wait_for_next_action_with_timeout`, or until `timeout` elapses.
- /// Returns true if a response was successfully received.
- pub fn trigger_callback_with_timeout(&mut self, timeout: Duration) -> bool {
- let &(ref lock, ref cvar) = &*self.request_notifier;
- let mut requested = lock.lock();
- *requested = true;
- cvar.notify_one();
- let start_time = Instant::now();
- while *requested {
- requested = cvar.wait_timeout(requested, timeout).0;
- if start_time.elapsed() > timeout {
- // We failed to get a callback in time, mark this as false.
- *requested = false;
- return false;
- }
- }
-
- true
- }
-
- fn notify_request(&mut self) {
- let &(ref lock, ref cvar) = &*self.request_notifier;
- let mut requested = lock.lock();
- *requested = false;
- cvar.notify_one();
- }
-}
-
-impl BufferSet for MockShmStream {
- fn callback(&mut self, _offset: usize, _frames: usize) -> GenericResult<()> {
- self.notify_request();
- Ok(())
- }
-
- fn ignore(&mut self) -> GenericResult<()> {
- self.notify_request();
- Ok(())
- }
-}
-
-impl ShmStream for MockShmStream {
- fn frame_size(&self) -> usize {
- self.frame_size
- }
-
- fn num_channels(&self) -> usize {
- self.num_channels
- }
-
- fn frame_rate(&self) -> u32 {
- self.frame_rate
- }
-
- fn wait_for_next_action_with_timeout(
- &mut self,
- timeout: Duration,
- ) -> GenericResult<Option<ServerRequest>> {
- {
- let start_time = Instant::now();
- let &(ref lock, ref cvar) = &*self.request_notifier;
- let mut requested = lock.lock();
- while !*requested {
- requested = cvar.wait_timeout(requested, timeout).0;
- if start_time.elapsed() > timeout {
- return Ok(None);
- }
- }
- }
-
- Ok(Some(ServerRequest::new(self.request_size, self)))
- }
-}
-
-/// Source of `MockShmStream` objects.
-#[derive(Clone, Default)]
-pub struct MockShmStreamSource {
- last_stream: Arc<(Mutex<Option<MockShmStream>>, Condvar)>,
-}
-
-impl MockShmStreamSource {
- pub fn new() -> Self {
- Default::default()
- }
-
- /// Get the last stream that has been created from this source. If no stream
- /// has been created, block until one has.
- pub fn get_last_stream(&self) -> MockShmStream {
- let &(ref last_stream, ref cvar) = &*self.last_stream;
- let mut stream = last_stream.lock();
- loop {
- match &*stream {
- None => stream = cvar.wait(stream),
- Some(ref s) => return s.clone(),
- };
- }
- }
-}
-
-impl ShmStreamSource for MockShmStreamSource {
- fn new_stream(
- &mut self,
- _direction: StreamDirection,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- _effects: &[StreamEffect],
- _client_shm: &SharedMemory,
- _buffer_offsets: [u64; 2],
- ) -> GenericResult<Box<dyn ShmStream>> {
- let &(ref last_stream, ref cvar) = &*self.last_stream;
- let mut stream = last_stream.lock();
-
- let new_stream = MockShmStream::new(num_channels, frame_rate, format, buffer_size);
- *stream = Some(new_stream.clone());
- cvar.notify_one();
- Ok(Box::new(new_stream))
- }
-}
-
-#[cfg(test)]
-pub mod tests {
- use super::*;
-
- #[test]
- fn mock_trigger_callback() {
- let stream_source = MockShmStreamSource::new();
- let mut thread_stream_source = stream_source.clone();
-
- let buffer_size = 480;
- let num_channels = 2;
- let format = SampleFormat::S24LE;
- let shm = SharedMemory::anon().expect("Failed to create shm");
-
- let handle = std::thread::spawn(move || {
- let mut stream = thread_stream_source
- .new_stream(
- StreamDirection::Playback,
- num_channels,
- format,
- 44100,
- buffer_size,
- &[],
- &shm,
- [400, 8000],
- )
- .expect("Failed to create stream");
-
- let request = stream
- .wait_for_next_action_with_timeout(Duration::from_secs(5))
- .expect("Failed to wait for next action");
- match request {
- Some(r) => {
- let requested = r.requested_frames();
- r.set_buffer_offset_and_frames(872, requested)
- .expect("Failed to set buffer offset and frames");
- requested
- }
- None => 0,
- }
- });
-
- let mut stream = stream_source.get_last_stream();
- assert!(stream.trigger_callback_with_timeout(Duration::from_secs(1)));
-
- let requested_frames = handle.join().expect("Failed to join thread");
- assert_eq!(requested_frames, buffer_size);
- }
-
- #[test]
- fn null_consumption_rate() {
- let frame_rate = 44100;
- let buffer_size = 480;
- let interval = Duration::from_millis(buffer_size as u64 * 1000 / frame_rate as u64);
-
- let shm = SharedMemory::anon().expect("Failed to create shm");
-
- let start = Instant::now();
-
- let mut stream_source = NullShmStreamSource::new();
- let mut stream = stream_source
- .new_stream(
- StreamDirection::Playback,
- 2,
- SampleFormat::S24LE,
- frame_rate,
- buffer_size,
- &[],
- &shm,
- [400, 8000],
- )
- .expect("Failed to create stream");
-
- let timeout = Duration::from_secs(5);
- let request = stream
- .wait_for_next_action_with_timeout(timeout)
- .expect("Failed to wait for first request")
- .expect("First request should not have timed out");
- request
- .set_buffer_offset_and_frames(276, 480)
- .expect("Failed to set buffer offset and length");
-
- // The second call should block until the first buffer is consumed.
- let _request = stream
- .wait_for_next_action_with_timeout(timeout)
- .expect("Failed to wait for second request");
- let elapsed = start.elapsed();
- assert!(
- elapsed > interval,
- "wait_for_next_action_with_timeout didn't block long enough: {:?}",
- elapsed
- );
-
- assert!(
- elapsed < timeout,
- "wait_for_next_action_with_timeout blocked for too long: {:?}",
- elapsed
- );
- }
-}
diff --git a/cras-config/bolt/HDA Intel PCH b/cras-config/bolt/HDA Intel PCH
new file mode 100644
index 00000000..b3865e6e
--- /dev/null
+++ b/cras-config/bolt/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Default]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -100
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -300
+ db_at_90 = -300
+ db_at_89 = -300
+ db_at_88 = -300
+ db_at_87 = -400
+ db_at_86 = -400
+ db_at_85 = -400
+ db_at_84 = -400
+ db_at_83 = -500
+ db_at_82 = -500
+ db_at_81 = -500
+ db_at_80 = -500
+ db_at_79 = -600
+ db_at_78 = -600
+ db_at_77 = -600
+ db_at_76 = -600
+ db_at_75 = -700
+ db_at_74 = -700
+ db_at_73 = -700
+ db_at_72 = -700
+ db_at_71 = -800
+ db_at_70 = -800
+ db_at_69 = -800
+ db_at_68 = -800
+ db_at_67 = -900
+ db_at_66 = -900
+ db_at_65 = -900
+ db_at_64 = -900
+ db_at_63 = -900
+ db_at_62 = -900
+ db_at_61 = -900
+ db_at_60 = -1000
+ db_at_59 = -1000
+ db_at_58 = -1000
+ db_at_57 = -1000
+ db_at_56 = -1100
+ db_at_55 = -1100
+ db_at_54 = -1100
+ db_at_53 = -1100
+ db_at_52 = -1200
+ db_at_51 = -1200
+ db_at_50 = -1200
+ db_at_49 = -1200
+ db_at_48 = -1300
+ db_at_47 = -1300
+ db_at_46 = -1300
+ db_at_45 = -1300
+ db_at_44 = -1400
+ db_at_43 = -1400
+ db_at_42 = -1400
+ db_at_41 = -1400
+ db_at_40 = -1500
+ db_at_39 = -1600
+ db_at_38 = -1600
+ db_at_37 = -1700
+ db_at_36 = -1700
+ db_at_35 = -1800
+ db_at_34 = -1900
+ db_at_33 = -2000
+ db_at_32 = -2100
+ db_at_31 = -2200
+ db_at_30 = -2300
+ db_at_29 = -2400
+ db_at_28 = -2500
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2800
+ db_at_24 = -2900
+ db_at_23 = -3000
+ db_at_22 = -3100
+ db_at_21 = -3200
+ db_at_20 = -3300
+ db_at_19 = -3400
+ db_at_18 = -3500
+ db_at_17 = -3600
+ db_at_16 = -3700
+ db_at_15 = -3800
+ db_at_14 = -3900
+ db_at_13 = -4000
+ db_at_12 = -4100
+ db_at_11 = -4200
+ db_at_10 = -4300
+ db_at_9 = -4400
+ db_at_8 = -4500
+ db_at_7 = -4600
+ db_at_6 = -4800
+ db_at_5 = -5000
+ db_at_4 = -5200
+ db_at_3 = -5400
+ db_at_2 = -5600
+ db_at_1 = -5800
+ db_at_0 = -6000
+[Front Headphone Jack]
+ volume_curve = simple_step
+ volume_step = 75
+ max_volume = -900
diff --git a/cras-config/cid/HDA Intel PCH b/cras-config/cid/HDA Intel PCH
new file mode 100644
index 00000000..e0adc3e9
--- /dev/null
+++ b/cras-config/cid/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -75
+ db_at_95 = -75
+ db_at_94 = -150
+ db_at_93 = -150
+ db_at_92 = -150
+ db_at_91 = -150
+ db_at_90 = -225
+ db_at_89 = -225
+ db_at_88 = -225
+ db_at_87 = -225
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -375
+ db_at_81 = -375
+ db_at_80 = -450
+ db_at_79 = -450
+ db_at_78 = -450
+ db_at_77 = -450
+ db_at_76 = -525
+ db_at_75 = -525
+ db_at_74 = -600
+ db_at_73 = -600
+ db_at_72 = -600
+ db_at_71 = -600
+ db_at_70 = -675
+ db_at_69 = -675
+ db_at_68 = -675
+ db_at_67 = -675
+ db_at_66 = -750
+ db_at_65 = -750
+ db_at_64 = -825
+ db_at_63 = -825
+ db_at_62 = -825
+ db_at_61 = -825
+ db_at_60 = -900
+ db_at_59 = -900
+ db_at_58 = -900
+ db_at_57 = -900
+ db_at_56 = -975
+ db_at_55 = -975
+ db_at_54 = -1050
+ db_at_53 = -1050
+ db_at_52 = -1050
+ db_at_51 = -1050
+ db_at_50 = -1125
+ db_at_49 = -1125
+ db_at_48 = -1200
+ db_at_47 = -1200
+ db_at_46 = -1200
+ db_at_45 = -1200
+ db_at_44 = -1275
+ db_at_43 = -1275
+ db_at_42 = -1275
+ db_at_41 = -1275
+ db_at_40 = -1350
+ db_at_39 = -1425
+ db_at_38 = -1425
+ db_at_37 = -1500
+ db_at_36 = -1500
+ db_at_35 = -1575
+ db_at_34 = -1650
+ db_at_33 = -1650
+ db_at_32 = -1725
+ db_at_31 = -1800
+ db_at_30 = -1800
+ db_at_29 = -1800
+ db_at_28 = -1875
+ db_at_27 = -2025
+ db_at_26 = -2100
+ db_at_25 = -2100
+ db_at_24 = -2175
+ db_at_23 = -2250
+ db_at_22 = -2400
+ db_at_21 = -2475
+ db_at_20 = -2550
+ db_at_19 = -2625
+ db_at_18 = -2700
+ db_at_17 = -2850
+ db_at_16 = -2925
+ db_at_15 = -3000
+ db_at_14 = -3075
+ db_at_13 = -3225
+ db_at_12 = -3300
+ db_at_11 = -3375
+ db_at_10 = -3450
+ db_at_9 = -3600
+ db_at_8 = -3675
+ db_at_7 = -3750
+ db_at_6 = -3825
+ db_at_5 = -3900
+ db_at_4 = -4050
+ db_at_3 = -4050
+ db_at_2 = -4275
+ db_at_1 = -4500
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 50
+ max_volume = 0
diff --git a/cras-config/daisy/DAISY-I2S b/cras-config/daisy/DAISY-I2S
new file mode 100755
index 00000000..949658d6
--- /dev/null
+++ b/cras-config/daisy/DAISY-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -900
+ db_at_99 = -900
+ db_at_98 = -900
+ db_at_97 = -950
+ db_at_96 = -950
+ db_at_95 = -950
+ db_at_94 = -1000
+ db_at_93 = -1000
+ db_at_92 = -1000
+ db_at_91 = -1050
+ db_at_90 = -1050
+ db_at_89 = -1050
+ db_at_88 = -1100
+ db_at_87 = -1100
+ db_at_86 = -1100
+ db_at_85 = -1150
+ db_at_84 = -1150
+ db_at_83 = -1150
+ db_at_82 = -1200
+ db_at_81 = -1200
+ db_at_80 = -1200
+ db_at_79 = -1250
+ db_at_78 = -1250
+ db_at_77 = -1250
+ db_at_76 = -1300
+ db_at_75 = -1300
+ db_at_74 = -1300
+ db_at_73 = -1350
+ db_at_72 = -1350
+ db_at_71 = -1350
+ db_at_70 = -1425
+ db_at_69 = -1425
+ db_at_68 = -1425
+ db_at_67 = -1500
+ db_at_66 = -1500
+ db_at_65 = -1500
+ db_at_64 = -1575
+ db_at_63 = -1575
+ db_at_62 = -1575
+ db_at_61 = -1650
+ db_at_60 = -1650
+ db_at_59 = -1650
+ db_at_58 = -1725
+ db_at_57 = -1725
+ db_at_56 = -1725
+ db_at_55 = -1800
+ db_at_54 = -1800
+ db_at_53 = -1800
+ db_at_52 = -1900
+ db_at_51 = -1900
+ db_at_50 = -1900
+ db_at_49 = -2000
+ db_at_48 = -2000
+ db_at_47 = -2000
+ db_at_46 = -2100
+ db_at_45 = -2100
+ db_at_44 = -2100
+ db_at_43 = -2200
+ db_at_42 = -2200
+ db_at_41 = -2200
+ db_at_40 = -2350
+ db_at_39 = -2350
+ db_at_38 = -2350
+ db_at_37 = -2500
+ db_at_36 = -2500
+ db_at_35 = -2500
+ db_at_34 = -2650
+ db_at_33 = -2650
+ db_at_32 = -2650
+ db_at_31 = -2725
+ db_at_30 = -2725
+ db_at_29 = -2800
+ db_at_28 = -3000
+ db_at_27 = -3000
+ db_at_26 = -3000
+ db_at_25 = -3200
+ db_at_24 = -3200
+ db_at_23 = -3200
+ db_at_22 = -3200
+ db_at_21 = -3600
+ db_at_20 = -3600
+ db_at_19 = -4000
+ db_at_18 = -4000
+ db_at_17 = -4000
+ db_at_16 = -4000
+ db_at_15 = -4400
+ db_at_14 = -4400
+ db_at_13 = -4400
+ db_at_12 = -4400
+ db_at_11 = -4800
+ db_at_10 = -4800
+ db_at_9 = -4800
+ db_at_8 = -4800
+ db_at_7 = -5000
+ db_at_6 = -5000
+ db_at_5 = -5200
+ db_at_4 = -5200
+ db_at_3 = -5200
+ db_at_2 = -5200
+ db_at_1 = -5600
+ db_at_0 = -6000
+[Headphone]
+ volume_curve = simple_step ; Headphones allowed full range, 0.5dB per step, 50dB total range.
+ volume_step = 50
+ max_volume = -200
diff --git a/cras-config/daisy/DAISY-I2S-98090 b/cras-config/daisy/DAISY-I2S-98090
new file mode 100755
index 00000000..f6420238
--- /dev/null
+++ b/cras-config/daisy/DAISY-I2S-98090
@@ -0,0 +1,206 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -500
+ db_at_98 = -500
+ db_at_97 = -500
+ db_at_96 = -600
+ db_at_95 = -600
+ db_at_94 = -600
+ db_at_93 = -600
+ db_at_92 = -700
+ db_at_91 = -700
+ db_at_90 = -700
+ db_at_89 = -700
+ db_at_88 = -800
+ db_at_87 = -800
+ db_at_86 = -800
+ db_at_85 = -800
+ db_at_84 = -900
+ db_at_83 = -900
+ db_at_82 = -900
+ db_at_81 = -900
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1000
+ db_at_76 = -1100
+ db_at_75 = -1100
+ db_at_74 = -1100
+ db_at_73 = -1100
+ db_at_72 = -1200
+ db_at_71 = -1200
+ db_at_70 = -1200
+ db_at_69 = -1200
+ db_at_68 = -1300
+ db_at_67 = -1300
+ db_at_66 = -1300
+ db_at_65 = -1300
+ db_at_64 = -1400
+ db_at_63 = -1400
+ db_at_62 = -1400
+ db_at_61 = -1400
+ db_at_60 = -1500
+ db_at_59 = -1500
+ db_at_58 = -1500
+ db_at_57 = -1500
+ db_at_56 = -1600
+ db_at_55 = -1600
+ db_at_54 = -1600
+ db_at_53 = -1600
+ db_at_52 = -1700
+ db_at_51 = -1700
+ db_at_50 = -1700
+ db_at_49 = -1700
+ db_at_48 = -1800
+ db_at_47 = -1800
+ db_at_46 = -1800
+ db_at_45 = -1800
+ db_at_44 = -1900
+ db_at_43 = -1900
+ db_at_42 = -1900
+ db_at_41 = -1900
+ db_at_40 = -2100
+ db_at_39 = -2100
+ db_at_38 = -2100
+ db_at_37 = -2100
+ db_at_36 = -2300
+ db_at_35 = -2300
+ db_at_34 = -2300
+ db_at_33 = -2300
+ db_at_32 = -2500
+ db_at_31 = -2500
+ db_at_30 = -2500
+ db_at_29 = -2500
+ db_at_28 = -2700
+ db_at_27 = -2700
+ db_at_26 = -2700
+ db_at_25 = -2700
+ db_at_24 = -2900
+ db_at_23 = -2900
+ db_at_22 = -2900
+ db_at_21 = -2900
+ db_at_20 = -3300
+ db_at_19 = -3300
+ db_at_18 = -3300
+ db_at_17 = -3300
+ db_at_16 = -3600
+ db_at_15 = -3600
+ db_at_14 = -3600
+ db_at_13 = -3600
+ db_at_12 = -4300
+ db_at_11 = -4300
+ db_at_10 = -4300
+ db_at_9 = -4300
+ db_at_8 = -4900
+ db_at_7 = -4900
+ db_at_6 = -4900
+ db_at_5 = -4900
+ db_at_4 = -5500
+ db_at_3 = -5500
+ db_at_2 = -5500
+ db_at_1 = -5500
+ db_at_0 = -6500
+[Headphone]
+ volume_curve = explicit
+ db_at_100 = -1000
+ db_at_99 = -1000
+ db_at_98 = -1000
+ db_at_97 = -1000
+ db_at_96 = -1200
+ db_at_95 = -1200
+ db_at_94 = -1200
+ db_at_93 = -1200
+ db_at_92 = -1400
+ db_at_91 = -1400
+ db_at_90 = -1400
+ db_at_89 = -1400
+ db_at_88 = -1600
+ db_at_87 = -1600
+ db_at_86 = -1600
+ db_at_85 = -1600
+ db_at_84 = -1800
+ db_at_83 = -1800
+ db_at_82 = -1800
+ db_at_81 = -1800
+ db_at_80 = -2000
+ db_at_79 = -2000
+ db_at_78 = -2000
+ db_at_77 = -2000
+ db_at_76 = -2200
+ db_at_75 = -2200
+ db_at_74 = -2200
+ db_at_73 = -2200
+ db_at_72 = -2300
+ db_at_71 = -2300
+ db_at_70 = -2300
+ db_at_69 = -2300
+ db_at_68 = -2500
+ db_at_67 = -2500
+ db_at_66 = -2500
+ db_at_65 = -2500
+ db_at_64 = -2700
+ db_at_63 = -2700
+ db_at_62 = -2700
+ db_at_61 = -2700
+ db_at_60 = -2900
+ db_at_59 = -2900
+ db_at_58 = -2900
+ db_at_57 = -2900
+ db_at_56 = -3100
+ db_at_55 = -3100
+ db_at_54 = -3100
+ db_at_53 = -3100
+ db_at_52 = -3300
+ db_at_51 = -3300
+ db_at_50 = -3300
+ db_at_49 = -3300
+ db_at_48 = -3500
+ db_at_47 = -3500
+ db_at_46 = -3500
+ db_at_45 = -3500
+ db_at_44 = -3700
+ db_at_43 = -3700
+ db_at_42 = -3700
+ db_at_41 = -3700
+ db_at_40 = -4000
+ db_at_39 = -4000
+ db_at_38 = -4000
+ db_at_37 = -4000
+ db_at_36 = -4300
+ db_at_35 = -4300
+ db_at_34 = -4300
+ db_at_33 = -4300
+ db_at_32 = -4600
+ db_at_31 = -4600
+ db_at_30 = -4600
+ db_at_29 = -4600
+ db_at_28 = -4900
+ db_at_27 = -4900
+ db_at_26 = -4900
+ db_at_25 = -4900
+ db_at_24 = -5200
+ db_at_23 = -5200
+ db_at_22 = -5200
+ db_at_21 = -5200
+ db_at_20 = -5500
+ db_at_19 = -5500
+ db_at_18 = -5500
+ db_at_17 = -5500
+ db_at_16 = -5800
+ db_at_15 = -5800
+ db_at_14 = -5800
+ db_at_13 = -5800
+ db_at_12 = -6200
+ db_at_11 = -6200
+ db_at_10 = -6200
+ db_at_9 = -6200
+ db_at_8 = -6600
+ db_at_7 = -6600
+ db_at_6 = -6600
+ db_at_5 = -6600
+ db_at_4 = -7000
+ db_at_3 = -7000
+ db_at_2 = -7000
+ db_at_1 = -7000
+ db_at_0 = -7400
diff --git a/cras-config/daisy/dsp.ini b/cras-config/daisy/dsp.ini
new file mode 100644
index 00000000..e675d558
--- /dev/null
+++ b/cras-config/daisy/dsp.ini
@@ -0,0 +1,46 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[eq2]
+library=builtin
+label=eq2
+input_0={src:0}
+input_1={src:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=150 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=150 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=1051 ; freq
+input_14=2 ; Q
+input_15=-3 ; gain
+input_16=6 ; peaking
+input_17=1051 ; freq
+input_18=2 ; Q
+input_19=-3 ; gain
+input_20=6 ; peaking
+input_21=4146 ; freq
+input_22=3 ; Q
+input_23=-3 ; gain
+input_24=6 ; peaking
+input_25=4146 ; freq
+input_26=3 ; Q
+input_27=-3 ; gain
diff --git a/cras-config/daisy_skate/dsp.ini b/cras-config/daisy_skate/dsp.ini
new file mode 100644
index 00000000..7c94fc0d
--- /dev/null
+++ b/cras-config/daisy_skate/dsp.ini
@@ -0,0 +1,111 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=2 ; boost
+input_13=200 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=30 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=2 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=2 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=200 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=200 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=350 ; freq
+input_14=1 ; Q
+input_15=3 ; gain
+input_16=6 ; peaking
+input_17=350 ; freq
+input_18=1 ; Q
+input_19=3 ; gain
+input_20=6 ; peaking
+input_21=1000 ; freq
+input_22=1 ; Q
+input_23=-8 ; gain
+input_24=6 ; peaking
+input_25=1000 ; freq
+input_26=1 ; Q
+input_27=-8 ; gain
+input_28=6 ; peaking
+input_29=5000 ; freq
+input_30=1 ; Q
+input_31=3 ; gain
+input_32=6 ; peaking
+input_33=5000 ; freq
+input_34=1 ; Q
+input_35=3 ; gain
+input_36=6 ; peaking
+input_37=8000 ; freq
+input_38=1 ; Q
+input_39=3 ; gain
+input_40=6 ; peaking
+input_41=8000 ; freq
+input_42=1 ; Q
+input_43=3 ; gain
+input_44=6 ; peaking
+input_45=10000 ; freq
+input_46=1 ; Q
+input_47=3 ; gain
+input_48=6 ; peaking
+input_49=10000 ; freq
+input_50=1 ; Q
+input_51=3 ; gain
+input_52=6 ; peaking
+input_53=2000 ; freq
+input_54=1 ; Q
+input_55=-2 ; gain
+input_56=6 ; peaking
+input_57=2000 ; freq
+input_58=1 ; Q
+input_59=-2 ; gain
diff --git a/cras-config/daisy_spring/DAISY-I2S b/cras-config/daisy_spring/DAISY-I2S
new file mode 100755
index 00000000..ae9801a4
--- /dev/null
+++ b/cras-config/daisy_spring/DAISY-I2S
@@ -0,0 +1,206 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -100
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -300
+ db_at_90 = -300
+ db_at_89 = -300
+ db_at_88 = -300
+ db_at_87 = -400
+ db_at_86 = -400
+ db_at_85 = -400
+ db_at_84 = -400
+ db_at_83 = -500
+ db_at_82 = -500
+ db_at_81 = -500
+ db_at_80 = -500
+ db_at_79 = -600
+ db_at_78 = -600
+ db_at_77 = -600
+ db_at_76 = -600
+ db_at_75 = -700
+ db_at_74 = -700
+ db_at_73 = -700
+ db_at_72 = -700
+ db_at_71 = -800
+ db_at_70 = -800
+ db_at_69 = -800
+ db_at_68 = -800
+ db_at_67 = -1000
+ db_at_66 = -1000
+ db_at_65 = -1000
+ db_at_64 = -1000
+ db_at_63 = -1000
+ db_at_62 = -1000
+ db_at_61 = -1000
+ db_at_60 = -1000
+ db_at_59 = -1200
+ db_at_58 = -1200
+ db_at_57 = -1200
+ db_at_56 = -1200
+ db_at_55 = -1200
+ db_at_54 = -1200
+ db_at_53 = -1200
+ db_at_52 = -1400
+ db_at_51 = -1400
+ db_at_50 = -1400
+ db_at_49 = -1400
+ db_at_48 = -1400
+ db_at_47 = -1400
+ db_at_46 = -1400
+ db_at_45 = -1400
+ db_at_44 = -1600
+ db_at_43 = -1600
+ db_at_42 = -1600
+ db_at_41 = -1600
+ db_at_40 = -1600
+ db_at_39 = -1600
+ db_at_38 = -1600
+ db_at_37 = -1600
+ db_at_36 = -1800
+ db_at_35 = -1800
+ db_at_34 = -1800
+ db_at_33 = -2000
+ db_at_32 = -2000
+ db_at_31 = -2200
+ db_at_30 = -2200
+ db_at_29 = -2500
+ db_at_28 = -2500
+ db_at_27 = -2500
+ db_at_26 = -2500
+ db_at_25 = -2800
+ db_at_24 = -2800
+ db_at_23 = -2800
+ db_at_22 = -3100
+ db_at_21 = -3100
+ db_at_20 = -3100
+ db_at_19 = -3400
+ db_at_18 = -3400
+ db_at_17 = -3400
+ db_at_16 = -3400
+ db_at_15 = -3700
+ db_at_14 = -3700
+ db_at_13 = -4000
+ db_at_12 = -4000
+ db_at_11 = -4300
+ db_at_10 = -4300
+ db_at_9 = -4600
+ db_at_8 = -4600
+ db_at_7 = -4600
+ db_at_6 = -5000
+ db_at_5 = -5000
+ db_at_4 = -5400
+ db_at_3 = -5400
+ db_at_2 = -5800
+ db_at_1 = -5800
+ db_at_0 = -6200
+[Headphone]
+ volume_curve = explicit
+ db_at_100 = -300
+ db_at_99 = -300
+ db_at_98 = -300
+ db_at_97 = -300
+ db_at_96 = -400
+ db_at_95 = -400
+ db_at_94 = -400
+ db_at_93 = -400
+ db_at_92 = -600
+ db_at_91 = -600
+ db_at_90 = -600
+ db_at_89 = -600
+ db_at_88 = -700
+ db_at_87 = -700
+ db_at_86 = -700
+ db_at_85 = -700
+ db_at_84 = -800
+ db_at_83 = -800
+ db_at_82 = -800
+ db_at_81 = -800
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1000
+ db_at_76 = -1200
+ db_at_75 = -1200
+ db_at_74 = -1200
+ db_at_73 = -1200
+ db_at_72 = -1400
+ db_at_71 = -1400
+ db_at_70 = -1400
+ db_at_69 = -1400
+ db_at_68 = -1600
+ db_at_67 = -1600
+ db_at_66 = -1600
+ db_at_65 = -1600
+ db_at_64 = -1800
+ db_at_63 = -1800
+ db_at_62 = -1800
+ db_at_61 = -1800
+ db_at_60 = -2000
+ db_at_59 = -2000
+ db_at_58 = -2000
+ db_at_57 = -2000
+ db_at_56 = -2200
+ db_at_55 = -2200
+ db_at_54 = -2200
+ db_at_53 = -2200
+ db_at_52 = -2500
+ db_at_51 = -2500
+ db_at_50 = -2500
+ db_at_49 = -2500
+ db_at_48 = -2800
+ db_at_47 = -2800
+ db_at_46 = -2800
+ db_at_45 = -2800
+ db_at_44 = -3100
+ db_at_43 = -3100
+ db_at_42 = -3100
+ db_at_41 = -3100
+ db_at_40 = -3400
+ db_at_39 = -3400
+ db_at_38 = -3400
+ db_at_37 = -3400
+ db_at_36 = -3700
+ db_at_35 = -3700
+ db_at_34 = -3700
+ db_at_33 = -3700
+ db_at_32 = -4000
+ db_at_31 = -4000
+ db_at_30 = -4000
+ db_at_29 = -4000
+ db_at_28 = -4300
+ db_at_27 = -4300
+ db_at_26 = -4300
+ db_at_25 = -4300
+ db_at_24 = -4700
+ db_at_23 = -4700
+ db_at_22 = -4700
+ db_at_21 = -4700
+ db_at_20 = -5100
+ db_at_19 = -5100
+ db_at_18 = -5100
+ db_at_17 = -5100
+ db_at_16 = -5500
+ db_at_15 = -5500
+ db_at_14 = -5500
+ db_at_13 = -5500
+ db_at_12 = -5900
+ db_at_11 = -5900
+ db_at_10 = -5900
+ db_at_9 = -5900
+ db_at_8 = -6300
+ db_at_7 = -6300
+ db_at_6 = -6300
+ db_at_5 = -6300
+ db_at_4 = -6700
+ db_at_3 = -6700
+ db_at_2 = -6700
+ db_at_1 = -6700
+ db_at_0 = -6700
diff --git a/cras-config/daisy_spring/dsp.ini b/cras-config/daisy_spring/dsp.ini
new file mode 100644
index 00000000..19ba9453
--- /dev/null
+++ b/cras-config/daisy_spring/dsp.ini
@@ -0,0 +1,95 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=0 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-30 ; threshold
+input_8=12 ; knee
+input_9=10.384 ; ratio
+input_10=0.02 ; attack
+input_11=1 ; release
+input_12=0 ; boost
+input_13=600 ; f
+input_14=1 ; enable
+input_15=-32 ; threshold
+input_16=21 ; knee
+input_17=12 ; ratio
+input_18=0.02 ; attack
+input_19=0.2 ; release
+input_20=1 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-24 ; threshold
+input_24=21 ; knee
+input_25=6.329 ; ratio
+input_26=0.02 ; attack
+input_27=0.2 ; release
+input_28=-1 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=6 ; peaking
+input_5=380 ; freq
+input_6=3 ; Q
+input_7=-10 ; gain
+input_8=6 ; peaking
+input_9=450 ; freq
+input_10=3 ; Q
+input_11=-12 ; gain
+input_12=6 ; peaking
+input_13=720 ; freq
+input_14=3 ; Q
+input_15=-12 ; gain
+input_16=6 ; peaking
+input_17=721 ; freq
+input_18=3 ; Q
+input_19=-12 ; gain
+input_20=6 ; peaking
+input_21=1705 ; freq
+input_22=3 ; Q
+input_23=-8 ; gain
+input_24=6 ; peaking
+input_25=1800 ; freq
+input_26=8 ; Q
+input_27=-10.2 ; gain
+input_28=6 ; peaking
+input_29=580 ; freq
+input_30=6 ; Q
+input_31=-8 ; gain
+input_32=6 ; peaking
+input_33=580 ; freq
+input_34=6 ; Q
+input_35=-8 ; gain
+input_36=2 ; highpass
+input_37=218 ; freq
+input_38=0.7 ; Q
+input_39=2 ; gain
+input_40=2 ; highpass
+input_41=250 ; freq
+input_42=0.7 ; Q
+input_43=0.6578 ; gain
diff --git a/cras-config/device_blocklist b/cras-config/device_blacklist
index 19a9b033..19a9b033 100644
--- a/cras-config/device_blocklist
+++ b/cras-config/device_blacklist
diff --git a/cras-config/falco/HDA Intel PCH b/cras-config/falco/HDA Intel PCH
new file mode 100644
index 00000000..e0adc3e9
--- /dev/null
+++ b/cras-config/falco/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -75
+ db_at_95 = -75
+ db_at_94 = -150
+ db_at_93 = -150
+ db_at_92 = -150
+ db_at_91 = -150
+ db_at_90 = -225
+ db_at_89 = -225
+ db_at_88 = -225
+ db_at_87 = -225
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -375
+ db_at_81 = -375
+ db_at_80 = -450
+ db_at_79 = -450
+ db_at_78 = -450
+ db_at_77 = -450
+ db_at_76 = -525
+ db_at_75 = -525
+ db_at_74 = -600
+ db_at_73 = -600
+ db_at_72 = -600
+ db_at_71 = -600
+ db_at_70 = -675
+ db_at_69 = -675
+ db_at_68 = -675
+ db_at_67 = -675
+ db_at_66 = -750
+ db_at_65 = -750
+ db_at_64 = -825
+ db_at_63 = -825
+ db_at_62 = -825
+ db_at_61 = -825
+ db_at_60 = -900
+ db_at_59 = -900
+ db_at_58 = -900
+ db_at_57 = -900
+ db_at_56 = -975
+ db_at_55 = -975
+ db_at_54 = -1050
+ db_at_53 = -1050
+ db_at_52 = -1050
+ db_at_51 = -1050
+ db_at_50 = -1125
+ db_at_49 = -1125
+ db_at_48 = -1200
+ db_at_47 = -1200
+ db_at_46 = -1200
+ db_at_45 = -1200
+ db_at_44 = -1275
+ db_at_43 = -1275
+ db_at_42 = -1275
+ db_at_41 = -1275
+ db_at_40 = -1350
+ db_at_39 = -1425
+ db_at_38 = -1425
+ db_at_37 = -1500
+ db_at_36 = -1500
+ db_at_35 = -1575
+ db_at_34 = -1650
+ db_at_33 = -1650
+ db_at_32 = -1725
+ db_at_31 = -1800
+ db_at_30 = -1800
+ db_at_29 = -1800
+ db_at_28 = -1875
+ db_at_27 = -2025
+ db_at_26 = -2100
+ db_at_25 = -2100
+ db_at_24 = -2175
+ db_at_23 = -2250
+ db_at_22 = -2400
+ db_at_21 = -2475
+ db_at_20 = -2550
+ db_at_19 = -2625
+ db_at_18 = -2700
+ db_at_17 = -2850
+ db_at_16 = -2925
+ db_at_15 = -3000
+ db_at_14 = -3075
+ db_at_13 = -3225
+ db_at_12 = -3300
+ db_at_11 = -3375
+ db_at_10 = -3450
+ db_at_9 = -3600
+ db_at_8 = -3675
+ db_at_7 = -3750
+ db_at_6 = -3825
+ db_at_5 = -3900
+ db_at_4 = -4050
+ db_at_3 = -4050
+ db_at_2 = -4275
+ db_at_1 = -4500
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 50
+ max_volume = 0
diff --git a/cras-config/falco/dsp.ini b/cras-config/falco/dsp.ini
new file mode 100644
index 00000000..a2b11097
--- /dev/null
+++ b/cras-config/falco/dsp.ini
@@ -0,0 +1,111 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=0 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=2 ; boost
+input_13=200 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=30 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=2 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=2 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=200 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=200 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=350 ; freq
+input_14=1 ; Q
+input_15=3 ; gain
+input_16=6 ; peaking
+input_17=350 ; freq
+input_18=1 ; Q
+input_19=3 ; gain
+input_20=6 ; peaking
+input_21=1000 ; freq
+input_22=1 ; Q
+input_23=-8 ; gain
+input_24=6 ; peaking
+input_25=1000 ; freq
+input_26=1 ; Q
+input_27=-8 ; gain
+input_28=6 ; peaking
+input_29=5000 ; freq
+input_30=1 ; Q
+input_31=3 ; gain
+input_32=6 ; peaking
+input_33=5000 ; freq
+input_34=1 ; Q
+input_35=3 ; gain
+input_36=6 ; peaking
+input_37=8000 ; freq
+input_38=1 ; Q
+input_39=3 ; gain
+input_40=6 ; peaking
+input_41=8000 ; freq
+input_42=1 ; Q
+input_43=3 ; gain
+input_44=6 ; peaking
+input_45=10000 ; freq
+input_46=1 ; Q
+input_47=3 ; gain
+input_48=6 ; peaking
+input_49=10000 ; freq
+input_50=1 ; Q
+input_51=3 ; gain
+input_52=6 ; peaking
+input_53=2000 ; freq
+input_54=1 ; Q
+input_55=-2 ; gain
+input_56=6 ; peaking
+input_57=2000 ; freq
+input_58=1 ; Q
+input_59=-2 ; gain
diff --git a/cras-config/leon/HDA Intel PCH b/cras-config/leon/HDA Intel PCH
new file mode 100644
index 00000000..e0adc3e9
--- /dev/null
+++ b/cras-config/leon/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -75
+ db_at_95 = -75
+ db_at_94 = -150
+ db_at_93 = -150
+ db_at_92 = -150
+ db_at_91 = -150
+ db_at_90 = -225
+ db_at_89 = -225
+ db_at_88 = -225
+ db_at_87 = -225
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -375
+ db_at_81 = -375
+ db_at_80 = -450
+ db_at_79 = -450
+ db_at_78 = -450
+ db_at_77 = -450
+ db_at_76 = -525
+ db_at_75 = -525
+ db_at_74 = -600
+ db_at_73 = -600
+ db_at_72 = -600
+ db_at_71 = -600
+ db_at_70 = -675
+ db_at_69 = -675
+ db_at_68 = -675
+ db_at_67 = -675
+ db_at_66 = -750
+ db_at_65 = -750
+ db_at_64 = -825
+ db_at_63 = -825
+ db_at_62 = -825
+ db_at_61 = -825
+ db_at_60 = -900
+ db_at_59 = -900
+ db_at_58 = -900
+ db_at_57 = -900
+ db_at_56 = -975
+ db_at_55 = -975
+ db_at_54 = -1050
+ db_at_53 = -1050
+ db_at_52 = -1050
+ db_at_51 = -1050
+ db_at_50 = -1125
+ db_at_49 = -1125
+ db_at_48 = -1200
+ db_at_47 = -1200
+ db_at_46 = -1200
+ db_at_45 = -1200
+ db_at_44 = -1275
+ db_at_43 = -1275
+ db_at_42 = -1275
+ db_at_41 = -1275
+ db_at_40 = -1350
+ db_at_39 = -1425
+ db_at_38 = -1425
+ db_at_37 = -1500
+ db_at_36 = -1500
+ db_at_35 = -1575
+ db_at_34 = -1650
+ db_at_33 = -1650
+ db_at_32 = -1725
+ db_at_31 = -1800
+ db_at_30 = -1800
+ db_at_29 = -1800
+ db_at_28 = -1875
+ db_at_27 = -2025
+ db_at_26 = -2100
+ db_at_25 = -2100
+ db_at_24 = -2175
+ db_at_23 = -2250
+ db_at_22 = -2400
+ db_at_21 = -2475
+ db_at_20 = -2550
+ db_at_19 = -2625
+ db_at_18 = -2700
+ db_at_17 = -2850
+ db_at_16 = -2925
+ db_at_15 = -3000
+ db_at_14 = -3075
+ db_at_13 = -3225
+ db_at_12 = -3300
+ db_at_11 = -3375
+ db_at_10 = -3450
+ db_at_9 = -3600
+ db_at_8 = -3675
+ db_at_7 = -3750
+ db_at_6 = -3825
+ db_at_5 = -3900
+ db_at_4 = -4050
+ db_at_3 = -4050
+ db_at_2 = -4275
+ db_at_1 = -4500
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 50
+ max_volume = 0
diff --git a/cras-config/leon/dsp.ini b/cras-config/leon/dsp.ini
new file mode 100644
index 00000000..14476470
--- /dev/null
+++ b/cras-config/leon/dsp.ini
@@ -0,0 +1,79 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=0 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-20 ; threshold
+input_8=25 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=4 ; boost
+input_13=579 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=31 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=-3 ; boost
+input_21=2164 ; f
+input_22=1 ; enable
+input_23=-25 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=4 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=231 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=218 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=728 ; freq
+input_14=1.5264 ; Q
+input_15=-7.8 ; gain
+input_16=6 ; peaking
+input_17=728 ; freq
+input_18=1.6351 ; Q
+input_19=-8.8 ; gain
+input_20=2 ; highpass
+input_21=164 ; freq
+input_22=3.3685 ; Q
+input_23=0 ; gain
+input_24=2 ; highpass
+input_25=164 ; freq
+input_26=3.3685 ; Q
+input_27=0 ; gain
diff --git a/cras-config/link/HDA Intel PCH b/cras-config/link/HDA Intel PCH
new file mode 100644
index 00000000..5344a083
--- /dev/null
+++ b/cras-config/link/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Default]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -100
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -300
+ db_at_90 = -300
+ db_at_89 = -300
+ db_at_88 = -300
+ db_at_87 = -400
+ db_at_86 = -400
+ db_at_85 = -400
+ db_at_84 = -400
+ db_at_83 = -500
+ db_at_82 = -500
+ db_at_81 = -500
+ db_at_80 = -500
+ db_at_79 = -600
+ db_at_78 = -600
+ db_at_77 = -600
+ db_at_76 = -600
+ db_at_75 = -700
+ db_at_74 = -700
+ db_at_73 = -700
+ db_at_72 = -700
+ db_at_71 = -800
+ db_at_70 = -800
+ db_at_69 = -800
+ db_at_68 = -800
+ db_at_67 = -900
+ db_at_66 = -900
+ db_at_65 = -900
+ db_at_64 = -900
+ db_at_63 = -900
+ db_at_62 = -900
+ db_at_61 = -900
+ db_at_60 = -1000
+ db_at_59 = -1000
+ db_at_58 = -1000
+ db_at_57 = -1000
+ db_at_56 = -1100
+ db_at_55 = -1100
+ db_at_54 = -1100
+ db_at_53 = -1100
+ db_at_52 = -1200
+ db_at_51 = -1200
+ db_at_50 = -1200
+ db_at_49 = -1200
+ db_at_48 = -1300
+ db_at_47 = -1300
+ db_at_46 = -1300
+ db_at_45 = -1300
+ db_at_44 = -1400
+ db_at_43 = -1400
+ db_at_42 = -1400
+ db_at_41 = -1400
+ db_at_40 = -1500
+ db_at_39 = -1600
+ db_at_38 = -1600
+ db_at_37 = -1700
+ db_at_36 = -1700
+ db_at_35 = -1800
+ db_at_34 = -1900
+ db_at_33 = -2000
+ db_at_32 = -2100
+ db_at_31 = -2200
+ db_at_30 = -2300
+ db_at_29 = -2400
+ db_at_28 = -2500
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2800
+ db_at_24 = -2900
+ db_at_23 = -3000
+ db_at_22 = -3100
+ db_at_21 = -3200
+ db_at_20 = -3300
+ db_at_19 = -3400
+ db_at_18 = -3500
+ db_at_17 = -3600
+ db_at_16 = -3700
+ db_at_15 = -3800
+ db_at_14 = -3900
+ db_at_13 = -4000
+ db_at_12 = -4100
+ db_at_11 = -4200
+ db_at_10 = -4300
+ db_at_9 = -4400
+ db_at_8 = -4500
+ db_at_7 = -4600
+ db_at_6 = -4800
+ db_at_5 = -5000
+ db_at_4 = -5200
+ db_at_3 = -5400
+ db_at_2 = -5600
+ db_at_1 = -5800
+ db_at_0 = -6000
+[Headphone Jack]
+ volume_curve = simple_step
+ volume_step = 75
+ max_volume = -900
diff --git a/cras-config/peppy/HDA Intel PCH b/cras-config/peppy/HDA Intel PCH
new file mode 100644
index 00000000..e0adc3e9
--- /dev/null
+++ b/cras-config/peppy/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -75
+ db_at_95 = -75
+ db_at_94 = -150
+ db_at_93 = -150
+ db_at_92 = -150
+ db_at_91 = -150
+ db_at_90 = -225
+ db_at_89 = -225
+ db_at_88 = -225
+ db_at_87 = -225
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -375
+ db_at_81 = -375
+ db_at_80 = -450
+ db_at_79 = -450
+ db_at_78 = -450
+ db_at_77 = -450
+ db_at_76 = -525
+ db_at_75 = -525
+ db_at_74 = -600
+ db_at_73 = -600
+ db_at_72 = -600
+ db_at_71 = -600
+ db_at_70 = -675
+ db_at_69 = -675
+ db_at_68 = -675
+ db_at_67 = -675
+ db_at_66 = -750
+ db_at_65 = -750
+ db_at_64 = -825
+ db_at_63 = -825
+ db_at_62 = -825
+ db_at_61 = -825
+ db_at_60 = -900
+ db_at_59 = -900
+ db_at_58 = -900
+ db_at_57 = -900
+ db_at_56 = -975
+ db_at_55 = -975
+ db_at_54 = -1050
+ db_at_53 = -1050
+ db_at_52 = -1050
+ db_at_51 = -1050
+ db_at_50 = -1125
+ db_at_49 = -1125
+ db_at_48 = -1200
+ db_at_47 = -1200
+ db_at_46 = -1200
+ db_at_45 = -1200
+ db_at_44 = -1275
+ db_at_43 = -1275
+ db_at_42 = -1275
+ db_at_41 = -1275
+ db_at_40 = -1350
+ db_at_39 = -1425
+ db_at_38 = -1425
+ db_at_37 = -1500
+ db_at_36 = -1500
+ db_at_35 = -1575
+ db_at_34 = -1650
+ db_at_33 = -1650
+ db_at_32 = -1725
+ db_at_31 = -1800
+ db_at_30 = -1800
+ db_at_29 = -1800
+ db_at_28 = -1875
+ db_at_27 = -2025
+ db_at_26 = -2100
+ db_at_25 = -2100
+ db_at_24 = -2175
+ db_at_23 = -2250
+ db_at_22 = -2400
+ db_at_21 = -2475
+ db_at_20 = -2550
+ db_at_19 = -2625
+ db_at_18 = -2700
+ db_at_17 = -2850
+ db_at_16 = -2925
+ db_at_15 = -3000
+ db_at_14 = -3075
+ db_at_13 = -3225
+ db_at_12 = -3300
+ db_at_11 = -3375
+ db_at_10 = -3450
+ db_at_9 = -3600
+ db_at_8 = -3675
+ db_at_7 = -3750
+ db_at_6 = -3825
+ db_at_5 = -3900
+ db_at_4 = -4050
+ db_at_3 = -4050
+ db_at_2 = -4275
+ db_at_1 = -4500
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 50
+ max_volume = 0
diff --git a/cras-config/peppy/dsp.ini b/cras-config/peppy/dsp.ini
new file mode 100644
index 00000000..e229b199
--- /dev/null
+++ b/cras-config/peppy/dsp.ini
@@ -0,0 +1,119 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=0 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-30 ; threshold
+input_8=24 ; knee
+input_9=6.032 ; ratio
+input_10=0.02 ; attack
+input_11=0.25 ; release
+input_12=2 ; boost
+input_13=326 ; f
+input_14=1 ; enable
+input_15=-27 ; threshold
+input_16=23 ; knee
+input_17=5.634 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=2 ; boost
+input_21=1842 ; f
+input_22=1 ; enable
+input_23=-40 ; threshold
+input_24=37 ; knee
+input_25=5.67 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=3 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=6 ; peaking
+input_5=248 ; freq
+input_6=4.8668 ; Q
+input_7=-7.8 ; gain
+input_8=6 ; peaking
+input_9=688 ; freq
+input_10=2.6911 ; Q
+input_11=-3.9 ; gain
+input_12=6 ; peaking
+input_13=410 ; freq
+input_14=8.5 ; Q
+input_15=-7.3 ; gain
+input_16=6 ; peaking
+input_17=817 ; freq
+input_18=4.1703 ; Q
+input_19=-15 ; gain
+input_20=6 ; peaking
+input_21=5112 ; freq
+input_22=3.957 ; Q
+input_23=-4.4 ; gain
+input_24=6 ; peaking
+input_25=4827 ; freq
+input_26=3.3685 ; Q
+input_27=-6.3 ; gain
+input_28=6 ; peaking
+input_29=819 ; freq
+input_30=2.2529 ; Q
+input_31=-14.1 ; gain
+input_32=6 ; peaking
+input_33=4065 ; freq
+input_34=2.5388 ; Q
+input_35=3 ; gain
+input_36=6 ; peaking
+input_37=4065 ; freq
+input_38=5.9436 ; Q
+input_39=3 ; gain
+input_40=6 ; peaking
+input_41=2292 ; freq
+input_42=2.6 ; Q
+input_43=1.5 ; gain
+input_44=6 ; peaking
+input_45=2292 ; freq
+input_46=2.6911 ; Q
+input_47=1.5 ; gain
+input_48=5 ; highshelf
+input_49=8960 ; freq
+input_50=2.1187 ; Q
+input_51=2.6 ; gain
+input_52=2 ; highpass
+input_53=293 ; freq
+input_54=1.0465 ; Q
+input_55=0 ; gain
+input_56=2 ; highpass
+input_57=343 ; freq
+input_58=1.4222 ; Q
+input_59=0 ; gain
+input_60=5 ; highshelf
+input_61=8960 ; freq
+input_62=1 ; Q
+input_63=2.6 ; gain
+input_64=0 ; none
+input_65=0 ; freq
+input_66=0 ; Q
+input_67=0 ; gain
diff --git a/cras-config/stout/HDA Intel PCH b/cras-config/stout/HDA Intel PCH
new file mode 100644
index 00000000..884c0060
--- /dev/null
+++ b/cras-config/stout/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -150
+ db_at_95 = -150
+ db_at_94 = -150
+ db_at_93 = -225
+ db_at_92 = -225
+ db_at_91 = -300
+ db_at_90 = -300
+ db_at_89 = -300
+ db_at_88 = -375
+ db_at_87 = -375
+ db_at_86 = -375
+ db_at_85 = -450
+ db_at_84 = -450
+ db_at_83 = -450
+ db_at_82 = -525
+ db_at_81 = -525
+ db_at_80 = -600
+ db_at_79 = -600
+ db_at_78 = -675
+ db_at_77 = -675
+ db_at_76 = -750
+ db_at_75 = -750
+ db_at_74 = -750
+ db_at_73 = -825
+ db_at_72 = -825
+ db_at_71 = -825
+ db_at_70 = -900
+ db_at_69 = -900
+ db_at_68 = -975
+ db_at_67 = -975
+ db_at_66 = -1050
+ db_at_65 = -1050
+ db_at_64 = -1125
+ db_at_63 = -1125
+ db_at_62 = -1125
+ db_at_61 = -1200
+ db_at_60 = -1200
+ db_at_59 = -1200
+ db_at_58 = -1275
+ db_at_57 = -1275
+ db_at_56 = -1350
+ db_at_55 = -1350
+ db_at_54 = -1425
+ db_at_53 = -1425
+ db_at_52 = -1500
+ db_at_51 = -1500
+ db_at_50 = -1500
+ db_at_49 = -1500
+ db_at_48 = -1575
+ db_at_47 = -1575
+ db_at_46 = -1650
+ db_at_45 = -1650
+ db_at_44 = -1725
+ db_at_43 = -1725
+ db_at_42 = -1800
+ db_at_41 = -1800
+ db_at_40 = -1875
+ db_at_39 = -1875
+ db_at_38 = -1950
+ db_at_37 = -2025
+ db_at_36 = -2100
+ db_at_35 = -2175
+ db_at_34 = -2250
+ db_at_33 = -2250
+ db_at_32 = -2325
+ db_at_31 = -2400
+ db_at_30 = -2475
+ db_at_29 = -2475
+ db_at_28 = -2625
+ db_at_27 = -2700
+ db_at_26 = -2850
+ db_at_25 = -2850
+ db_at_24 = -3000
+ db_at_23 = -3075
+ db_at_22 = -3225
+ db_at_21 = -3375
+ db_at_20 = -3450
+ db_at_19 = -3600
+ db_at_18 = -3750
+ db_at_17 = -3825
+ db_at_16 = -3975
+ db_at_15 = -4125
+ db_at_14 = -4200
+ db_at_13 = -4350
+ db_at_12 = -4500
+ db_at_11 = -4575
+ db_at_10 = -4725
+ db_at_9 = -4875
+ db_at_8 = -4950
+ db_at_7 = -5100
+ db_at_6 = -5250
+ db_at_5 = -5325
+ db_at_4 = -5475
+ db_at_3 = -5550
+ db_at_2 = -5850
+ db_at_1 = -6150
+ db_at_0 = -6525
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 65
+ max_volume = 0
diff --git a/cras-config/veryon_jerry-kernelnext b/cras-config/veryon_jerry-kernelnext
new file mode 120000
index 00000000..0462d3a7
--- /dev/null
+++ b/cras-config/veryon_jerry-kernelnext
@@ -0,0 +1 @@
+veyron_jerry \ No newline at end of file
diff --git a/cras-config/veyron_jaq/ROCKCHIP-I2S b/cras-config/veyron_jaq/ROCKCHIP-I2S
new file mode 100644
index 00000000..2b946ca9
--- /dev/null
+++ b/cras-config/veyron_jaq/ROCKCHIP-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -100
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -200
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -200
+ db_at_90 = -200
+ db_at_89 = -200
+ db_at_88 = -300
+ db_at_87 = -300
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -300
+ db_at_81 = -400
+ db_at_80 = -400
+ db_at_79 = -400
+ db_at_78 = -400
+ db_at_77 = -400
+ db_at_76 = -400
+ db_at_75 = -400
+ db_at_74 = -500
+ db_at_73 = -500
+ db_at_72 = -500
+ db_at_71 = -500
+ db_at_70 = -500
+ db_at_69 = -500
+ db_at_68 = -500
+ db_at_67 = -500
+ db_at_66 = -600
+ db_at_65 = -600
+ db_at_64 = -600
+ db_at_63 = -600
+ db_at_62 = -600
+ db_at_61 = -600
+ db_at_60 = -600
+ db_at_59 = -700
+ db_at_58 = -700
+ db_at_57 = -700
+ db_at_56 = -700
+ db_at_55 = -700
+ db_at_54 = -800
+ db_at_53 = -800
+ db_at_52 = -800
+ db_at_51 = -900
+ db_at_50 = -900
+ db_at_49 = -900
+ db_at_48 = -900
+ db_at_47 = -1000
+ db_at_46 = -1000
+ db_at_45 = -1000
+ db_at_44 = -1100
+ db_at_43 = -1100
+ db_at_42 = -1100
+ db_at_41 = -1200
+ db_at_40 = -1200
+ db_at_39 = -1200
+ db_at_38 = -1200
+ db_at_37 = -1300
+ db_at_36 = -1300
+ db_at_35 = -1300
+ db_at_34 = -1400
+ db_at_33 = -1400
+ db_at_32 = -1400
+ db_at_31 = -1500
+ db_at_30 = -1500
+ db_at_29 = -1500
+ db_at_28 = -1500
+ db_at_27 = -1600
+ db_at_26 = -1600
+ db_at_25 = -1600
+ db_at_24 = -1700
+ db_at_23 = -1700
+ db_at_22 = -1700
+ db_at_21 = -1800
+ db_at_20 = -1800
+ db_at_19 = -1800
+ db_at_18 = -1900
+ db_at_17 = -1900
+ db_at_16 = -1900
+ db_at_15 = -1900
+ db_at_14 = -2000
+ db_at_13 = -2000
+ db_at_12 = -2000
+ db_at_11 = -2100
+ db_at_10 = -2100
+ db_at_9 = -2100
+ db_at_8 = -2200
+ db_at_7 = -2200
+ db_at_6 = -2200
+ db_at_5 = -2200
+ db_at_4 = -2300
+ db_at_3 = -2300
+ db_at_2 = -2300
+ db_at_1 = -2400
+ db_at_0 = -2400
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_jaq/VEYRON-I2S b/cras-config/veyron_jaq/VEYRON-I2S
new file mode 100644
index 00000000..2b946ca9
--- /dev/null
+++ b/cras-config/veyron_jaq/VEYRON-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -100
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -200
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -200
+ db_at_90 = -200
+ db_at_89 = -200
+ db_at_88 = -300
+ db_at_87 = -300
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -300
+ db_at_81 = -400
+ db_at_80 = -400
+ db_at_79 = -400
+ db_at_78 = -400
+ db_at_77 = -400
+ db_at_76 = -400
+ db_at_75 = -400
+ db_at_74 = -500
+ db_at_73 = -500
+ db_at_72 = -500
+ db_at_71 = -500
+ db_at_70 = -500
+ db_at_69 = -500
+ db_at_68 = -500
+ db_at_67 = -500
+ db_at_66 = -600
+ db_at_65 = -600
+ db_at_64 = -600
+ db_at_63 = -600
+ db_at_62 = -600
+ db_at_61 = -600
+ db_at_60 = -600
+ db_at_59 = -700
+ db_at_58 = -700
+ db_at_57 = -700
+ db_at_56 = -700
+ db_at_55 = -700
+ db_at_54 = -800
+ db_at_53 = -800
+ db_at_52 = -800
+ db_at_51 = -900
+ db_at_50 = -900
+ db_at_49 = -900
+ db_at_48 = -900
+ db_at_47 = -1000
+ db_at_46 = -1000
+ db_at_45 = -1000
+ db_at_44 = -1100
+ db_at_43 = -1100
+ db_at_42 = -1100
+ db_at_41 = -1200
+ db_at_40 = -1200
+ db_at_39 = -1200
+ db_at_38 = -1200
+ db_at_37 = -1300
+ db_at_36 = -1300
+ db_at_35 = -1300
+ db_at_34 = -1400
+ db_at_33 = -1400
+ db_at_32 = -1400
+ db_at_31 = -1500
+ db_at_30 = -1500
+ db_at_29 = -1500
+ db_at_28 = -1500
+ db_at_27 = -1600
+ db_at_26 = -1600
+ db_at_25 = -1600
+ db_at_24 = -1700
+ db_at_23 = -1700
+ db_at_22 = -1700
+ db_at_21 = -1800
+ db_at_20 = -1800
+ db_at_19 = -1800
+ db_at_18 = -1900
+ db_at_17 = -1900
+ db_at_16 = -1900
+ db_at_15 = -1900
+ db_at_14 = -2000
+ db_at_13 = -2000
+ db_at_12 = -2000
+ db_at_11 = -2100
+ db_at_10 = -2100
+ db_at_9 = -2100
+ db_at_8 = -2200
+ db_at_7 = -2200
+ db_at_6 = -2200
+ db_at_5 = -2200
+ db_at_4 = -2300
+ db_at_3 = -2300
+ db_at_2 = -2300
+ db_at_1 = -2400
+ db_at_0 = -2400
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_jaq/dsp.ini b/cras-config/veyron_jaq/dsp.ini
new file mode 100644
index 00000000..8f7c6282
--- /dev/null
+++ b/cras-config/veyron_jaq/dsp.ini
@@ -0,0 +1,119 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=0 ; boost
+input_13=200 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=30 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=0 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=250 ; freq
+input_6=3 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=250 ; freq
+input_10=3 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=400 ; freq
+input_14=1 ; Q
+input_15=3 ; gain
+input_16=6 ; peaking
+input_17=400 ; freq
+input_18=1 ; Q
+input_19=3 ; gain
+input_20=6 ; peaking
+input_21=630 ; freq
+input_22=1 ; Q
+input_23=1 ; gain
+input_24=6 ; peaking
+input_25=630 ; freq
+input_26=1 ; Q
+input_27=1 ; gain
+input_28=6 ; peaking
+input_29=1500 ; freq
+input_30=1 ; Q
+input_31=-2 ; gain
+input_32=6 ; peaking
+input_33=1500 ; freq
+input_34=1 ; Q
+input_35=-2 ; gain
+input_36=6 ; peaking
+input_37=2200 ; freq
+input_38=1 ; Q
+input_39=1 ; gain
+input_40=6 ; peaking
+input_41=2200 ; freq
+input_42=1 ; Q
+input_43=1 ; gain
+input_44=6 ; peaking
+input_45=3300 ; freq
+input_46=0.7 ; Q
+input_47=-6 ; gain
+input_48=6 ; peaking
+input_49=3300 ; freq
+input_50=0.7 ; Q
+input_51=-6 ; gain
+input_52=6 ; peaking
+input_53=6000 ; freq
+input_54=1 ; Q
+input_55=-3 ; gain
+input_56=6 ; peaking
+input_57=6000 ; freq
+input_58=1 ; Q
+input_59=-3 ; gain
+input_60=5 ; highshelf
+input_61=12000 ; freq
+input_62=1 ; Q
+input_63=1.5 ; gain
+input_64=5 ; highshelf
+input_65=12000 ; freq
+input_66=1 ; Q
+input_67=1.5 ; gain
diff --git a/cras-config/veyron_jerry/ROCKCHIP-I2S b/cras-config/veyron_jerry/ROCKCHIP-I2S
new file mode 100644
index 00000000..d59988f6
--- /dev/null
+++ b/cras-config/veyron_jerry/ROCKCHIP-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -520
+ db_at_98 = -520
+ db_at_97 = -540
+ db_at_96 = -540
+ db_at_95 = -560
+ db_at_94 = -580
+ db_at_93 = -580
+ db_at_92 = -600
+ db_at_91 = -620
+ db_at_90 = -620
+ db_at_89 = -640
+ db_at_88 = -640
+ db_at_87 = -660
+ db_at_86 = -680
+ db_at_85 = -680
+ db_at_84 = -700
+ db_at_83 = -720
+ db_at_82 = -740
+ db_at_81 = -760
+ db_at_80 = -780
+ db_at_79 = -800
+ db_at_78 = -820
+ db_at_77 = -840
+ db_at_76 = -860
+ db_at_75 = -880
+ db_at_74 = -880
+ db_at_73 = -880
+ db_at_72 = -900
+ db_at_71 = -920
+ db_at_70 = -940
+ db_at_69 = -980
+ db_at_68 = -1000
+ db_at_67 = -1020
+ db_at_66 = -1040
+ db_at_65 = -1080
+ db_at_64 = -1100
+ db_at_63 = -1120
+ db_at_62 = -1140
+ db_at_61 = -1180
+ db_at_60 = -1200
+ db_at_59 = -1220
+ db_at_58 = -1240
+ db_at_57 = -1280
+ db_at_56 = -1300
+ db_at_55 = -1320
+ db_at_54 = -1340
+ db_at_53 = -1380
+ db_at_52 = -1400
+ db_at_51 = -1460
+ db_at_50 = -1540
+ db_at_49 = -1600
+ db_at_48 = -1660
+ db_at_47 = -1720
+ db_at_46 = -1800
+ db_at_45 = -1860
+ db_at_44 = -1920
+ db_at_43 = -1980
+ db_at_42 = -2060
+ db_at_41 = -2120
+ db_at_40 = -2180
+ db_at_39 = -2240
+ db_at_38 = -2320
+ db_at_37 = -2380
+ db_at_36 = -2440
+ db_at_35 = -2520
+ db_at_34 = -2580
+ db_at_33 = -2640
+ db_at_32 = -2700
+ db_at_31 = -2780
+ db_at_30 = -2840
+ db_at_29 = -2900
+ db_at_28 = -2960
+ db_at_27 = -3040
+ db_at_26 = -3100
+ db_at_25 = -3160
+ db_at_24 = -3240
+ db_at_23 = -3300
+ db_at_22 = -3360
+ db_at_21 = -3420
+ db_at_20 = -3500
+ db_at_19 = -3560
+ db_at_18 = -3620
+ db_at_17 = -3680
+ db_at_16 = -3760
+ db_at_15 = -3820
+ db_at_14 = -3880
+ db_at_13 = -3940
+ db_at_12 = -4020
+ db_at_11 = -4080
+ db_at_10 = -4140
+ db_at_9 = -4220
+ db_at_8 = -4280
+ db_at_7 = -4340
+ db_at_6 = -4400
+ db_at_5 = -4480
+ db_at_4 = -4540
+ db_at_3 = -4600
+ db_at_2 = -4660
+ db_at_1 = -4740
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_jerry/VEYRON-I2S b/cras-config/veyron_jerry/VEYRON-I2S
new file mode 100644
index 00000000..d59988f6
--- /dev/null
+++ b/cras-config/veyron_jerry/VEYRON-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -520
+ db_at_98 = -520
+ db_at_97 = -540
+ db_at_96 = -540
+ db_at_95 = -560
+ db_at_94 = -580
+ db_at_93 = -580
+ db_at_92 = -600
+ db_at_91 = -620
+ db_at_90 = -620
+ db_at_89 = -640
+ db_at_88 = -640
+ db_at_87 = -660
+ db_at_86 = -680
+ db_at_85 = -680
+ db_at_84 = -700
+ db_at_83 = -720
+ db_at_82 = -740
+ db_at_81 = -760
+ db_at_80 = -780
+ db_at_79 = -800
+ db_at_78 = -820
+ db_at_77 = -840
+ db_at_76 = -860
+ db_at_75 = -880
+ db_at_74 = -880
+ db_at_73 = -880
+ db_at_72 = -900
+ db_at_71 = -920
+ db_at_70 = -940
+ db_at_69 = -980
+ db_at_68 = -1000
+ db_at_67 = -1020
+ db_at_66 = -1040
+ db_at_65 = -1080
+ db_at_64 = -1100
+ db_at_63 = -1120
+ db_at_62 = -1140
+ db_at_61 = -1180
+ db_at_60 = -1200
+ db_at_59 = -1220
+ db_at_58 = -1240
+ db_at_57 = -1280
+ db_at_56 = -1300
+ db_at_55 = -1320
+ db_at_54 = -1340
+ db_at_53 = -1380
+ db_at_52 = -1400
+ db_at_51 = -1460
+ db_at_50 = -1540
+ db_at_49 = -1600
+ db_at_48 = -1660
+ db_at_47 = -1720
+ db_at_46 = -1800
+ db_at_45 = -1860
+ db_at_44 = -1920
+ db_at_43 = -1980
+ db_at_42 = -2060
+ db_at_41 = -2120
+ db_at_40 = -2180
+ db_at_39 = -2240
+ db_at_38 = -2320
+ db_at_37 = -2380
+ db_at_36 = -2440
+ db_at_35 = -2520
+ db_at_34 = -2580
+ db_at_33 = -2640
+ db_at_32 = -2700
+ db_at_31 = -2780
+ db_at_30 = -2840
+ db_at_29 = -2900
+ db_at_28 = -2960
+ db_at_27 = -3040
+ db_at_26 = -3100
+ db_at_25 = -3160
+ db_at_24 = -3240
+ db_at_23 = -3300
+ db_at_22 = -3360
+ db_at_21 = -3420
+ db_at_20 = -3500
+ db_at_19 = -3560
+ db_at_18 = -3620
+ db_at_17 = -3680
+ db_at_16 = -3760
+ db_at_15 = -3820
+ db_at_14 = -3880
+ db_at_13 = -3940
+ db_at_12 = -4020
+ db_at_11 = -4080
+ db_at_10 = -4140
+ db_at_9 = -4220
+ db_at_8 = -4280
+ db_at_7 = -4340
+ db_at_6 = -4400
+ db_at_5 = -4480
+ db_at_4 = -4540
+ db_at_3 = -4600
+ db_at_2 = -4660
+ db_at_1 = -4740
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_jerry/dsp.ini b/cras-config/veyron_jerry/dsp.ini
new file mode 100644
index 00000000..4973a551
--- /dev/null
+++ b/cras-config/veyron_jerry/dsp.ini
@@ -0,0 +1,79 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-30 ; threshold
+input_8=25 ; knee
+input_9=4 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=0 ; boost
+input_13=200 ; f
+input_14=1 ; enable
+input_15=-30 ; threshold
+input_16=25 ; knee
+input_17=4 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=0 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-30 ; threshold
+input_24=25 ; knee
+input_25=4 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=500 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=500 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=350 ; freq
+input_14=4 ; Q
+input_15=-6 ; gain
+input_16=6 ; peaking
+input_17=350 ; freq
+input_18=4 ; Q
+input_19=-6 ; gain
+input_20=6 ; peaking
+input_21=750 ; freq
+input_22=4 ; Q
+input_23=-6 ; gain
+input_24=6 ; peaking
+input_25=750 ; freq
+input_26=4 ; Q
+input_27=-6 ; gain
diff --git a/cras-config/veyron_mighty/ROCKCHIP-I2S b/cras-config/veyron_mighty/ROCKCHIP-I2S
new file mode 100644
index 00000000..2b946ca9
--- /dev/null
+++ b/cras-config/veyron_mighty/ROCKCHIP-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -100
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -200
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -200
+ db_at_90 = -200
+ db_at_89 = -200
+ db_at_88 = -300
+ db_at_87 = -300
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -300
+ db_at_81 = -400
+ db_at_80 = -400
+ db_at_79 = -400
+ db_at_78 = -400
+ db_at_77 = -400
+ db_at_76 = -400
+ db_at_75 = -400
+ db_at_74 = -500
+ db_at_73 = -500
+ db_at_72 = -500
+ db_at_71 = -500
+ db_at_70 = -500
+ db_at_69 = -500
+ db_at_68 = -500
+ db_at_67 = -500
+ db_at_66 = -600
+ db_at_65 = -600
+ db_at_64 = -600
+ db_at_63 = -600
+ db_at_62 = -600
+ db_at_61 = -600
+ db_at_60 = -600
+ db_at_59 = -700
+ db_at_58 = -700
+ db_at_57 = -700
+ db_at_56 = -700
+ db_at_55 = -700
+ db_at_54 = -800
+ db_at_53 = -800
+ db_at_52 = -800
+ db_at_51 = -900
+ db_at_50 = -900
+ db_at_49 = -900
+ db_at_48 = -900
+ db_at_47 = -1000
+ db_at_46 = -1000
+ db_at_45 = -1000
+ db_at_44 = -1100
+ db_at_43 = -1100
+ db_at_42 = -1100
+ db_at_41 = -1200
+ db_at_40 = -1200
+ db_at_39 = -1200
+ db_at_38 = -1200
+ db_at_37 = -1300
+ db_at_36 = -1300
+ db_at_35 = -1300
+ db_at_34 = -1400
+ db_at_33 = -1400
+ db_at_32 = -1400
+ db_at_31 = -1500
+ db_at_30 = -1500
+ db_at_29 = -1500
+ db_at_28 = -1500
+ db_at_27 = -1600
+ db_at_26 = -1600
+ db_at_25 = -1600
+ db_at_24 = -1700
+ db_at_23 = -1700
+ db_at_22 = -1700
+ db_at_21 = -1800
+ db_at_20 = -1800
+ db_at_19 = -1800
+ db_at_18 = -1900
+ db_at_17 = -1900
+ db_at_16 = -1900
+ db_at_15 = -1900
+ db_at_14 = -2000
+ db_at_13 = -2000
+ db_at_12 = -2000
+ db_at_11 = -2100
+ db_at_10 = -2100
+ db_at_9 = -2100
+ db_at_8 = -2200
+ db_at_7 = -2200
+ db_at_6 = -2200
+ db_at_5 = -2200
+ db_at_4 = -2300
+ db_at_3 = -2300
+ db_at_2 = -2300
+ db_at_1 = -2400
+ db_at_0 = -2400
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_mighty/VEYRON-I2S b/cras-config/veyron_mighty/VEYRON-I2S
new file mode 100644
index 00000000..2b946ca9
--- /dev/null
+++ b/cras-config/veyron_mighty/VEYRON-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -100
+ db_at_99 = -100
+ db_at_98 = -100
+ db_at_97 = -100
+ db_at_96 = -200
+ db_at_95 = -200
+ db_at_94 = -200
+ db_at_93 = -200
+ db_at_92 = -200
+ db_at_91 = -200
+ db_at_90 = -200
+ db_at_89 = -200
+ db_at_88 = -300
+ db_at_87 = -300
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -300
+ db_at_81 = -400
+ db_at_80 = -400
+ db_at_79 = -400
+ db_at_78 = -400
+ db_at_77 = -400
+ db_at_76 = -400
+ db_at_75 = -400
+ db_at_74 = -500
+ db_at_73 = -500
+ db_at_72 = -500
+ db_at_71 = -500
+ db_at_70 = -500
+ db_at_69 = -500
+ db_at_68 = -500
+ db_at_67 = -500
+ db_at_66 = -600
+ db_at_65 = -600
+ db_at_64 = -600
+ db_at_63 = -600
+ db_at_62 = -600
+ db_at_61 = -600
+ db_at_60 = -600
+ db_at_59 = -700
+ db_at_58 = -700
+ db_at_57 = -700
+ db_at_56 = -700
+ db_at_55 = -700
+ db_at_54 = -800
+ db_at_53 = -800
+ db_at_52 = -800
+ db_at_51 = -900
+ db_at_50 = -900
+ db_at_49 = -900
+ db_at_48 = -900
+ db_at_47 = -1000
+ db_at_46 = -1000
+ db_at_45 = -1000
+ db_at_44 = -1100
+ db_at_43 = -1100
+ db_at_42 = -1100
+ db_at_41 = -1200
+ db_at_40 = -1200
+ db_at_39 = -1200
+ db_at_38 = -1200
+ db_at_37 = -1300
+ db_at_36 = -1300
+ db_at_35 = -1300
+ db_at_34 = -1400
+ db_at_33 = -1400
+ db_at_32 = -1400
+ db_at_31 = -1500
+ db_at_30 = -1500
+ db_at_29 = -1500
+ db_at_28 = -1500
+ db_at_27 = -1600
+ db_at_26 = -1600
+ db_at_25 = -1600
+ db_at_24 = -1700
+ db_at_23 = -1700
+ db_at_22 = -1700
+ db_at_21 = -1800
+ db_at_20 = -1800
+ db_at_19 = -1800
+ db_at_18 = -1900
+ db_at_17 = -1900
+ db_at_16 = -1900
+ db_at_15 = -1900
+ db_at_14 = -2000
+ db_at_13 = -2000
+ db_at_12 = -2000
+ db_at_11 = -2100
+ db_at_10 = -2100
+ db_at_9 = -2100
+ db_at_8 = -2200
+ db_at_7 = -2200
+ db_at_6 = -2200
+ db_at_5 = -2200
+ db_at_4 = -2300
+ db_at_3 = -2300
+ db_at_2 = -2300
+ db_at_1 = -2400
+ db_at_0 = -2400
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_mighty/dsp.ini b/cras-config/veyron_mighty/dsp.ini
new file mode 100644
index 00000000..94c7ad23
--- /dev/null
+++ b/cras-config/veyron_mighty/dsp.ini
@@ -0,0 +1,119 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=0 ; boost
+input_13=200 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=30 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=0 ; boost
+input_21=2000 ; f
+input_22=1 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=250 ; freq
+input_6=3 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=300 ; freq
+input_10=3 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=500 ; freq
+input_14=1 ; Q
+input_15=4.5 ; gain
+input_16=6 ; peaking
+input_17=500 ; freq
+input_18=1 ; Q
+input_19=4.5 ; gain
+input_20=6 ; peaking
+input_21=800 ; freq
+input_22=3 ; Q
+input_23=-8 ; gain
+input_24=6 ; peaking
+input_25=800 ; freq
+input_26=3 ; Q
+input_27=-8 ; gain
+input_28=6 ; peaking
+input_29=1000 ; freq
+input_30=1 ; Q
+input_31=-2 ; gain
+input_32=6 ; peaking
+input_33=1000 ; freq
+input_34=1 ; Q
+input_35=-2 ; gain
+input_36=6 ; peaking
+input_37=2600 ; freq
+input_38=1 ; Q
+input_39=-2 ; gain
+input_40=6 ; peaking
+input_41=2600 ; freq
+input_42=1 ; Q
+input_43=-2 ; gain
+input_44=6 ; peaking
+input_45=3500 ; freq
+input_46=2.5 ; Q
+input_47=-8 ; gain
+input_48=6 ; peaking
+input_49=3500 ; freq
+input_50=2.5 ; Q
+input_51=-8 ; gain
+input_52=6 ; peaking
+input_53=6000 ; freq
+input_54=1 ; Q
+input_55=-2 ; gain
+input_56=6 ; peaking
+input_57=6000 ; freq
+input_58=1 ; Q
+input_59=-2 ; gain
+input_60=5 ; highshelf
+input_61=8000 ; freq
+input_62=1 ; Q
+input_63=1.5 ; gain
+input_64=5 ; highshelf
+input_65=8000 ; freq
+input_66=1 ; Q
+input_67=1.5 ; gain
diff --git a/cras-config/veyron_minnie-kernelnext b/cras-config/veyron_minnie-kernelnext
new file mode 120000
index 00000000..5fea6bb7
--- /dev/null
+++ b/cras-config/veyron_minnie-kernelnext
@@ -0,0 +1 @@
+veyron_minnie \ No newline at end of file
diff --git a/cras-config/veyron_minnie/ROCKCHIP-I2S b/cras-config/veyron_minnie/ROCKCHIP-I2S
new file mode 100644
index 00000000..297ac51d
--- /dev/null
+++ b/cras-config/veyron_minnie/ROCKCHIP-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -500
+ db_at_98 = -500
+ db_at_97 = -600
+ db_at_96 = -600
+ db_at_95 = -600
+ db_at_94 = -600
+ db_at_93 = -700
+ db_at_92 = -700
+ db_at_91 = -700
+ db_at_90 = -700
+ db_at_89 = -800
+ db_at_88 = -800
+ db_at_87 = -800
+ db_at_86 = -800
+ db_at_85 = -900
+ db_at_84 = -900
+ db_at_83 = -900
+ db_at_82 = -900
+ db_at_81 = -1000
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1100
+ db_at_76 = -1100
+ db_at_75 = -1100
+ db_at_74 = -1100
+ db_at_73 = -1200
+ db_at_72 = -1200
+ db_at_71 = -1200
+ db_at_70 = -1200
+ db_at_69 = -1300
+ db_at_68 = -1300
+ db_at_67 = -1300
+ db_at_66 = -1300
+ db_at_65 = -1400
+ db_at_64 = -1400
+ db_at_63 = -1400
+ db_at_62 = -1400
+ db_at_61 = -1500
+ db_at_60 = -1500
+ db_at_59 = -1500
+ db_at_58 = -1500
+ db_at_57 = -1600
+ db_at_56 = -1600
+ db_at_55 = -1600
+ db_at_54 = -1600
+ db_at_53 = -1700
+ db_at_52 = -1700
+ db_at_51 = -1700
+ db_at_50 = -1700
+ db_at_49 = -1800
+ db_at_48 = -1800
+ db_at_47 = -1800
+ db_at_46 = -1800
+ db_at_45 = -1900
+ db_at_44 = -1900
+ db_at_43 = -1900
+ db_at_42 = -1900
+ db_at_41 = -2000
+ db_at_40 = -2000
+ db_at_39 = -2000
+ db_at_38 = -2100
+ db_at_37 = -2100
+ db_at_36 = -2200
+ db_at_35 = -2200
+ db_at_34 = -2300
+ db_at_33 = -2300
+ db_at_32 = -2400
+ db_at_31 = -2400
+ db_at_30 = -2500
+ db_at_29 = -2500
+ db_at_28 = -2600
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2700
+ db_at_24 = -2800
+ db_at_23 = -2900
+ db_at_22 = -2900
+ db_at_21 = -3000
+ db_at_20 = -3100
+ db_at_19 = -3200
+ db_at_18 = -3200
+ db_at_17 = -3300
+ db_at_16 = -3400
+ db_at_15 = -3500
+ db_at_14 = -3500
+ db_at_13 = -3600
+ db_at_12 = -3700
+ db_at_11 = -3800
+ db_at_10 = -3800
+ db_at_9 = -3900
+ db_at_8 = -4000
+ db_at_7 = -4100
+ db_at_6 = -4100
+ db_at_5 = -4200
+ db_at_4 = -4300
+ db_at_3 = -4400
+ db_at_2 = -4400
+ db_at_1 = -4500
+ db_at_0 = -4600
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_minnie/VEYRON-I2S b/cras-config/veyron_minnie/VEYRON-I2S
new file mode 100644
index 00000000..297ac51d
--- /dev/null
+++ b/cras-config/veyron_minnie/VEYRON-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -500
+ db_at_98 = -500
+ db_at_97 = -600
+ db_at_96 = -600
+ db_at_95 = -600
+ db_at_94 = -600
+ db_at_93 = -700
+ db_at_92 = -700
+ db_at_91 = -700
+ db_at_90 = -700
+ db_at_89 = -800
+ db_at_88 = -800
+ db_at_87 = -800
+ db_at_86 = -800
+ db_at_85 = -900
+ db_at_84 = -900
+ db_at_83 = -900
+ db_at_82 = -900
+ db_at_81 = -1000
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1100
+ db_at_76 = -1100
+ db_at_75 = -1100
+ db_at_74 = -1100
+ db_at_73 = -1200
+ db_at_72 = -1200
+ db_at_71 = -1200
+ db_at_70 = -1200
+ db_at_69 = -1300
+ db_at_68 = -1300
+ db_at_67 = -1300
+ db_at_66 = -1300
+ db_at_65 = -1400
+ db_at_64 = -1400
+ db_at_63 = -1400
+ db_at_62 = -1400
+ db_at_61 = -1500
+ db_at_60 = -1500
+ db_at_59 = -1500
+ db_at_58 = -1500
+ db_at_57 = -1600
+ db_at_56 = -1600
+ db_at_55 = -1600
+ db_at_54 = -1600
+ db_at_53 = -1700
+ db_at_52 = -1700
+ db_at_51 = -1700
+ db_at_50 = -1700
+ db_at_49 = -1800
+ db_at_48 = -1800
+ db_at_47 = -1800
+ db_at_46 = -1800
+ db_at_45 = -1900
+ db_at_44 = -1900
+ db_at_43 = -1900
+ db_at_42 = -1900
+ db_at_41 = -2000
+ db_at_40 = -2000
+ db_at_39 = -2000
+ db_at_38 = -2100
+ db_at_37 = -2100
+ db_at_36 = -2200
+ db_at_35 = -2200
+ db_at_34 = -2300
+ db_at_33 = -2300
+ db_at_32 = -2400
+ db_at_31 = -2400
+ db_at_30 = -2500
+ db_at_29 = -2500
+ db_at_28 = -2600
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2700
+ db_at_24 = -2800
+ db_at_23 = -2900
+ db_at_22 = -2900
+ db_at_21 = -3000
+ db_at_20 = -3100
+ db_at_19 = -3200
+ db_at_18 = -3200
+ db_at_17 = -3300
+ db_at_16 = -3400
+ db_at_15 = -3500
+ db_at_14 = -3500
+ db_at_13 = -3600
+ db_at_12 = -3700
+ db_at_11 = -3800
+ db_at_10 = -3800
+ db_at_9 = -3900
+ db_at_8 = -4000
+ db_at_7 = -4100
+ db_at_6 = -4100
+ db_at_5 = -4200
+ db_at_4 = -4300
+ db_at_3 = -4400
+ db_at_2 = -4400
+ db_at_1 = -4500
+ db_at_0 = -4600
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_minnie/dsp.ini b/cras-config/veyron_minnie/dsp.ini
new file mode 100644
index 00000000..148b098f
--- /dev/null
+++ b/cras-config/veyron_minnie/dsp.ini
@@ -0,0 +1,79 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=0 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=0 ; boost
+input_13=100 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=24 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.5 ; release
+input_20=1 ; boost
+input_21=2000 ; f
+input_22=0 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=200 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=200 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=700 ; freq
+input_14=3 ; Q
+input_15=-12 ; gain
+input_16=6 ; peaking
+input_17=700 ; freq
+input_18=3 ; Q
+input_19=-12 ; gain
+input_20=6 ; peaking
+input_21=930 ; freq
+input_22=3 ; Q
+input_23=-12 ; gain
+input_24=6 ; peaking
+input_25=980 ; freq
+input_26=3 ; Q
+input_27=-12 ; gain
diff --git a/cras-config/veyron_speedy/ROCKCHIP-I2S b/cras-config/veyron_speedy/ROCKCHIP-I2S
new file mode 100644
index 00000000..297ac51d
--- /dev/null
+++ b/cras-config/veyron_speedy/ROCKCHIP-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -500
+ db_at_98 = -500
+ db_at_97 = -600
+ db_at_96 = -600
+ db_at_95 = -600
+ db_at_94 = -600
+ db_at_93 = -700
+ db_at_92 = -700
+ db_at_91 = -700
+ db_at_90 = -700
+ db_at_89 = -800
+ db_at_88 = -800
+ db_at_87 = -800
+ db_at_86 = -800
+ db_at_85 = -900
+ db_at_84 = -900
+ db_at_83 = -900
+ db_at_82 = -900
+ db_at_81 = -1000
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1100
+ db_at_76 = -1100
+ db_at_75 = -1100
+ db_at_74 = -1100
+ db_at_73 = -1200
+ db_at_72 = -1200
+ db_at_71 = -1200
+ db_at_70 = -1200
+ db_at_69 = -1300
+ db_at_68 = -1300
+ db_at_67 = -1300
+ db_at_66 = -1300
+ db_at_65 = -1400
+ db_at_64 = -1400
+ db_at_63 = -1400
+ db_at_62 = -1400
+ db_at_61 = -1500
+ db_at_60 = -1500
+ db_at_59 = -1500
+ db_at_58 = -1500
+ db_at_57 = -1600
+ db_at_56 = -1600
+ db_at_55 = -1600
+ db_at_54 = -1600
+ db_at_53 = -1700
+ db_at_52 = -1700
+ db_at_51 = -1700
+ db_at_50 = -1700
+ db_at_49 = -1800
+ db_at_48 = -1800
+ db_at_47 = -1800
+ db_at_46 = -1800
+ db_at_45 = -1900
+ db_at_44 = -1900
+ db_at_43 = -1900
+ db_at_42 = -1900
+ db_at_41 = -2000
+ db_at_40 = -2000
+ db_at_39 = -2000
+ db_at_38 = -2100
+ db_at_37 = -2100
+ db_at_36 = -2200
+ db_at_35 = -2200
+ db_at_34 = -2300
+ db_at_33 = -2300
+ db_at_32 = -2400
+ db_at_31 = -2400
+ db_at_30 = -2500
+ db_at_29 = -2500
+ db_at_28 = -2600
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2700
+ db_at_24 = -2800
+ db_at_23 = -2900
+ db_at_22 = -2900
+ db_at_21 = -3000
+ db_at_20 = -3100
+ db_at_19 = -3200
+ db_at_18 = -3200
+ db_at_17 = -3300
+ db_at_16 = -3400
+ db_at_15 = -3500
+ db_at_14 = -3500
+ db_at_13 = -3600
+ db_at_12 = -3700
+ db_at_11 = -3800
+ db_at_10 = -3800
+ db_at_9 = -3900
+ db_at_8 = -4000
+ db_at_7 = -4100
+ db_at_6 = -4100
+ db_at_5 = -4200
+ db_at_4 = -4300
+ db_at_3 = -4400
+ db_at_2 = -4400
+ db_at_1 = -4500
+ db_at_0 = -4600
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_speedy/VEYRON-I2S b/cras-config/veyron_speedy/VEYRON-I2S
new file mode 100644
index 00000000..297ac51d
--- /dev/null
+++ b/cras-config/veyron_speedy/VEYRON-I2S
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = -500
+ db_at_99 = -500
+ db_at_98 = -500
+ db_at_97 = -600
+ db_at_96 = -600
+ db_at_95 = -600
+ db_at_94 = -600
+ db_at_93 = -700
+ db_at_92 = -700
+ db_at_91 = -700
+ db_at_90 = -700
+ db_at_89 = -800
+ db_at_88 = -800
+ db_at_87 = -800
+ db_at_86 = -800
+ db_at_85 = -900
+ db_at_84 = -900
+ db_at_83 = -900
+ db_at_82 = -900
+ db_at_81 = -1000
+ db_at_80 = -1000
+ db_at_79 = -1000
+ db_at_78 = -1000
+ db_at_77 = -1100
+ db_at_76 = -1100
+ db_at_75 = -1100
+ db_at_74 = -1100
+ db_at_73 = -1200
+ db_at_72 = -1200
+ db_at_71 = -1200
+ db_at_70 = -1200
+ db_at_69 = -1300
+ db_at_68 = -1300
+ db_at_67 = -1300
+ db_at_66 = -1300
+ db_at_65 = -1400
+ db_at_64 = -1400
+ db_at_63 = -1400
+ db_at_62 = -1400
+ db_at_61 = -1500
+ db_at_60 = -1500
+ db_at_59 = -1500
+ db_at_58 = -1500
+ db_at_57 = -1600
+ db_at_56 = -1600
+ db_at_55 = -1600
+ db_at_54 = -1600
+ db_at_53 = -1700
+ db_at_52 = -1700
+ db_at_51 = -1700
+ db_at_50 = -1700
+ db_at_49 = -1800
+ db_at_48 = -1800
+ db_at_47 = -1800
+ db_at_46 = -1800
+ db_at_45 = -1900
+ db_at_44 = -1900
+ db_at_43 = -1900
+ db_at_42 = -1900
+ db_at_41 = -2000
+ db_at_40 = -2000
+ db_at_39 = -2000
+ db_at_38 = -2100
+ db_at_37 = -2100
+ db_at_36 = -2200
+ db_at_35 = -2200
+ db_at_34 = -2300
+ db_at_33 = -2300
+ db_at_32 = -2400
+ db_at_31 = -2400
+ db_at_30 = -2500
+ db_at_29 = -2500
+ db_at_28 = -2600
+ db_at_27 = -2600
+ db_at_26 = -2700
+ db_at_25 = -2700
+ db_at_24 = -2800
+ db_at_23 = -2900
+ db_at_22 = -2900
+ db_at_21 = -3000
+ db_at_20 = -3100
+ db_at_19 = -3200
+ db_at_18 = -3200
+ db_at_17 = -3300
+ db_at_16 = -3400
+ db_at_15 = -3500
+ db_at_14 = -3500
+ db_at_13 = -3600
+ db_at_12 = -3700
+ db_at_11 = -3800
+ db_at_10 = -3800
+ db_at_9 = -3900
+ db_at_8 = -4000
+ db_at_7 = -4100
+ db_at_6 = -4100
+ db_at_5 = -4200
+ db_at_4 = -4300
+ db_at_3 = -4400
+ db_at_2 = -4400
+ db_at_1 = -4500
+ db_at_0 = -4600
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 70
+ max_volume = 0
diff --git a/cras-config/veyron_speedy/dsp.ini b/cras-config/veyron_speedy/dsp.ini
new file mode 100644
index 00000000..f95096d4
--- /dev/null
+++ b/cras-config/veyron_speedy/dsp.ini
@@ -0,0 +1,79 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=0 ; enable
+input_7=-24 ; threshold
+input_8=30 ; knee
+input_9=12 ; ratio
+input_10=0.003 ; attack
+input_11=0.25 ; release
+input_12=-6 ; boost
+input_13=50 ; f
+input_14=1 ; enable
+input_15=-24 ; threshold
+input_16=30 ; knee
+input_17=12 ; ratio
+input_18=0.003 ; attack
+input_19=0.25 ; release
+input_20=-4.5 ; boost
+input_21=2000 ; f
+input_22=0 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=300 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=300 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=600 ; freq
+input_14=4 ; Q
+input_15=-6 ; gain
+input_16=6 ; peaking
+input_17=600 ; freq
+input_18=4 ; Q
+input_19=-6 ; gain
+input_20=6 ; peaking
+input_21=800 ; freq
+input_22=4 ; Q
+input_23=-6 ; gain
+input_24=6 ; peaking
+input_25=800 ; freq
+input_26=4 ; Q
+input_27=-6 ; gain
diff --git a/cras-config/whirlwind/dsp.ini b/cras-config/whirlwind/dsp.ini
new file mode 100644
index 00000000..9b1badd6
--- /dev/null
+++ b/cras-config/whirlwind/dsp.ini
@@ -0,0 +1,95 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=1 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-35 ; threshold
+input_8=24 ; knee
+input_9=8 ; ratio
+input_10=0.003 ; attack
+input_11=0.3 ; release
+input_12=0 ; boost
+input_13=450 ; f
+input_14=1 ; enable
+input_15=-16 ; threshold
+input_16=10 ; knee
+input_17=6 ; ratio
+input_18=0.003 ; attack
+input_19=0.3 ; release
+input_20=0 ; boost
+input_21=1500 ; f
+input_22=1 ; enable
+input_23=0 ; threshold
+input_24=0 ; knee
+input_25=1 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=150 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=150 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=350 ; freq
+input_14=5 ; Q
+input_15=-6 ; gain
+input_16=6 ; peaking
+input_17=350 ; freq
+input_18=5 ; Q
+input_19=-6 ; gain
+input_20=6 ; peaking
+input_21=700 ; freq
+input_22=2 ; Q
+input_23=-3 ; gain
+input_24=6 ; peaking
+input_25=700 ; freq
+input_26=2 ; Q
+input_27=-3 ; gain
+input_28=6 ; peaking
+input_29=3300 ; freq
+input_30=3 ; Q
+input_31=-4 ; gain
+input_32=6 ; peaking
+input_33=3300 ; freq
+input_34=3 ; Q
+input_35=-4 ; gain
+input_36=5 ; highshelf
+input_37=2000 ; freq
+input_38=1 ; Q
+input_39=2 ; gain
+input_40=5 ; highshelf
+input_41=2000 ; freq
+input_42=1 ; Q
+input_43=2 ; gain
diff --git a/cras-config/wolf/HDA Intel PCH b/cras-config/wolf/HDA Intel PCH
new file mode 100644
index 00000000..e0adc3e9
--- /dev/null
+++ b/cras-config/wolf/HDA Intel PCH
@@ -0,0 +1,107 @@
+[Speaker]
+ volume_curve = explicit
+ db_at_100 = 0
+ db_at_99 = -75
+ db_at_98 = -75
+ db_at_97 = -75
+ db_at_96 = -75
+ db_at_95 = -75
+ db_at_94 = -150
+ db_at_93 = -150
+ db_at_92 = -150
+ db_at_91 = -150
+ db_at_90 = -225
+ db_at_89 = -225
+ db_at_88 = -225
+ db_at_87 = -225
+ db_at_86 = -300
+ db_at_85 = -300
+ db_at_84 = -300
+ db_at_83 = -300
+ db_at_82 = -375
+ db_at_81 = -375
+ db_at_80 = -450
+ db_at_79 = -450
+ db_at_78 = -450
+ db_at_77 = -450
+ db_at_76 = -525
+ db_at_75 = -525
+ db_at_74 = -600
+ db_at_73 = -600
+ db_at_72 = -600
+ db_at_71 = -600
+ db_at_70 = -675
+ db_at_69 = -675
+ db_at_68 = -675
+ db_at_67 = -675
+ db_at_66 = -750
+ db_at_65 = -750
+ db_at_64 = -825
+ db_at_63 = -825
+ db_at_62 = -825
+ db_at_61 = -825
+ db_at_60 = -900
+ db_at_59 = -900
+ db_at_58 = -900
+ db_at_57 = -900
+ db_at_56 = -975
+ db_at_55 = -975
+ db_at_54 = -1050
+ db_at_53 = -1050
+ db_at_52 = -1050
+ db_at_51 = -1050
+ db_at_50 = -1125
+ db_at_49 = -1125
+ db_at_48 = -1200
+ db_at_47 = -1200
+ db_at_46 = -1200
+ db_at_45 = -1200
+ db_at_44 = -1275
+ db_at_43 = -1275
+ db_at_42 = -1275
+ db_at_41 = -1275
+ db_at_40 = -1350
+ db_at_39 = -1425
+ db_at_38 = -1425
+ db_at_37 = -1500
+ db_at_36 = -1500
+ db_at_35 = -1575
+ db_at_34 = -1650
+ db_at_33 = -1650
+ db_at_32 = -1725
+ db_at_31 = -1800
+ db_at_30 = -1800
+ db_at_29 = -1800
+ db_at_28 = -1875
+ db_at_27 = -2025
+ db_at_26 = -2100
+ db_at_25 = -2100
+ db_at_24 = -2175
+ db_at_23 = -2250
+ db_at_22 = -2400
+ db_at_21 = -2475
+ db_at_20 = -2550
+ db_at_19 = -2625
+ db_at_18 = -2700
+ db_at_17 = -2850
+ db_at_16 = -2925
+ db_at_15 = -3000
+ db_at_14 = -3075
+ db_at_13 = -3225
+ db_at_12 = -3300
+ db_at_11 = -3375
+ db_at_10 = -3450
+ db_at_9 = -3600
+ db_at_8 = -3675
+ db_at_7 = -3750
+ db_at_6 = -3825
+ db_at_5 = -3900
+ db_at_4 = -4050
+ db_at_3 = -4050
+ db_at_2 = -4275
+ db_at_1 = -4500
+ db_at_0 = -4800
+[Headphone]
+ volume_curve = simple_step
+ volume_step = 50
+ max_volume = 0
diff --git a/cras-config/wolf/dsp.ini b/cras-config/wolf/dsp.ini
new file mode 100644
index 00000000..6afaf612
--- /dev/null
+++ b/cras-config/wolf/dsp.ini
@@ -0,0 +1,103 @@
+[output_source]
+library=builtin
+label=source
+purpose=playback
+disable=(not (equal? dsp_name "speaker_eq"))
+output_0={src:0}
+output_1={src:1}
+
+[output_sink]
+library=builtin
+label=sink
+purpose=playback
+input_0={dst:0}
+input_1={dst:1}
+
+[drc]
+library=builtin
+label=drc
+input_0={src:0}
+input_1={src:1}
+output_2={intermediate:0}
+output_3={intermediate:1}
+input_4=0 ; emphasis_disabled
+input_5=0 ; f
+input_6=1 ; enable
+input_7=-16 ; threshold
+input_8=11 ; knee
+input_9=4.476 ; ratio
+input_10=0.003 ; attack
+input_11=0.427 ; release
+input_12=3 ; boost
+input_13=2292 ; f
+input_14=1 ; enable
+input_15=-17 ; threshold
+input_16=13 ; knee
+input_17=3.78 ; ratio
+input_18=0.003 ; attack
+input_19=0.421 ; release
+input_20=4 ; boost
+input_21=3000 ; f
+input_22=0 ; enable
+input_23=-24 ; threshold
+input_24=30 ; knee
+input_25=12 ; ratio
+input_26=0.003 ; attack
+input_27=0.25 ; release
+input_28=0 ; boost
+
+[eq2]
+library=builtin
+label=eq2
+input_0={intermediate:0}
+input_1={intermediate:1}
+output_2={dst:0}
+output_3={dst:1}
+input_4=2 ; highpass
+input_5=200 ; freq
+input_6=0 ; Q
+input_7=0 ; gain
+input_8=2 ; highpass
+input_9=200 ; freq
+input_10=0 ; Q
+input_11=0 ; gain
+input_12=6 ; peaking
+input_13=794 ; freq
+input_14=2 ; Q
+input_15=-6.6 ; gain
+input_16=6 ; peaking
+input_17=794 ; freq
+input_18=2 ; Q
+input_19=-6.6 ; gain
+input_20=6 ; peaking
+input_21=1491 ; freq
+input_22=3.8537 ; Q
+input_23=-4.6 ; gain
+input_24=6 ; peaking
+input_25=1491 ; freq
+input_26=3.8537 ; Q
+input_27=-4.6 ; gain
+input_28=6 ; peaking
+input_29=399 ; freq
+input_30=5.2495 ; Q
+input_31=-5.1 ; gain
+input_32=6 ; peaking
+input_33=399 ; freq
+input_34=5.2495 ; Q
+input_35=-5.1 ; gain
+input_36=6 ; peaking
+input_37=2645 ; freq
+input_38=1 ; Q
+input_39=-1.7 ; gain
+input_40=6 ; peaking
+input_41=2645 ; freq
+input_42=1 ; Q
+input_43=-1.7 ; gain
+input_44=6 ; peaking
+input_45=2966 ; freq
+input_46=5.5184 ; Q
+input_47=4.1 ; gain
+input_48=6 ; peaking
+input_49=2966 ; freq
+input_50=5.5184 ; Q
+input_51=4.1 ; gain
diff --git a/cras/Makefile.am b/cras/Makefile.am
index 6c89bdcb..6ecfbaec 100644
--- a/cras/Makefile.am
+++ b/cras/Makefile.am
@@ -5,10 +5,3 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = src
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libcras.pc
-
-compile_commands.json:
- which bear || (echo "Please install 'bear' first." && exit 1)
- bear make check -j$(nproc)
-
-clean-local:
- rm -f compile_commands.json
diff --git a/cras/README.md b/cras/README
index e0ef0ec5..bb7004a9 100644
--- a/cras/README.md
+++ b/cras/README
@@ -1,88 +1,59 @@
CRAS = ChromeOS Audio Server
-===
-
-# Directories
-- [src/server](src/server) - the source for the sound server
-- [src/libcras](src/libcras) - client library for interacting with cras
-- [src/common](src/common) - files common to both the server and library
-- [src/tests](src/tests) - tests for cras and libcras
-- [src/fuzz](src/fuzz) - source code and build scripts for coverage-guided
- fuzzers for CRAS
-
-# Building from source:
-```
-# Generate install-sh
-./git_prepare.sh
-
-# Configure
-CC=clang \
-CXX=clang++ \
-CXXFLAGS="-g -O2 -std=gnu++11 -Wall" \
-CFLAGS="-g -O2 -Wall" \
-./configure --disable-alsa-plugin
-
-# Compile
-make -j$(nproc)
-# Compile with unit tests
-make -j$(nproc) check
+Directories
+src/server - the source for the sound server
+src/libcras - client library for interacting with cras
+src/common - files common to both the server and library
+src/tests - tests for cras and libcras
-# Install binaries to /usr/bin
+Building from source:
+./git_prepare.sh
+./configure
+make
sudo make install
-```
-
-## Code complete for for editors
-You need to install [bear] first and generate [compile commands] for
-[language server plugins in editors] by
-```
-make clean && make compile_commands.json
-```
-Then you'll get `compile_commands.json` for editor.
-Import the JSON file to your editor and you'll get useful code complete
-features for CRAS and its unit tests.
-
-# Configuration:
-## Device Blocklisting:
+---------------------
+Configuration:
+---------------------
-Blocklist of certain USB output device(s) is possible by modifying the config
-file `/etc/cras/device_blocklist`.
+Device Blacklisting:
+--------------------
+Blacklist of certain USB output device(s) is possible by modifying the config
+file /etc/cras/device_blacklist.
The format of this file is as follows:
-```
+
[USB_Outputs]
<vendor_id>_<product_id>_<checksum>_<device_index> = 1
-```
+
Where vendor_id and product id are the USB identifiers for the card to
-blocklist. The checksum is the output of "cksum" command applied to the
+blacklist. The checksum is the output of "cksum" command applied to the
sysfs "descriptors" file of the device. The device index specifies the
-index of the output device in the card to blocklist. This is a bool
+index of the output device in the card to blacklist. This is a bool
parameter, so '= 1' enables the option.
-Example, blocklisting the non-functional output device reported by the C-Media
+Example, blacklisting the non-functional output device reported by the C-Media
based CAD-u1 mic:
-```
+
[USB_Outputs]
0d8c_0008_00000000_0 = 1
-```
-
-## Card Configuration:
+Card Configuration:
+-------------------
There can be a config file for each sound alsa card on the system. This file
-lives in `/etc/cras/`. The file should be named with the card name returned by
+lives in /etc/cras/. The file should be named with the card name returned by
ALSA, the string in the second set of '[]' in the aplay -l output. The ini file
has the following format.
-```
[<output-node-name>] ; Name of the mixer control for this output.
<config-option> = <config-value>
-```
+
output-node-name can be speficied in a few ways to link with the real node:
-- UCM device name - The name string following the SectionDevice label in UCM
+ UCM device name - The name string following the SectionDevice label in UCM
config, i.e. HiFi.conf
-- Jack name - Name of the mixer control for mixer jack, or the gpio jack name
+ Jack name - Name of the mixer control for mixer jack, or the gpio jack name
listed by 'evtest' command.
-- Mixer control name - e.g. "Headphone" or "Speaker", listed by
+ Mixer control name - e.g. "Headphone" or "Speaker", listed by
'amixer scontrols' command.
Note that an output node matches to the output-node-name label in card config by
@@ -91,12 +62,12 @@ search the config file for the UCM device name. When not found, jack name will
be used for searching, and lastly the mixer output control name.
config-option can be the following:
-- volume_curve - The type of volume curve, "simple_step" or "explicit".
-- Options valid and mandatory when volume_curve = simple_step:
- - max_volume - The maximum volume for this output specified in dBFS * 100.
- - volume_step - Number of dB per volume 'tick' specified in dBFS * 100.
-- Options valid and mandatory when volume_curve = explicit:
- - dB_at_N - The value in dB*100 that should be used for the volume at step
+ volume_curve - The type of volume curve, "simple_step" or "explicit".
+ Options valid and mandatory when volume_curve = simple_step:
+ max_volume - The maximum volume for this output specified in dBFS * 100.
+ volume_step - Number of dB per volume 'tick' specified in dBFS * 100.
+ Options valid and mandatory when volume_curve = explicit:
+ dB_at_N - The value in dB*100 that should be used for the volume at step
"N". There must be one of these for each setting from N=0 to 100
inclusive.
@@ -107,7 +78,6 @@ step size of 0.75dBFS and the Speaker to have the curve specified by the steps
given, which is a 1dBFS per step curve from max = +0.5dBFS to min = -99.5dBFS
(volume step 10 is -89.5dBFS).
-```
[Headphone]
volume_curve = simple_step
volume_step = 75
@@ -215,8 +185,3 @@ given, which is a 1dBFS per step curve from max = +0.5dBFS to min = -99.5dBFS
dB_at_98 = -150
dB_at_99 = -50
dB_at_100 = 50
-```
-
-[bear]: https://github.com/rizsotto/Bear
-[compile commands]: https://clang.llvm.org/extra/clangd/Installation.html#compile-commands-json
-[language server plugins in editors]: https://clang.llvm.org/extra/clangd/Installation.html#editor-plugins
diff --git a/cras/README.dbus-api b/cras/README.dbus-api
index f347358e..cac2f031 100644
--- a/cras/README.dbus-api
+++ b/cras/README.dbus-api
@@ -30,12 +30,19 @@ Methods void SetOutputVolume(int32 volume)
Sets the system output mute from user action.
+ void SetInputGain(int32 gain)
+
+ Sets the capture gain of the system. Gain is specified
+ in dBFS * 100. For example 5dB of gain would be
+ specified with an argument of 500, while -10 would be
+ specified with -1000, and 11.5 maps to 1150.
+
void SetInputNodeGain(uint64 node_id, int32 gain)
- Sets the capture gain of the node. gain is a 0-100
- integer which linearly maps [0, 50] to range [-40dB, 0dB]
- and [50, 100] to [0dB, 20dB],
- Default gain value is 50, which is 0dB.
+ Sets the capture gain of the node. Gain is specified
+ in dBFS * 100. For example 5dB of gain would be
+ specified with an argument of 500, while -10 would be
+ specified with -1000, and 11.5 maps to 1150.
void SetInputMute(boolean mute_on)
@@ -105,6 +112,9 @@ Methods void SetOutputVolume(int32 volume)
uint64 PluggedTime
The time that this device was plugged
in. This value is in microseconds.
+ string MicPositions
+ The string formed by floating numbers
+ describing the position of mic array.
unit64 NodeVolume
The node volume indexed from 0 to 100.
unit64 NodeCaptureGain
@@ -151,9 +161,9 @@ Methods void SetOutputVolume(int32 volume)
int32 IsAudioOutputActive()
Returns 1 if there are currently any active output streams,
- excluding 'fake' streams that are not actually outputting any
+ excluding 'dummy' streams that are not actually outputting any
audio. Returns 0 if there are no active streams, or all active
- streams are 'fake' streams.
+ streams are 'dummy' streams.
void SetGlobalOutputChannelRemix(int32 num_channels,
array:double coefficient)
diff --git a/cras/client/cras-sys/.gitignore b/cras/client/cras-sys/.gitignore
index fa8d85ac..5245cb55 100644
--- a/cras/client/cras-sys/.gitignore
+++ b/cras/client/cras-sys/.gitignore
@@ -1,2 +1,2 @@
-Cargo.lock
-target
+target/
+lib_gen.rs
diff --git a/cras/client/cras-sys/Android.bp b/cras/client/cras-sys/Android.bp
index d6482b2e..2a90f8f9 100644
--- a/cras/client/cras-sys/Android.bp
+++ b/cras/client/cras-sys/Android.bp
@@ -1,62 +1,26 @@
-// This file is generated by cargo2android.py --run --device --test --global_defaults=crosvm_defaults --dependencies.
+// This file is generated by cargo2android.py, added defaults.
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_adhd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-BSD
- default_applicable_licenses: ["external_adhd_license"],
-}
-
-rust_defaults {
- name: "cras-sys_defaults",
+rust_test_host {
+ name: "cras-sys_tests_cras_sys",
defaults: ["crosvm_defaults"],
crate_name: "cras_sys",
srcs: ["src/lib.rs"],
+ relative_install_path: "cras-sys_tests",
test_suites: ["general-tests"],
auto_gen_config: true,
edition: "2015",
- rustlibs: [
- "libaudio_streams",
+ rlibs: [
"libdata_model",
],
}
-rust_test_host {
- name: "cras-sys_host_test_src_lib",
- defaults: ["cras-sys_defaults"],
-}
-
-rust_test {
- name: "cras-sys_device_test_src_lib",
- defaults: ["cras-sys_defaults"],
-}
-
-rust_library {
+rust_library_host_rlib {
name: "libcras_sys",
defaults: ["crosvm_defaults"],
- host_supported: true,
crate_name: "cras_sys",
srcs: ["src/lib.rs"],
edition: "2015",
- rustlibs: [
- "libaudio_streams",
+ rlibs: [
"libdata_model",
],
}
-
-// dependent_library ["feature_list"]
-// ../../../../crosvm/assertions/src/lib.rs
-// ../../../../crosvm/data_model/src/lib.rs
-// ../../../../crosvm/sync/src/lib.rs
-// ../../../../crosvm/sys_util/poll_token_derive/poll_token_derive.rs
-// ../../../../crosvm/sys_util/src/lib.rs
-// ../../../../crosvm/syscall_defines/src/lib.rs
-// ../../../../crosvm/tempfile/src/lib.rs
-// ../../../audio_streams/src/audio_streams.rs
-// libc-0.2.76 "default,std"
-// proc-macro2-1.0.19 "default,proc-macro"
-// quote-1.0.7 "default,proc-macro"
-// syn-1.0.39 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
-// unicode-xid-0.2.1 "default"
diff --git a/cras/client/cras-sys/Cargo.toml b/cras/client/cras-sys/Cargo.toml
index 1ac1857a..f71e5408 100644
--- a/cras/client/cras-sys/Cargo.toml
+++ b/cras/client/cras-sys/Cargo.toml
@@ -4,5 +4,4 @@ version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
-audio_streams = { path = "../../../audio_streams" } # provided by ebuild
-data_model = { path = "../../../../crosvm/data_model" } # provided by ebuild
+data_model = { path = "../../../../../platform/crosvm/data_model" } # provided by ebuild
diff --git a/cras/client/cras-sys/generator/src/main.rs b/cras/client/cras-sys/generator/src/main.rs
index e562691d..7b47f025 100644
--- a/cras/client/cras-sys/generator/src/main.rs
+++ b/cras/client/cras-sys/generator/src/main.rs
@@ -36,7 +36,6 @@ fn copy_headers(src_dir: &Path, dst_dir: &Path) -> Result<(), String> {
"cras_shm.h",
"cras_types.h",
"cras_util.h",
- "packet_status_logger.h",
];
for header in &header_files {
@@ -111,10 +110,8 @@ fn gen() -> String {
.whitelist_type("CRAS_.*")
.whitelist_var("CRAS_.*")
.whitelist_type("audio_message")
- .whitelist_var("MAX_DEBUG_.*")
.rustified_enum("CRAS_.*")
.rustified_enum("_snd_pcm_.*")
- .bitfield_enum("CRAS_STREAM_EFFECT")
.generate()
.expect(format!("Unable to generate {} code", name).as_str());
@@ -134,11 +131,7 @@ fn write_output(output_path: &Path, output: String) -> std::io::Result<()> {
* cras_shm.h
* cras_types.h
* cras_util.h
- * packet_status_logger.h
*/
-
-#![allow(clippy::unreadable_literal)]
-#![allow(clippy::cognitive_complexity)]
";
let mut output_file = File::create(output_path)?;
diff --git a/cras/client/cras-sys/src/gen.rs b/cras/client/cras-sys/src/gen.rs
index 6fb4cdf8..59d146a6 100644
--- a/cras/client/cras-sys/src/gen.rs
+++ b/cras/client/cras-sys/src/gen.rs
@@ -10,11 +10,7 @@
* cras_shm.h
* cras_types.h
* cras_util.h
- * packet_status_logger.h
*/
-
-#![allow(clippy::unreadable_literal)]
-#![allow(clippy::cognitive_complexity)]
/* automatically generated by rust-bindgen */
pub const CRAS_IODEV_NAME_BUFFER_SIZE: u32 = 64;
@@ -27,15 +23,13 @@ pub const CRAS_MAX_IONODES: u32 = 20;
pub const CRAS_MAX_ATTACHED_CLIENTS: u32 = 20;
pub const CRAS_MAX_AUDIO_THREAD_SNAPSHOTS: u32 = 10;
pub const CRAS_MAX_HOTWORD_MODEL_NAME_SIZE: u32 = 12;
-pub const MAX_DEBUG_DEVS: u32 = 4;
-pub const MAX_DEBUG_STREAMS: u32 = 8;
pub const CRAS_BT_EVENT_LOG_SIZE: u32 = 1024;
pub const CRAS_SERVER_STATE_VERSION: u32 = 2;
-pub const CRAS_PROTO_VER: u32 = 7;
+pub const CRAS_PROTO_VER: u32 = 5;
pub const CRAS_SERV_MAX_MSG_SIZE: u32 = 256;
pub const CRAS_CLIENT_MAX_MSG_SIZE: u32 = 256;
-pub const CRAS_MAX_HOTWORD_MODELS: u32 = 243;
-pub const CRAS_MAX_REMIX_CHANNELS: u32 = 8;
+pub const CRAS_MAX_HOTWORD_MODELS: u32 = 244;
+pub const CRAS_MAX_REMIX_CHANNELS: u32 = 32;
pub const CRAS_MAX_TEST_DATA_LEN: u32 = 224;
pub const CRAS_AEC_DUMP_FILE_NAME_LEN: u32 = 128;
pub const CRAS_NUM_SHM_BUFFERS: u32 = 2;
@@ -54,7 +48,7 @@ pub struct cras_iodev_info {
pub idx: u32,
pub name: [::std::os::raw::c_char; 64usize],
pub stable_id: u32,
- pub max_supported_channels: u32,
+ pub stable_id_new: u32,
}
#[test]
fn bindgen_test_layout_cras_iodev_info() {
@@ -99,15 +93,13 @@ fn bindgen_test_layout_cras_iodev_info() {
)
);
assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_iodev_info>())).max_supported_channels as *const _ as usize
- },
+ unsafe { &(*(::std::ptr::null::<cras_iodev_info>())).stable_id_new as *const _ as usize },
72usize,
concat!(
"Offset of field: ",
stringify!(cras_iodev_info),
"::",
- stringify!(max_supported_channels)
+ stringify!(stable_id_new)
)
);
}
@@ -121,10 +113,11 @@ pub struct cras_ionode_info {
pub plugged_time: cras_ionode_info__bindgen_ty_1,
pub volume: u32,
pub capture_gain: i32,
- pub ui_gain_scaler: f32,
pub left_right_swapped: i32,
pub type_enum: u32,
pub stable_id: u32,
+ pub stable_id_new: u32,
+ pub mic_positions: [::std::os::raw::c_char; 128usize],
pub type_: [::std::os::raw::c_char; 32usize],
pub name: [::std::os::raw::c_char; 64usize],
pub active_hotword_model: [::std::os::raw::c_char; 16usize],
@@ -176,7 +169,7 @@ fn bindgen_test_layout_cras_ionode_info__bindgen_ty_1() {
fn bindgen_test_layout_cras_ionode_info() {
assert_eq!(
::std::mem::size_of::<cras_ionode_info>(),
- 168usize,
+ 296usize,
concat!("Size of: ", stringify!(cras_ionode_info))
);
assert_eq!(
@@ -255,60 +248,70 @@ fn bindgen_test_layout_cras_ionode_info() {
)
);
assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).ui_gain_scaler as *const _ as usize },
+ unsafe {
+ &(*(::std::ptr::null::<cras_ionode_info>())).left_right_swapped as *const _ as usize
+ },
40usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
"::",
- stringify!(ui_gain_scaler)
+ stringify!(left_right_swapped)
)
);
assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_ionode_info>())).left_right_swapped as *const _ as usize
- },
+ unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_enum as *const _ as usize },
44usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
"::",
- stringify!(left_right_swapped)
+ stringify!(type_enum)
)
);
assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_enum as *const _ as usize },
+ unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).stable_id as *const _ as usize },
48usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
"::",
- stringify!(type_enum)
+ stringify!(stable_id)
)
);
assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).stable_id as *const _ as usize },
+ unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).stable_id_new as *const _ as usize },
52usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
"::",
- stringify!(stable_id)
+ stringify!(stable_id_new)
)
);
assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_ as *const _ as usize },
+ unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).mic_positions as *const _ as usize },
56usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
"::",
+ stringify!(mic_positions)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).type_ as *const _ as usize },
+ 184usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_ionode_info),
+ "::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_ionode_info>())).name as *const _ as usize },
- 88usize,
+ 216usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
@@ -320,7 +323,7 @@ fn bindgen_test_layout_cras_ionode_info() {
unsafe {
&(*(::std::ptr::null::<cras_ionode_info>())).active_hotword_model as *const _ as usize
},
- 152usize,
+ 280usize,
concat!(
"Offset of field: ",
stringify!(cras_ionode_info),
@@ -613,78 +616,6 @@ fn bindgen_test_layout_cras_audio_format_packed() {
)
);
}
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct packet_status_logger {
- pub data: [u8; 64usize],
- pub size: ::std::os::raw::c_int,
- pub wp: ::std::os::raw::c_int,
- pub num_wraps: ::std::os::raw::c_int,
- pub ts: timespec,
-}
-#[test]
-fn bindgen_test_layout_packet_status_logger() {
- assert_eq!(
- ::std::mem::size_of::<packet_status_logger>(),
- 96usize,
- concat!("Size of: ", stringify!(packet_status_logger))
- );
- assert_eq!(
- ::std::mem::align_of::<packet_status_logger>(),
- 8usize,
- concat!("Alignment of ", stringify!(packet_status_logger))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<packet_status_logger>())).data as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(packet_status_logger),
- "::",
- stringify!(data)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<packet_status_logger>())).size as *const _ as usize },
- 64usize,
- concat!(
- "Offset of field: ",
- stringify!(packet_status_logger),
- "::",
- stringify!(size)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<packet_status_logger>())).wp as *const _ as usize },
- 68usize,
- concat!(
- "Offset of field: ",
- stringify!(packet_status_logger),
- "::",
- stringify!(wp)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<packet_status_logger>())).num_wraps as *const _ as usize },
- 72usize,
- concat!(
- "Offset of field: ",
- stringify!(packet_status_logger),
- "::",
- stringify!(num_wraps)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<packet_status_logger>())).ts as *const _ as usize },
- 80usize,
- concat!(
- "Offset of field: ",
- stringify!(packet_status_logger),
- "::",
- stringify!(ts)
- )
- );
-}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct cras_timespec {
@@ -742,18 +673,6 @@ pub enum CRAS_TEST_IODEV_CMD {
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub enum CRAS_CONNECTION_TYPE {
- CRAS_CONTROL = 0,
- CRAS_PLAYBACK = 1,
- CRAS_CAPTURE = 2,
- CRAS_VMS_LEGACY = 3,
- CRAS_VMS_UNIFIED = 4,
- CRAS_PLUGIN_PLAYBACK = 5,
- CRAS_PLUGIN_UNIFIED = 6,
- CRAS_NUM_CONN_TYPE = 7,
-}
-#[repr(u32)]
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CRAS_STREAM_DIRECTION {
CRAS_STREAM_OUTPUT = 0,
CRAS_STREAM_INPUT = 1,
@@ -798,53 +717,15 @@ pub enum CRAS_CLIENT_TYPE {
CRAS_CLIENT_TYPE_CHROME = 4,
CRAS_CLIENT_TYPE_ARC = 5,
CRAS_CLIENT_TYPE_CROSVM = 6,
- CRAS_CLIENT_TYPE_SERVER_STREAM = 7,
- CRAS_CLIENT_TYPE_LACROS = 8,
- CRAS_CLIENT_TYPE_PLUGIN = 9,
- CRAS_CLIENT_TYPE_ARCVM = 10,
- CRAS_NUM_CLIENT_TYPE = 11,
-}
-impl CRAS_STREAM_EFFECT {
- pub const APM_ECHO_CANCELLATION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(1);
-}
-impl CRAS_STREAM_EFFECT {
- pub const APM_NOISE_SUPRESSION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(2);
-}
-impl CRAS_STREAM_EFFECT {
- pub const APM_GAIN_CONTROL: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(4);
-}
-impl CRAS_STREAM_EFFECT {
- pub const APM_VOICE_DETECTION: CRAS_STREAM_EFFECT = CRAS_STREAM_EFFECT(8);
-}
-impl ::std::ops::BitOr<CRAS_STREAM_EFFECT> for CRAS_STREAM_EFFECT {
- type Output = Self;
- #[inline]
- fn bitor(self, other: Self) -> Self {
- CRAS_STREAM_EFFECT(self.0 | other.0)
- }
-}
-impl ::std::ops::BitOrAssign for CRAS_STREAM_EFFECT {
- #[inline]
- fn bitor_assign(&mut self, rhs: CRAS_STREAM_EFFECT) {
- self.0 |= rhs.0;
- }
-}
-impl ::std::ops::BitAnd<CRAS_STREAM_EFFECT> for CRAS_STREAM_EFFECT {
- type Output = Self;
- #[inline]
- fn bitand(self, other: Self) -> Self {
- CRAS_STREAM_EFFECT(self.0 & other.0)
- }
-}
-impl ::std::ops::BitAndAssign for CRAS_STREAM_EFFECT {
- #[inline]
- fn bitand_assign(&mut self, rhs: CRAS_STREAM_EFFECT) {
- self.0 &= rhs.0;
- }
}
-#[repr(C)]
+#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct CRAS_STREAM_EFFECT(pub u32);
+pub enum CRAS_STREAM_EFFECT {
+ APM_ECHO_CANCELLATION = 1,
+ APM_NOISE_SUPRESSION = 2,
+ APM_GAIN_CONTROL = 4,
+ APM_VOICE_DETECTION = 8,
+}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
pub struct cras_attached_client_info {
@@ -919,25 +800,19 @@ pub enum CRAS_BT_LOG_EVENTS {
BT_A2DP_START = 6,
BT_A2DP_SUSPENDED = 7,
BT_CODEC_SELECTION = 8,
- BT_DEV_CONNECTED = 9,
- BT_DEV_DISCONNECTED = 10,
- BT_DEV_CONN_WATCH_CB = 11,
- BT_DEV_SUSPEND_CB = 12,
- BT_HFP_NEW_CONNECTION = 13,
- BT_HFP_REQUEST_DISCONNECT = 14,
- BT_HFP_SUPPORTED_FEATURES = 15,
- BT_HFP_HF_INDICATOR = 16,
- BT_HFP_SET_SPEAKER_GAIN = 17,
- BT_HFP_UPDATE_SPEAKER_GAIN = 18,
- BT_HSP_NEW_CONNECTION = 19,
- BT_HSP_REQUEST_DISCONNECT = 20,
- BT_NEW_AUDIO_PROFILE_AFTER_CONNECT = 21,
- BT_RESET = 22,
- BT_SCO_CONNECT = 23,
- BT_TRANSPORT_ACQUIRE = 24,
- BT_TRANSPORT_RELEASE = 25,
- BT_TRANSPORT_SET_VOLUME = 26,
- BT_TRANSPORT_UPDATE_VOLUME = 27,
+ BT_DEV_CONNECTED_CHANGE = 9,
+ BT_DEV_CONN_WATCH_CB = 10,
+ BT_DEV_SUSPEND_CB = 11,
+ BT_HFP_NEW_CONNECTION = 12,
+ BT_HFP_REQUEST_DISCONNECT = 13,
+ BT_HFP_SUPPORTED_FEATURES = 14,
+ BT_HSP_NEW_CONNECTION = 15,
+ BT_HSP_REQUEST_DISCONNECT = 16,
+ BT_NEW_AUDIO_PROFILE_AFTER_CONNECT = 17,
+ BT_RESET = 18,
+ BT_SCO_CONNECT = 19,
+ BT_TRANSPORT_ACQUIRE = 20,
+ BT_TRANSPORT_RELEASE = 21,
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
@@ -1014,8 +889,7 @@ fn bindgen_test_layout_audio_thread_event() {
#[repr(C, packed)]
#[derive(Copy, Clone)]
pub struct audio_thread_event_log {
- pub write_pos: u64,
- pub sync_write_pos: u64,
+ pub write_pos: u32,
pub len: u32,
pub log: [audio_thread_event; 6144usize],
}
@@ -1023,7 +897,7 @@ pub struct audio_thread_event_log {
fn bindgen_test_layout_audio_thread_event_log() {
assert_eq!(
::std::mem::size_of::<audio_thread_event_log>(),
- 122900usize,
+ 122888usize,
concat!("Size of: ", stringify!(audio_thread_event_log))
);
assert_eq!(
@@ -1044,20 +918,8 @@ fn bindgen_test_layout_audio_thread_event_log() {
)
);
assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<audio_thread_event_log>())).sync_write_pos as *const _ as usize
- },
- 8usize,
- concat!(
- "Offset of field: ",
- stringify!(audio_thread_event_log),
- "::",
- stringify!(sync_write_pos)
- )
- );
- assert_eq!(
unsafe { &(*(::std::ptr::null::<audio_thread_event_log>())).len as *const _ as usize },
- 16usize,
+ 4usize,
concat!(
"Offset of field: ",
stringify!(audio_thread_event_log),
@@ -1067,7 +929,7 @@ fn bindgen_test_layout_audio_thread_event_log() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<audio_thread_event_log>())).log as *const _ as usize },
- 20usize,
+ 8usize,
concat!(
"Offset of field: ",
stringify!(audio_thread_event_log),
@@ -1093,15 +955,13 @@ pub struct audio_dev_debug_info {
pub highest_hw_level: u32,
pub runtime_sec: u32,
pub runtime_nsec: u32,
- pub longest_wake_sec: u32,
- pub longest_wake_nsec: u32,
pub software_gain_scaler: f64,
}
#[test]
fn bindgen_test_layout_audio_dev_debug_info() {
assert_eq!(
::std::mem::size_of::<audio_dev_debug_info>(),
- 133usize,
+ 125usize,
concat!("Size of: ", stringify!(audio_dev_debug_info))
);
assert_eq!(
@@ -1274,34 +1134,10 @@ fn bindgen_test_layout_audio_dev_debug_info() {
);
assert_eq!(
unsafe {
- &(*(::std::ptr::null::<audio_dev_debug_info>())).longest_wake_sec as *const _ as usize
- },
- 117usize,
- concat!(
- "Offset of field: ",
- stringify!(audio_dev_debug_info),
- "::",
- stringify!(longest_wake_sec)
- )
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<audio_dev_debug_info>())).longest_wake_nsec as *const _ as usize
- },
- 121usize,
- concat!(
- "Offset of field: ",
- stringify!(audio_dev_debug_info),
- "::",
- stringify!(longest_wake_nsec)
- )
- );
- assert_eq!(
- unsafe {
&(*(::std::ptr::null::<audio_dev_debug_info>())).software_gain_scaler as *const _
as usize
},
- 125usize,
+ 117usize,
concat!(
"Offset of field: ",
stringify!(audio_dev_debug_info),
@@ -1609,7 +1445,7 @@ pub struct audio_debug_info {
fn bindgen_test_layout_audio_debug_info() {
assert_eq!(
::std::mem::size_of::<audio_debug_info>(),
- 124264usize,
+ 124220usize,
concat!("Size of: ", stringify!(audio_debug_info))
);
assert_eq!(
@@ -1649,7 +1485,7 @@ fn bindgen_test_layout_audio_debug_info() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<audio_debug_info>())).streams as *const _ as usize },
- 540usize,
+ 508usize,
concat!(
"Offset of field: ",
stringify!(audio_debug_info),
@@ -1659,7 +1495,7 @@ fn bindgen_test_layout_audio_debug_info() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<audio_debug_info>())).log as *const _ as usize },
- 1364usize,
+ 1332usize,
concat!(
"Offset of field: ",
stringify!(audio_debug_info),
@@ -1670,156 +1506,6 @@ fn bindgen_test_layout_audio_debug_info() {
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
-pub struct main_thread_event {
- pub tag_sec: u32,
- pub nsec: u32,
- pub data1: u32,
- pub data2: u32,
- pub data3: u32,
-}
-#[test]
-fn bindgen_test_layout_main_thread_event() {
- assert_eq!(
- ::std::mem::size_of::<main_thread_event>(),
- 20usize,
- concat!("Size of: ", stringify!(main_thread_event))
- );
- assert_eq!(
- ::std::mem::align_of::<main_thread_event>(),
- 1usize,
- concat!("Alignment of ", stringify!(main_thread_event))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event>())).tag_sec as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event),
- "::",
- stringify!(tag_sec)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event>())).nsec as *const _ as usize },
- 4usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event),
- "::",
- stringify!(nsec)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event>())).data1 as *const _ as usize },
- 8usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event),
- "::",
- stringify!(data1)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event>())).data2 as *const _ as usize },
- 12usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event),
- "::",
- stringify!(data2)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event>())).data3 as *const _ as usize },
- 16usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event),
- "::",
- stringify!(data3)
- )
- );
-}
-#[repr(C, packed)]
-#[derive(Copy, Clone)]
-pub struct main_thread_event_log {
- pub write_pos: u32,
- pub len: u32,
- pub log: [main_thread_event; 1024usize],
-}
-#[test]
-fn bindgen_test_layout_main_thread_event_log() {
- assert_eq!(
- ::std::mem::size_of::<main_thread_event_log>(),
- 20488usize,
- concat!("Size of: ", stringify!(main_thread_event_log))
- );
- assert_eq!(
- ::std::mem::align_of::<main_thread_event_log>(),
- 1usize,
- concat!("Alignment of ", stringify!(main_thread_event_log))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).write_pos as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event_log),
- "::",
- stringify!(write_pos)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).len as *const _ as usize },
- 4usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event_log),
- "::",
- stringify!(len)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_event_log>())).log as *const _ as usize },
- 8usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_event_log),
- "::",
- stringify!(log)
- )
- );
-}
-#[repr(C, packed)]
-#[derive(Copy, Clone)]
-pub struct main_thread_debug_info {
- pub main_log: main_thread_event_log,
-}
-#[test]
-fn bindgen_test_layout_main_thread_debug_info() {
- assert_eq!(
- ::std::mem::size_of::<main_thread_debug_info>(),
- 20488usize,
- concat!("Size of: ", stringify!(main_thread_debug_info))
- );
- assert_eq!(
- ::std::mem::align_of::<main_thread_debug_info>(),
- 1usize,
- concat!("Alignment of ", stringify!(main_thread_debug_info))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<main_thread_debug_info>())).main_log as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(main_thread_debug_info),
- "::",
- stringify!(main_log)
- )
- );
-}
-#[repr(C, packed)]
-#[derive(Debug, Copy, Clone)]
pub struct cras_bt_event {
pub tag_sec: u32,
pub nsec: u32,
@@ -1933,13 +1619,12 @@ fn bindgen_test_layout_cras_bt_event_log() {
#[derive(Copy, Clone)]
pub struct cras_bt_debug_info {
pub bt_log: cras_bt_event_log,
- pub wbs_logger: packet_status_logger,
}
#[test]
fn bindgen_test_layout_cras_bt_debug_info() {
assert_eq!(
::std::mem::size_of::<cras_bt_debug_info>(),
- 16488usize,
+ 16392usize,
concat!("Size of: ", stringify!(cras_bt_debug_info))
);
assert_eq!(
@@ -1957,29 +1642,15 @@ fn bindgen_test_layout_cras_bt_debug_info() {
stringify!(bt_log)
)
);
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_bt_debug_info>())).wbs_logger as *const _ as usize },
- 16392usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_bt_debug_info),
- "::",
- stringify!(wbs_logger)
- )
- );
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum CRAS_AUDIO_THREAD_EVENT_TYPE {
- AUDIO_THREAD_EVENT_A2DP_OVERRUN = 0,
- AUDIO_THREAD_EVENT_A2DP_THROTTLE = 1,
- AUDIO_THREAD_EVENT_BUSYLOOP = 2,
- AUDIO_THREAD_EVENT_DEBUG = 3,
- AUDIO_THREAD_EVENT_SEVERE_UNDERRUN = 4,
- AUDIO_THREAD_EVENT_UNDERRUN = 5,
- AUDIO_THREAD_EVENT_DROP_SAMPLES = 6,
- AUDIO_THREAD_EVENT_DEV_OVERRUN = 7,
- AUDIO_THREAD_EVENT_TYPE_COUNT = 8,
+ AUDIO_THREAD_EVENT_BUSYLOOP = 0,
+ AUDIO_THREAD_EVENT_DEBUG = 1,
+ AUDIO_THREAD_EVENT_SEVERE_UNDERRUN = 2,
+ AUDIO_THREAD_EVENT_UNDERRUN = 3,
+ AUDIO_THREAD_EVENT_TYPE_COUNT = 4,
}
#[repr(C, packed)]
#[derive(Copy, Clone)]
@@ -1992,7 +1663,7 @@ pub struct cras_audio_thread_snapshot {
fn bindgen_test_layout_cras_audio_thread_snapshot() {
assert_eq!(
::std::mem::size_of::<cras_audio_thread_snapshot>(),
- 124284usize,
+ 124240usize,
concat!("Size of: ", stringify!(cras_audio_thread_snapshot))
);
assert_eq!(
@@ -2048,7 +1719,7 @@ pub struct cras_audio_thread_snapshot_buffer {
fn bindgen_test_layout_cras_audio_thread_snapshot_buffer() {
assert_eq!(
::std::mem::size_of::<cras_audio_thread_snapshot_buffer>(),
- 1242844usize,
+ 1242404usize,
concat!("Size of: ", stringify!(cras_audio_thread_snapshot_buffer))
);
assert_eq!(
@@ -2076,7 +1747,7 @@ fn bindgen_test_layout_cras_audio_thread_snapshot_buffer() {
unsafe {
&(*(::std::ptr::null::<cras_audio_thread_snapshot_buffer>())).pos as *const _ as usize
},
- 1242840usize,
+ 1242400usize,
concat!(
"Offset of field: ",
stringify!(cras_audio_thread_snapshot_buffer),
@@ -2097,8 +1768,11 @@ pub struct cras_server_state {
pub mute_locked: i32,
pub suspended: i32,
pub capture_gain: i32,
+ pub capture_gain_target: i32,
pub capture_mute: i32,
pub capture_mute_locked: i32,
+ pub min_capture_gain: i32,
+ pub max_capture_gain: i32,
pub num_streams_attached: u32,
pub num_output_devs: u32,
pub num_input_devs: u32,
@@ -2121,17 +1795,12 @@ pub struct cras_server_state {
pub snapshot_buffer: cras_audio_thread_snapshot_buffer,
pub bt_debug_info: cras_bt_debug_info,
pub bt_wbs_enabled: i32,
- pub deprioritize_bt_wbs_mic: i32,
- pub main_thread_debug_info: main_thread_debug_info,
- pub num_input_streams_with_permission: [u32; 11usize],
- pub noise_cancellation_enabled: i32,
- pub hotword_pause_at_suspend: i32,
}
#[test]
fn bindgen_test_layout_cras_server_state() {
assert_eq!(
::std::mem::size_of::<cras_server_state>(),
- 1414344usize,
+ 1398352usize,
concat!("Size of: ", stringify!(cras_server_state))
);
assert_eq!(
@@ -2234,12 +1903,24 @@ fn bindgen_test_layout_cras_server_state() {
)
);
assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_server_state>())).capture_mute as *const _ as usize },
+ unsafe {
+ &(*(::std::ptr::null::<cras_server_state>())).capture_gain_target as *const _ as usize
+ },
36usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
"::",
+ stringify!(capture_gain_target)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<cras_server_state>())).capture_mute as *const _ as usize },
+ 40usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_server_state),
+ "::",
stringify!(capture_mute)
)
);
@@ -2247,7 +1928,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).capture_mute_locked as *const _ as usize
},
- 40usize,
+ 44usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2257,9 +1938,33 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe {
+ &(*(::std::ptr::null::<cras_server_state>())).min_capture_gain as *const _ as usize
+ },
+ 48usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_server_state),
+ "::",
+ stringify!(min_capture_gain)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_server_state>())).max_capture_gain as *const _ as usize
+ },
+ 52usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_server_state),
+ "::",
+ stringify!(max_capture_gain)
+ )
+ );
+ assert_eq!(
+ unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_streams_attached as *const _ as usize
},
- 44usize,
+ 56usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2271,7 +1976,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_output_devs as *const _ as usize
},
- 48usize,
+ 60usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2283,7 +1988,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_input_devs as *const _ as usize
},
- 52usize,
+ 64usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2293,7 +1998,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).output_devs as *const _ as usize },
- 56usize,
+ 68usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2303,7 +2008,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).input_devs as *const _ as usize },
- 1576usize,
+ 1588usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2315,7 +2020,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_output_nodes as *const _ as usize
},
- 3096usize,
+ 3108usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2327,7 +2032,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_input_nodes as *const _ as usize
},
- 3100usize,
+ 3112usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2337,7 +2042,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).output_nodes as *const _ as usize },
- 3104usize,
+ 3116usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2347,7 +2052,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).input_nodes as *const _ as usize },
- 6464usize,
+ 9036usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2359,7 +2064,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_attached_clients as *const _ as usize
},
- 9824usize,
+ 14956usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2369,7 +2074,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).client_info as *const _ as usize },
- 9828usize,
+ 14960usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2379,7 +2084,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).update_count as *const _ as usize },
- 10148usize,
+ 15280usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2391,7 +2096,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).num_active_streams as *const _ as usize
},
- 10152usize,
+ 15284usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2404,7 +2109,7 @@ fn bindgen_test_layout_cras_server_state() {
&(*(::std::ptr::null::<cras_server_state>())).last_active_stream_time as *const _
as usize
},
- 10168usize,
+ 15300usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2416,7 +2121,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).audio_debug_info as *const _ as usize
},
- 10184usize,
+ 15316usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2429,7 +2134,7 @@ fn bindgen_test_layout_cras_server_state() {
&(*(::std::ptr::null::<cras_server_state>())).default_output_buffer_size as *const _
as usize
},
- 134448usize,
+ 139536usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2441,7 +2146,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).non_empty_status as *const _ as usize
},
- 134452usize,
+ 139540usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2451,7 +2156,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).aec_supported as *const _ as usize },
- 134456usize,
+ 139544usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2461,7 +2166,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).aec_group_id as *const _ as usize },
- 134460usize,
+ 139548usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2473,7 +2178,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).snapshot_buffer as *const _ as usize
},
- 134464usize,
+ 139552usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2483,7 +2188,7 @@ fn bindgen_test_layout_cras_server_state() {
);
assert_eq!(
unsafe { &(*(::std::ptr::null::<cras_server_state>())).bt_debug_info as *const _ as usize },
- 1377308usize,
+ 1381956usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2495,7 +2200,7 @@ fn bindgen_test_layout_cras_server_state() {
unsafe {
&(*(::std::ptr::null::<cras_server_state>())).bt_wbs_enabled as *const _ as usize
},
- 1393796usize,
+ 1398348usize,
concat!(
"Offset of field: ",
stringify!(cras_server_state),
@@ -2503,71 +2208,6 @@ fn bindgen_test_layout_cras_server_state() {
stringify!(bt_wbs_enabled)
)
);
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_server_state>())).deprioritize_bt_wbs_mic as *const _
- as usize
- },
- 1393800usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_server_state),
- "::",
- stringify!(deprioritize_bt_wbs_mic)
- )
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_server_state>())).main_thread_debug_info as *const _
- as usize
- },
- 1393804usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_server_state),
- "::",
- stringify!(main_thread_debug_info)
- )
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_server_state>())).num_input_streams_with_permission
- as *const _ as usize
- },
- 1414292usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_server_state),
- "::",
- stringify!(num_input_streams_with_permission)
- )
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_server_state>())).noise_cancellation_enabled as *const _
- as usize
- },
- 1414336usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_server_state),
- "::",
- stringify!(noise_cancellation_enabled)
- )
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_server_state>())).hotword_pause_at_suspend as *const _
- as usize
- },
- 1414340usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_server_state),
- "::",
- stringify!(hotword_pause_at_suspend)
- )
- );
}
pub const cras_notify_device_action_CRAS_DEVICE_ACTION_ADD: cras_notify_device_action = 0;
pub const cras_notify_device_action_CRAS_DEVICE_ACTION_REMOVE: cras_notify_device_action = 1;
@@ -2683,14 +2323,9 @@ pub enum CRAS_NODE_TYPE {
CRAS_NODE_TYPE_HOTWORD = 6,
CRAS_NODE_TYPE_POST_MIX_PRE_DSP = 7,
CRAS_NODE_TYPE_POST_DSP = 8,
- CRAS_NODE_TYPE_BLUETOOTH_NB_MIC = 9,
- CRAS_NODE_TYPE_USB = 10,
- CRAS_NODE_TYPE_BLUETOOTH = 11,
- CRAS_NODE_TYPE_FALLBACK_NORMAL = 12,
- CRAS_NODE_TYPE_FALLBACK_ABNORMAL = 13,
- CRAS_NODE_TYPE_UNKNOWN = 14,
- CRAS_NODE_TYPE_ECHO_REFERENCE = 15,
- CRAS_NODE_TYPE_ALSA_LOOPBACK = 16,
+ CRAS_NODE_TYPE_USB = 9,
+ CRAS_NODE_TYPE_BLUETOOTH = 10,
+ CRAS_NODE_TYPE_UNKNOWN = 11,
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -2734,8 +2369,6 @@ pub enum CRAS_SERVER_MESSAGE_ID {
CRAS_SERVER_RELOAD_AEC_CONFIG = 27,
CRAS_SERVER_DUMP_BT = 28,
CRAS_SERVER_SET_BT_WBS_ENABLED = 29,
- CRAS_SERVER_GET_ATLOG_FD = 30,
- CRAS_SERVER_DUMP_MAIN = 31,
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -2754,7 +2387,6 @@ pub enum CRAS_CLIENT_MESSAGE_ID {
CRAS_CLIENT_NODE_LEFT_RIGHT_SWAPPED_CHANGED = 11,
CRAS_CLIENT_INPUT_NODE_GAIN_CHANGED = 12,
CRAS_CLIENT_NUM_ACTIVE_STREAMS_CHANGED = 13,
- CRAS_CLIENT_ATLOG_FD_READY = 14,
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
@@ -2849,14 +2481,13 @@ pub struct cras_connect_message {
pub dev_idx: u32,
pub effects: u64,
pub client_type: CRAS_CLIENT_TYPE,
- pub client_shm_size: u64,
- pub buffer_offsets: [u64; 2usize],
+ pub client_shm_size: u32,
}
#[test]
fn bindgen_test_layout_cras_connect_message() {
assert_eq!(
::std::mem::size_of::<cras_connect_message>(),
- 99usize,
+ 79usize,
concat!("Size of: ", stringify!(cras_connect_message))
);
assert_eq!(
@@ -3006,16 +2637,158 @@ fn bindgen_test_layout_cras_connect_message() {
stringify!(client_shm_size)
)
);
+}
+#[repr(C, packed)]
+#[derive(Debug, Copy, Clone)]
+pub struct cras_connect_message_old {
+ pub header: cras_server_message,
+ pub proto_version: u32,
+ pub direction: CRAS_STREAM_DIRECTION,
+ pub stream_id: cras_stream_id_t,
+ pub stream_type: CRAS_STREAM_TYPE,
+ pub buffer_frames: u32,
+ pub cb_threshold: u32,
+ pub flags: u32,
+ pub format: cras_audio_format_packed,
+ pub dev_idx: u32,
+ pub effects: u64,
+}
+#[test]
+fn bindgen_test_layout_cras_connect_message_old() {
+ assert_eq!(
+ ::std::mem::size_of::<cras_connect_message_old>(),
+ 71usize,
+ concat!("Size of: ", stringify!(cras_connect_message_old))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<cras_connect_message_old>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(cras_connect_message_old))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<cras_connect_message_old>())).header as *const _ as usize },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(header)
+ )
+ );
assert_eq!(
unsafe {
- &(*(::std::ptr::null::<cras_connect_message>())).buffer_offsets as *const _ as usize
+ &(*(::std::ptr::null::<cras_connect_message_old>())).proto_version as *const _ as usize
},
- 83usize,
+ 8usize,
concat!(
"Offset of field: ",
- stringify!(cras_connect_message),
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(proto_version)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).direction as *const _ as usize
+ },
+ 12usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(direction)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).stream_id as *const _ as usize
+ },
+ 16usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(stream_id)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).stream_type as *const _ as usize
+ },
+ 20usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(stream_type)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).buffer_frames as *const _ as usize
+ },
+ 24usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(buffer_frames)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).cb_threshold as *const _ as usize
+ },
+ 28usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(cb_threshold)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<cras_connect_message_old>())).flags as *const _ as usize },
+ 32usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(flags)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<cras_connect_message_old>())).format as *const _ as usize },
+ 36usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
"::",
- stringify!(buffer_offsets)
+ stringify!(format)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).dev_idx as *const _ as usize
+ },
+ 59usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(dev_idx)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_connect_message_old>())).effects as *const _ as usize
+ },
+ 63usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_connect_message_old),
+ "::",
+ stringify!(effects)
)
);
}
@@ -3161,6 +2934,49 @@ fn bindgen_test_layout_cras_set_system_volume() {
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
+pub struct cras_set_system_capture_gain {
+ pub header: cras_server_message,
+ pub gain: i32,
+}
+#[test]
+fn bindgen_test_layout_cras_set_system_capture_gain() {
+ assert_eq!(
+ ::std::mem::size_of::<cras_set_system_capture_gain>(),
+ 12usize,
+ concat!("Size of: ", stringify!(cras_set_system_capture_gain))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<cras_set_system_capture_gain>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(cras_set_system_capture_gain))
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_set_system_capture_gain>())).header as *const _ as usize
+ },
+ 0usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_set_system_capture_gain),
+ "::",
+ stringify!(header)
+ )
+ );
+ assert_eq!(
+ unsafe {
+ &(*(::std::ptr::null::<cras_set_system_capture_gain>())).gain as *const _ as usize
+ },
+ 8usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(cras_set_system_capture_gain),
+ "::",
+ stringify!(gain)
+ )
+ );
+}
+#[repr(C, packed)]
+#[derive(Debug, Copy, Clone)]
pub struct cras_set_system_mute {
pub header: cras_server_message,
pub mute: i32,
@@ -3495,62 +3311,6 @@ fn bindgen_test_layout_cras_dump_audio_thread() {
}
#[repr(C, packed)]
#[derive(Debug, Copy, Clone)]
-pub struct cras_get_atlog_fd {
- pub header: cras_server_message,
-}
-#[test]
-fn bindgen_test_layout_cras_get_atlog_fd() {
- assert_eq!(
- ::std::mem::size_of::<cras_get_atlog_fd>(),
- 8usize,
- concat!("Size of: ", stringify!(cras_get_atlog_fd))
- );
- assert_eq!(
- ::std::mem::align_of::<cras_get_atlog_fd>(),
- 1usize,
- concat!("Alignment of ", stringify!(cras_get_atlog_fd))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_get_atlog_fd>())).header as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_get_atlog_fd),
- "::",
- stringify!(header)
- )
- );
-}
-#[repr(C, packed)]
-#[derive(Debug, Copy, Clone)]
-pub struct cras_dump_main {
- pub header: cras_server_message,
-}
-#[test]
-fn bindgen_test_layout_cras_dump_main() {
- assert_eq!(
- ::std::mem::size_of::<cras_dump_main>(),
- 8usize,
- concat!("Size of: ", stringify!(cras_dump_main))
- );
- assert_eq!(
- ::std::mem::align_of::<cras_dump_main>(),
- 1usize,
- concat!("Alignment of ", stringify!(cras_dump_main))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<cras_dump_main>())).header as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_dump_main),
- "::",
- stringify!(header)
- )
- );
-}
-#[repr(C, packed)]
-#[derive(Debug, Copy, Clone)]
pub struct cras_dump_bt {
pub header: cras_server_message,
}
@@ -3717,17 +3477,17 @@ fn bindgen_test_layout_cras_test_dev_command() {
);
}
#[repr(C, packed)]
-#[derive(Copy, Clone)]
+#[derive(Debug, Copy, Clone)]
pub struct cras_config_global_remix {
pub header: cras_server_message,
pub num_channels: ::std::os::raw::c_uint,
- pub coefficient: [f32; 64usize],
+ pub coefficient: [f32; 32usize],
}
#[test]
fn bindgen_test_layout_cras_config_global_remix() {
assert_eq!(
::std::mem::size_of::<cras_config_global_remix>(),
- 268usize,
+ 140usize,
concat!("Size of: ", stringify!(cras_config_global_remix))
);
assert_eq!(
@@ -4169,7 +3929,7 @@ fn bindgen_test_layout_cras_client_stream_connected() {
)
);
}
-#[repr(C, packed)]
+#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct cras_client_audio_debug_info_ready {
pub header: cras_client_message,
@@ -4203,37 +3963,7 @@ fn bindgen_test_layout_cras_client_audio_debug_info_ready() {
)
);
}
-#[repr(C, packed)]
-#[derive(Debug, Copy, Clone)]
-pub struct cras_client_atlog_fd_ready {
- pub header: cras_client_message,
-}
-#[test]
-fn bindgen_test_layout_cras_client_atlog_fd_ready() {
- assert_eq!(
- ::std::mem::size_of::<cras_client_atlog_fd_ready>(),
- 8usize,
- concat!("Size of: ", stringify!(cras_client_atlog_fd_ready))
- );
- assert_eq!(
- ::std::mem::align_of::<cras_client_atlog_fd_ready>(),
- 1usize,
- concat!("Alignment of ", stringify!(cras_client_atlog_fd_ready))
- );
- assert_eq!(
- unsafe {
- &(*(::std::ptr::null::<cras_client_atlog_fd_ready>())).header as *const _ as usize
- },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(cras_client_atlog_fd_ready),
- "::",
- stringify!(header)
- )
- );
-}
-#[repr(C, packed)]
+#[repr(C)]
#[derive(Copy, Clone)]
pub struct cras_client_get_hotword_models_ready {
pub header: cras_client_message,
@@ -4252,7 +3982,7 @@ fn bindgen_test_layout_cras_client_get_hotword_models_ready() {
);
assert_eq!(
::std::mem::align_of::<cras_client_get_hotword_models_ready>(),
- 1usize,
+ 4usize,
concat!(
"Alignment of ",
stringify!(cras_client_get_hotword_models_ready)
@@ -4727,13 +4457,13 @@ pub struct cras_audio_shm_header {
pub callback_pending: i32,
pub num_overruns: u32,
pub ts: cras_timespec,
- pub buffer_offset: [u64; 2usize],
+ pub buffer_offset: [u32; 2usize],
}
#[test]
fn bindgen_test_layout_cras_audio_shm_header() {
assert_eq!(
::std::mem::size_of::<cras_audio_shm_header>(),
- 88usize,
+ 80usize,
concat!("Size of: ", stringify!(cras_audio_shm_header))
);
assert_eq!(
diff --git a/cras/client/cras-sys/src/lib.rs b/cras/client/cras-sys/src/lib.rs
index 2b3d21e0..4056162f 100644
--- a/cras/client/cras-sys/src/lib.rs
+++ b/cras/client/cras-sys/src/lib.rs
@@ -1,168 +1,49 @@
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-extern crate audio_streams;
extern crate data_model;
-use std::cmp::min;
-use std::convert::{TryFrom, TryInto};
-use std::error;
-use std::fmt;
-use std::iter::FromIterator;
-use std::os::raw::c_char;
-use std::str::FromStr;
-use std::time::Duration;
-
#[allow(dead_code)]
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
pub mod gen;
use gen::{
- _snd_pcm_format, audio_dev_debug_info, audio_message, audio_stream_debug_info,
- cras_audio_format_packed, cras_iodev_info, cras_ionode_info, cras_ionode_info__bindgen_ty_1,
- cras_timespec, snd_pcm_format_t, CRAS_AUDIO_MESSAGE_ID, CRAS_CHANNEL, CRAS_CLIENT_TYPE,
- CRAS_NODE_TYPE, CRAS_STREAM_DIRECTION, CRAS_STREAM_EFFECT, CRAS_STREAM_TYPE,
+ _snd_pcm_format, audio_message, cras_audio_format_packed, CRAS_AUDIO_MESSAGE_ID, CRAS_CHANNEL,
};
-use audio_streams::{SampleFormat, StreamDirection, StreamEffect};
-
unsafe impl data_model::DataInit for gen::audio_message {}
-unsafe impl data_model::DataInit for gen::audio_debug_info {}
-unsafe impl data_model::DataInit for gen::audio_dev_debug_info {}
-unsafe impl data_model::DataInit for gen::audio_stream_debug_info {}
unsafe impl data_model::DataInit for gen::cras_client_connected {}
unsafe impl data_model::DataInit for gen::cras_client_stream_connected {}
unsafe impl data_model::DataInit for gen::cras_connect_message {}
unsafe impl data_model::DataInit for gen::cras_disconnect_stream_message {}
-unsafe impl data_model::DataInit for gen::cras_dump_audio_thread {}
-unsafe impl data_model::DataInit for gen::cras_iodev_info {}
-unsafe impl data_model::DataInit for gen::cras_ionode_info {}
unsafe impl data_model::DataInit for gen::cras_server_state {}
-unsafe impl data_model::DataInit for gen::cras_set_system_mute {}
-unsafe impl data_model::DataInit for gen::cras_set_system_volume {}
-
-/// An enumeration of errors that can occur when converting the packed C
-/// structs into Rust-style structs.
-#[derive(Debug)]
-pub enum Error {
- InvalidChannel(i8),
- InvalidClientType(u32),
- InvalidClientTypeStr,
- InvalidStreamType(u32),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- InvalidChannel(c) => write!(
- f,
- "Channel value {} is not within valid range [0, {})",
- c,
- CRAS_CHANNEL::CRAS_CH_MAX as u32
- ),
- InvalidClientType(t) => write!(
- f,
- "Client type {} is not within valid range [0, {})",
- t,
- CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_SERVER_STREAM as u32 + 1
- ),
- InvalidClientTypeStr => write!(f, "Invalid client type string"),
- InvalidStreamType(t) => write!(
- f,
- "Stream type {} is not within valid range [0, {})",
- t,
- CRAS_STREAM_TYPE::CRAS_STREAM_NUM_TYPES as u32
- ),
- }
- }
-}
impl cras_audio_format_packed {
/// Initializes `cras_audio_format_packed` from input parameters.
- /// Field `channel_layout` will be assigned with default channel layout defined in
- /// `Self::default_channel_layout`.
///
/// # Arguments
/// * `format` - Format in used.
/// * `rate` - Rate in used.
/// * `num_channels` - Number of channels in used.
- /// * `direction` - Stream direction enumeration.
///
/// # Returns
/// Structure `cras_audio_format_packed`
- pub fn new(
- format: _snd_pcm_format,
- rate: u32,
- num_channels: usize,
- direction: CRAS_STREAM_DIRECTION,
- ) -> Self {
- Self {
+ pub fn new(format: _snd_pcm_format, rate: usize, num_channels: usize) -> Self {
+ let mut audio_format = Self {
format: format as i32,
- frame_rate: rate,
+ frame_rate: rate as u32,
num_channels: num_channels as u32,
- channel_layout: Self::default_channel_layout(num_channels, direction),
- }
- }
-
- /// Generates default channel layout by given number of channels and stream direction.
- /// ```
- /// use cras_sys::gen::{
- /// _snd_pcm_format,
- /// cras_audio_format_packed,
- /// CRAS_STREAM_DIRECTION::*
- /// };
- /// let test_one = | num_channels, direction, expected_results | {
- /// let default_channel_fmt = cras_audio_format_packed::new(
- /// _snd_pcm_format::SND_PCM_FORMAT_S16,
- /// 48000,
- /// num_channels,
- /// direction
- /// );
- /// assert_eq!(default_channel_fmt.channel_layout, expected_results);
- /// };
- /// test_one(2, CRAS_STREAM_OUTPUT, [0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1]);
- /// test_one(4, CRAS_STREAM_OUTPUT, [0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1]);
- /// test_one(6, CRAS_STREAM_OUTPUT, [0, 1, 4, 5, 2, 3, -1, -1, -1, -1, -1]);
- /// test_one(2, CRAS_STREAM_INPUT, [0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1]);
- /// test_one(4, CRAS_STREAM_INPUT, [0, 1, 2, 3, -1, -1, -1, -1, -1, -1, -1]);
- /// test_one(6, CRAS_STREAM_INPUT, [0, 1, 2, 3, 4, 5, -1, -1, -1, -1, -1]);
- /// ```
- fn default_channel_layout(
- num_channels: usize,
- direction: CRAS_STREAM_DIRECTION,
- ) -> [i8; CRAS_CHANNEL::CRAS_CH_MAX as usize] {
- use {CRAS_CHANNEL::*, CRAS_STREAM_DIRECTION::*};
-
- let mut channel_layout = [-1; CRAS_CH_MAX as usize];
- match (num_channels, direction) {
- (6, CRAS_STREAM_OUTPUT) => {
- [
- CRAS_CH_FL,
- CRAS_CH_FR,
- CRAS_CH_FC,
- CRAS_CH_LFE,
- CRAS_CH_RL,
- CRAS_CH_RR,
- ]
- .iter()
- .enumerate()
- .for_each(|(idx, &channel)| channel_layout[channel as usize] = idx as i8);
- }
- _ => {
- for (i, channel) in channel_layout
- .iter_mut()
- .enumerate()
- .take(min(num_channels, CRAS_CH_MAX as usize))
- {
- *channel = i as i8;
- }
+ channel_layout: [-1; CRAS_CHANNEL::CRAS_CH_MAX as usize],
+ };
+ for i in 0..CRAS_CHANNEL::CRAS_CH_MAX as usize {
+ if i < num_channels {
+ audio_format.channel_layout[i] = i as i8;
+ } else {
+ break;
}
}
- channel_layout
+ audio_format
}
}
@@ -175,483 +56,3 @@ impl Default for audio_message {
}
}
}
-
-impl Default for cras_iodev_info {
- fn default() -> Self {
- Self {
- idx: 0,
- name: [0; 64usize],
- stable_id: 0,
- max_supported_channels: 0,
- }
- }
-}
-
-#[derive(Debug)]
-pub struct CrasIodevInfo {
- pub index: u32,
- pub name: String,
-}
-
-fn cstring_to_string(cstring: &[c_char]) -> String {
- let null_idx = match cstring.iter().enumerate().find(|(_, &c)| c == 0) {
- Some((i, _)) => i,
- None => return "".to_owned(),
- };
-
- let ptr = cstring.as_ptr() as *const u8;
- let slice = unsafe { core::slice::from_raw_parts(ptr, null_idx) };
- String::from_utf8_lossy(slice).to_string()
-}
-
-impl From<cras_iodev_info> for CrasIodevInfo {
- fn from(info: cras_iodev_info) -> Self {
- Self {
- index: info.idx,
- name: cstring_to_string(&info.name),
- }
- }
-}
-
-impl Default for cras_ionode_info {
- fn default() -> Self {
- Self {
- iodev_idx: 0,
- ionode_idx: 0,
- plugged: 0,
- active: 0,
- plugged_time: cras_ionode_info__bindgen_ty_1 {
- tv_sec: 0,
- tv_usec: 0,
- },
- volume: 0,
- ui_gain_scaler: 0.0,
- capture_gain: 0,
- left_right_swapped: 0,
- type_enum: 0,
- stable_id: 0,
- type_: [0; 32usize],
- name: [0; 64usize],
- active_hotword_model: [0; 16usize],
- }
- }
-}
-
-impl From<u32> for CRAS_NODE_TYPE {
- fn from(node_type: u32) -> CRAS_NODE_TYPE {
- use CRAS_NODE_TYPE::*;
- match node_type {
- 0 => CRAS_NODE_TYPE_INTERNAL_SPEAKER,
- 1 => CRAS_NODE_TYPE_HEADPHONE,
- 2 => CRAS_NODE_TYPE_HDMI,
- 3 => CRAS_NODE_TYPE_HAPTIC,
- 4 => CRAS_NODE_TYPE_LINEOUT,
- 5 => CRAS_NODE_TYPE_MIC,
- 6 => CRAS_NODE_TYPE_HOTWORD,
- 7 => CRAS_NODE_TYPE_POST_MIX_PRE_DSP,
- 8 => CRAS_NODE_TYPE_POST_DSP,
- 9 => CRAS_NODE_TYPE_USB,
- 10 => CRAS_NODE_TYPE_BLUETOOTH,
- _ => CRAS_NODE_TYPE_UNKNOWN,
- }
- }
-}
-
-#[derive(Debug)]
-pub struct CrasIonodeInfo {
- pub name: String,
- pub iodev_index: u32,
- pub ionode_index: u32,
- pub stable_id: u32,
- pub plugged: bool,
- pub active: bool,
- pub node_type: CRAS_NODE_TYPE,
- pub type_name: String,
- pub volume: u32,
- pub capture_gain: i32,
- pub plugged_time: cras_timespec,
-}
-
-impl From<cras_ionode_info> for CrasIonodeInfo {
- fn from(info: cras_ionode_info) -> Self {
- Self {
- name: cstring_to_string(&info.name),
- iodev_index: info.iodev_idx,
- ionode_index: info.ionode_idx,
- stable_id: info.stable_id,
- plugged: info.plugged != 0,
- active: info.active != 0,
- node_type: CRAS_NODE_TYPE::from(info.type_enum),
- type_name: cstring_to_string(&info.type_),
- volume: info.volume,
- capture_gain: info.capture_gain,
- plugged_time: cras_timespec {
- tv_sec: info.plugged_time.tv_sec,
- tv_nsec: info.plugged_time.tv_usec * 1000,
- },
- }
- }
-}
-
-impl From<u32> for CRAS_STREAM_DIRECTION {
- fn from(node_type: u32) -> CRAS_STREAM_DIRECTION {
- use CRAS_STREAM_DIRECTION::*;
- match node_type {
- 0 => CRAS_STREAM_OUTPUT,
- 1 => CRAS_STREAM_INPUT,
- 2 => CRAS_STREAM_UNDEFINED,
- 3 => CRAS_STREAM_POST_MIX_PRE_DSP,
- _ => CRAS_STREAM_UNDEFINED,
- }
- }
-}
-
-impl Default for audio_dev_debug_info {
- fn default() -> Self {
- Self {
- dev_name: [0; 64],
- buffer_size: 0,
- min_buffer_level: 0,
- min_cb_level: 0,
- max_cb_level: 0,
- frame_rate: 0,
- num_channels: 0,
- est_rate_ratio: 0.0,
- direction: 0,
- num_underruns: 0,
- num_severe_underruns: 0,
- highest_hw_level: 0,
- runtime_sec: 0,
- runtime_nsec: 0,
- longest_wake_sec: 0,
- longest_wake_nsec: 0,
- software_gain_scaler: 0.0,
- }
- }
-}
-
-/// A rust-style representation of the server's packed audio_dev_debug_info
-/// struct.
-#[derive(Debug)]
-pub struct AudioDevDebugInfo {
- pub dev_name: String,
- pub buffer_size: u32,
- pub min_buffer_level: u32,
- pub min_cb_level: u32,
- pub max_cb_level: u32,
- pub frame_rate: u32,
- pub num_channels: u32,
- pub est_rate_ratio: f64,
- pub direction: CRAS_STREAM_DIRECTION,
- pub num_underruns: u32,
- pub num_severe_underruns: u32,
- pub highest_hw_level: u32,
- pub runtime: Duration,
- pub longest_wake: Duration,
- pub software_gain_scaler: f64,
-}
-
-impl From<audio_dev_debug_info> for AudioDevDebugInfo {
- fn from(info: audio_dev_debug_info) -> Self {
- Self {
- dev_name: cstring_to_string(&info.dev_name),
- buffer_size: info.buffer_size,
- min_buffer_level: info.min_buffer_level,
- min_cb_level: info.min_cb_level,
- max_cb_level: info.max_cb_level,
- frame_rate: info.frame_rate,
- num_channels: info.num_channels,
- est_rate_ratio: info.est_rate_ratio,
- direction: CRAS_STREAM_DIRECTION::from(u32::from(info.direction)),
- num_underruns: info.num_underruns,
- num_severe_underruns: info.num_severe_underruns,
- highest_hw_level: info.highest_hw_level,
- runtime: Duration::new(info.runtime_sec.into(), info.runtime_nsec),
- longest_wake: Duration::new(info.longest_wake_sec.into(), info.longest_wake_nsec),
- software_gain_scaler: info.software_gain_scaler,
- }
- }
-}
-
-impl fmt::Display for AudioDevDebugInfo {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- writeln!(f, "Device: {}", self.dev_name)?;
- writeln!(f, " Direction: {:?}", self.direction)?;
- writeln!(f, " Buffer size: {}", self.buffer_size)?;
- writeln!(f, " Minimum buffer level: {}", self.min_buffer_level)?;
- writeln!(f, " Minimum callback level: {}", self.min_cb_level)?;
- writeln!(f, " Max callback level: {}", self.max_cb_level)?;
- writeln!(f, " Frame rate: {}", self.frame_rate)?;
- writeln!(f, " Number of channels: {}", self.num_channels)?;
- writeln!(f, " Estimated rate ratio: {:.2}", self.est_rate_ratio)?;
- writeln!(f, " Underrun count: {}", self.num_underruns)?;
- writeln!(f, " Severe underrun count: {}", self.num_severe_underruns)?;
- writeln!(f, " Highest hardware level: {}", self.highest_hw_level)?;
- writeln!(f, " Runtime: {:?}", self.runtime)?;
- writeln!(f, " Longest wake: {:?}", self.longest_wake)?;
- writeln!(f, " Software gain scaler: {}", self.software_gain_scaler)?;
- Ok(())
- }
-}
-
-impl TryFrom<u32> for CRAS_STREAM_TYPE {
- type Error = Error;
- fn try_from(stream_type: u32) -> Result<Self, Self::Error> {
- use CRAS_STREAM_TYPE::*;
- match stream_type {
- 0 => Ok(CRAS_STREAM_TYPE_DEFAULT),
- 1 => Ok(CRAS_STREAM_TYPE_MULTIMEDIA),
- 2 => Ok(CRAS_STREAM_TYPE_VOICE_COMMUNICATION),
- 3 => Ok(CRAS_STREAM_TYPE_SPEECH_RECOGNITION),
- 4 => Ok(CRAS_STREAM_TYPE_PRO_AUDIO),
- 5 => Ok(CRAS_STREAM_TYPE_ACCESSIBILITY),
- _ => Err(Error::InvalidStreamType(stream_type)),
- }
- }
-}
-
-impl TryFrom<u32> for CRAS_CLIENT_TYPE {
- type Error = Error;
- fn try_from(client_type: u32) -> Result<Self, Self::Error> {
- use CRAS_CLIENT_TYPE::*;
- match client_type {
- 0 => Ok(CRAS_CLIENT_TYPE_UNKNOWN),
- 1 => Ok(CRAS_CLIENT_TYPE_LEGACY),
- 2 => Ok(CRAS_CLIENT_TYPE_TEST),
- 3 => Ok(CRAS_CLIENT_TYPE_PCM),
- 4 => Ok(CRAS_CLIENT_TYPE_CHROME),
- 5 => Ok(CRAS_CLIENT_TYPE_ARC),
- 6 => Ok(CRAS_CLIENT_TYPE_CROSVM),
- 7 => Ok(CRAS_CLIENT_TYPE_SERVER_STREAM),
- 8 => Ok(CRAS_CLIENT_TYPE_LACROS),
- _ => Err(Error::InvalidClientType(client_type)),
- }
- }
-}
-
-impl FromStr for CRAS_CLIENT_TYPE {
- type Err = Error;
- fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
- use CRAS_CLIENT_TYPE::*;
- match s {
- "crosvm" => Ok(CRAS_CLIENT_TYPE_CROSVM),
- "arcvm" => Ok(CRAS_CLIENT_TYPE_ARCVM),
- _ => Err(Error::InvalidClientTypeStr),
- }
- }
-}
-
-impl Default for audio_stream_debug_info {
- fn default() -> Self {
- Self {
- stream_id: 0,
- dev_idx: 0,
- direction: 0,
- stream_type: 0,
- client_type: 0,
- buffer_frames: 0,
- cb_threshold: 0,
- effects: 0,
- flags: 0,
- frame_rate: 0,
- num_channels: 0,
- longest_fetch_sec: 0,
- longest_fetch_nsec: 0,
- num_missed_cb: 0,
- num_overruns: 0,
- is_pinned: 0,
- pinned_dev_idx: 0,
- runtime_sec: 0,
- runtime_nsec: 0,
- stream_volume: 0.0,
- channel_layout: [0; 11],
- }
- }
-}
-
-impl TryFrom<i8> for CRAS_CHANNEL {
- type Error = Error;
- fn try_from(channel: i8) -> Result<Self, Self::Error> {
- use CRAS_CHANNEL::*;
- match channel {
- 0 => Ok(CRAS_CH_FL),
- 1 => Ok(CRAS_CH_FR),
- 2 => Ok(CRAS_CH_RL),
- 3 => Ok(CRAS_CH_RR),
- 4 => Ok(CRAS_CH_FC),
- 5 => Ok(CRAS_CH_LFE),
- 6 => Ok(CRAS_CH_SL),
- 7 => Ok(CRAS_CH_SR),
- 8 => Ok(CRAS_CH_RC),
- 9 => Ok(CRAS_CH_FLC),
- 10 => Ok(CRAS_CH_FRC),
- _ => Err(Error::InvalidChannel(channel)),
- }
- }
-}
-
-/// A rust-style representation of the server's packed audio_stream_debug_info
-/// struct.
-#[derive(Debug)]
-pub struct AudioStreamDebugInfo {
- pub stream_id: u64,
- pub dev_idx: u32,
- pub direction: CRAS_STREAM_DIRECTION,
- pub stream_type: CRAS_STREAM_TYPE,
- pub client_type: CRAS_CLIENT_TYPE,
- pub buffer_frames: u32,
- pub cb_threshold: u32,
- pub effects: u64,
- pub flags: u32,
- pub frame_rate: u32,
- pub num_channels: u32,
- pub longest_fetch: Duration,
- pub num_missed_cb: u32,
- pub num_overruns: u32,
- pub is_pinned: bool,
- pub pinned_dev_idx: u32,
- pub runtime: Duration,
- pub stream_volume: f64,
- pub channel_layout: Vec<CRAS_CHANNEL>,
-}
-
-impl TryFrom<audio_stream_debug_info> for AudioStreamDebugInfo {
- type Error = Error;
- fn try_from(info: audio_stream_debug_info) -> Result<Self, Self::Error> {
- let channel_layout = info
- .channel_layout
- .iter()
- .cloned()
- .take_while(|&c| c != -1)
- .map(TryInto::try_into)
- .collect::<Result<Vec<_>, _>>()?;
- Ok(Self {
- stream_id: info.stream_id,
- dev_idx: info.dev_idx,
- direction: info.direction.into(),
- stream_type: info.stream_type.try_into()?,
- client_type: info.client_type.try_into()?,
- buffer_frames: info.buffer_frames,
- cb_threshold: info.cb_threshold,
- effects: info.effects,
- flags: info.flags,
- frame_rate: info.frame_rate,
- num_channels: info.num_channels,
- longest_fetch: Duration::new(info.longest_fetch_sec.into(), info.longest_fetch_nsec),
- num_missed_cb: info.num_missed_cb,
- num_overruns: info.num_overruns,
- is_pinned: info.is_pinned != 0,
- pinned_dev_idx: info.pinned_dev_idx,
- runtime: Duration::new(info.runtime_sec.into(), info.runtime_nsec),
- stream_volume: info.stream_volume,
- channel_layout,
- })
- }
-}
-
-impl fmt::Display for AudioStreamDebugInfo {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- writeln!(
- f,
- "Stream: {}, Device index: {}",
- self.stream_id, self.dev_idx
- )?;
- writeln!(f, " Direction: {:?}", self.direction)?;
- writeln!(f, " Stream type: {:?}", self.stream_type)?;
- writeln!(f, " Client type: {:?}", self.client_type)?;
- writeln!(f, " Buffer frames: {}", self.buffer_frames)?;
- writeln!(f, " Callback threshold: {}", self.cb_threshold)?;
- writeln!(f, " Effects: {:#x}", self.effects)?;
- writeln!(f, " Frame rate: {}", self.frame_rate)?;
- writeln!(f, " Number of channels: {}", self.num_channels)?;
- writeln!(f, " Longest fetch: {:?}", self.longest_fetch)?;
- writeln!(f, " Overrun count: {}", self.num_overruns)?;
- writeln!(f, " Pinned: {}", self.is_pinned)?;
- writeln!(f, " Pinned device index: {}", self.pinned_dev_idx)?;
- writeln!(f, " Missed callbacks: {}", self.num_missed_cb)?;
- match self.direction {
- CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT => {
- writeln!(f, " Volume: {:.2}", self.stream_volume)?
- }
- CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT => {
- writeln!(f, " Gain: {:.2}", self.stream_volume)?
- }
- _ => (),
- };
- writeln!(f, " Runtime: {:?}", self.runtime)?;
- write!(f, " Channel map:")?;
- for channel in &self.channel_layout {
- write!(f, " {:?}", channel)?;
- }
- writeln!(f)?;
- Ok(())
- }
-}
-
-/// A rust-style representation of the server's audio debug info.
-pub struct AudioDebugInfo {
- pub devices: Vec<AudioDevDebugInfo>,
- pub streams: Vec<AudioStreamDebugInfo>,
-}
-
-impl AudioDebugInfo {
- pub fn new(devices: Vec<AudioDevDebugInfo>, streams: Vec<AudioStreamDebugInfo>) -> Self {
- Self { devices, streams }
- }
-}
-
-impl Into<u64> for CRAS_STREAM_EFFECT {
- fn into(self) -> u64 {
- u64::from(self.0)
- }
-}
-
-impl CRAS_STREAM_EFFECT {
- pub fn empty() -> Self {
- CRAS_STREAM_EFFECT(0)
- }
-}
-
-impl From<StreamDirection> for CRAS_STREAM_DIRECTION {
- /// Convert an audio_streams StreamDirection into the corresponding CRAS_STREAM_DIRECTION.
- fn from(direction: StreamDirection) -> Self {
- match direction {
- StreamDirection::Playback => CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT,
- StreamDirection::Capture => CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT,
- }
- }
-}
-
-impl From<StreamEffect> for CRAS_STREAM_EFFECT {
- /// Convert an audio_streams StreamEffect into the corresponding CRAS_STREAM_EFFECT.
- fn from(effect: StreamEffect) -> Self {
- match effect {
- StreamEffect::NoEffect => CRAS_STREAM_EFFECT::empty(),
- StreamEffect::EchoCancellation => CRAS_STREAM_EFFECT::APM_ECHO_CANCELLATION,
- }
- }
-}
-
-impl<'a> FromIterator<&'a StreamEffect> for CRAS_STREAM_EFFECT {
- fn from_iter<I>(iter: I) -> Self
- where
- I: IntoIterator<Item = &'a StreamEffect>,
- {
- iter.into_iter().fold(
- CRAS_STREAM_EFFECT::empty(),
- |cras_effect, &stream_effect| cras_effect | stream_effect.into(),
- )
- }
-}
-
-/// Convert an audio_streams SampleFormat into the corresponding pcm_format.
-impl From<SampleFormat> for snd_pcm_format_t {
- fn from(format: SampleFormat) -> Self {
- match format {
- SampleFormat::U8 => snd_pcm_format_t::SND_PCM_FORMAT_U8,
- SampleFormat::S16LE => snd_pcm_format_t::SND_PCM_FORMAT_S16_LE,
- SampleFormat::S24LE => snd_pcm_format_t::SND_PCM_FORMAT_S24_LE,
- SampleFormat::S32LE => snd_pcm_format_t::SND_PCM_FORMAT_S32_LE,
- }
- }
-}
diff --git a/cras/client/cras_tests/Cargo.toml b/cras/client/cras_tests/Cargo.toml
index 108fe6c4..94453ddf 100644
--- a/cras/client/cras_tests/Cargo.toml
+++ b/cras/client/cras_tests/Cargo.toml
@@ -7,11 +7,5 @@ edition = "2018"
[dependencies]
audio_streams = { path = "../../../audio_streams" } # provided by ebuild
getopts = "0.2.18"
-hound = "3.4.0"
libcras = { path = "../libcras" } # provided by ebuild
-sys_util = { path = "../../../../crosvm/sys_util" } # provided by ebuild
-
-[profile.release]
-lto = true
-panic = 'abort'
-overflow-checks = true
+sys_util = { path = "../../../../../platform/crosvm/sys_util" } # provided by ebuild
diff --git a/cras/client/cras_tests/src/arguments.rs b/cras/client/cras_tests/src/arguments.rs
deleted file mode 100644
index 59e9ec26..00000000
--- a/cras/client/cras_tests/src/arguments.rs
+++ /dev/null
@@ -1,462 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::error;
-use std::fmt;
-use std::path::PathBuf;
-
-use audio_streams::SampleFormat;
-use getopts::{self, Matches, Options};
-
-#[derive(Debug)]
-pub enum Error {
- GetOpts(getopts::Fail),
- InvalidArgument(String, String, String),
- InvalidFiletype(String),
- MissingArgument(String),
- MissingCommand,
- MissingFilename,
- UnknownCommand(String),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- GetOpts(e) => write!(f, "Getopts Error: {}", e),
- InvalidArgument(flag, value, error_msg) => {
- write!(f, "Invalid {} argument '{}': {}", flag, value, error_msg)
- }
- InvalidFiletype(extension) => write!(
- f,
- "Invalid file extension '{}'. Supported types are 'wav' and 'raw'",
- extension
- ),
- MissingArgument(subcommand) => write!(f, "Missing argument for {}", subcommand),
- MissingCommand => write!(f, "A command must be provided"),
- MissingFilename => write!(f, "A file name must be provided"),
- UnknownCommand(s) => write!(f, "Unknown command '{}'", s),
- }
- }
-}
-
-type Result<T> = std::result::Result<T, Error>;
-
-/// The different types of commands that can be given to cras_tests.
-/// Any options for those commands are passed as parameters to the enum values.
-#[derive(Debug, PartialEq)]
-pub enum Command {
- Capture(AudioOptions),
- Playback(AudioOptions),
- Control(ControlCommand),
-}
-
-impl Command {
- pub fn parse<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> {
- let program_name = args.get(0).map(|s| s.as_ref()).unwrap_or("cras_tests");
- let remaining_args = args.get(2..).unwrap_or(&[]);
- match args.get(1).map(|s| s.as_ref()) {
- None => {
- show_usage(program_name);
- Err(Error::MissingCommand)
- }
- Some("help") => {
- show_usage(program_name);
- Ok(None)
- }
- Some("capture") => Ok(
- AudioOptions::parse(program_name, "capture", remaining_args)?.map(Command::Capture),
- ),
- Some("playback") => Ok(
- AudioOptions::parse(program_name, "playback", remaining_args)?
- .map(Command::Playback),
- ),
- Some("control") => {
- Ok(ControlCommand::parse(program_name, remaining_args)?.map(Command::Control))
- }
- Some(s) => {
- show_usage(program_name);
- Err(Error::UnknownCommand(s.to_string()))
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum FileType {
- Raw,
- Wav,
-}
-
-impl fmt::Display for FileType {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- FileType::Raw => write!(f, "raw data"),
- FileType::Wav => write!(f, "WAVE"),
- }
- }
-}
-
-fn show_usage(program_name: &str) {
- eprintln!("Usage: {} [command] <command args>", program_name);
- eprintln!("\nCommands:\n");
- eprintln!("capture - Capture to a file from CRAS");
- eprintln!("playback - Playback to CRAS from a file");
- eprintln!("control - Get and set server settings");
- eprintln!("\nhelp - Print help message");
-}
-
-fn show_audio_command_usage(program_name: &str, command: &str, opts: &Options) {
- let brief = format!("Usage: {} {} [options] [filename]", program_name, command);
- eprint!("{}", opts.usage(&brief));
-}
-
-/// The possible command line options that can be passed to the 'playback' and
-/// 'capture' commands. Optional values will be `Some(_)` only if a value was
-/// explicitly provided by the user.
-///
-/// This struct will be passed to `playback()` and `capture()`.
-#[derive(Debug, PartialEq)]
-pub enum LoopbackType {
- PreDsp,
- PostDsp,
-}
-
-#[derive(Debug, PartialEq)]
-pub struct AudioOptions {
- pub file_name: PathBuf,
- pub loopback_type: Option<LoopbackType>,
- pub file_type: FileType,
- pub buffer_size: Option<usize>,
- pub num_channels: Option<usize>,
- pub format: Option<SampleFormat>,
- pub frame_rate: Option<u32>,
-}
-
-fn get_u32_param(matches: &Matches, option_name: &str) -> Result<Option<u32>> {
- matches.opt_get::<u32>(option_name).map_err(|e| {
- let argument = matches.opt_str(option_name).unwrap_or_default();
- Error::InvalidArgument(option_name.to_string(), argument, e.to_string())
- })
-}
-
-fn get_usize_param(matches: &Matches, option_name: &str) -> Result<Option<usize>> {
- matches.opt_get::<usize>(option_name).map_err(|e| {
- let argument = matches.opt_str(option_name).unwrap_or_default();
- Error::InvalidArgument(option_name.to_string(), argument, e.to_string())
- })
-}
-
-impl AudioOptions {
- fn parse<T: AsRef<str>>(
- program_name: &str,
- command_name: &str,
- args: &[T],
- ) -> Result<Option<Self>> {
- let mut opts = Options::new();
- opts.optopt("b", "buffer_size", "Buffer size in frames", "SIZE")
- .optopt("c", "channels", "Number of channels", "NUM")
- .optopt(
- "f",
- "format",
- "Sample format (U8, S16_LE, S24_LE, or S32_LE)",
- "FORMAT",
- )
- .optopt("r", "rate", "Audio frame rate (Hz)", "RATE")
- .optflag("h", "help", "Print help message");
-
- if command_name == "capture" {
- opts.optopt(
- "",
- "loopback",
- "Capture from loopback device ('pre_dsp' or 'post_dsp')",
- "DEVICE",
- );
- }
-
- let args = args.iter().map(|s| s.as_ref());
- let matches = match opts.parse(args) {
- Ok(m) => m,
- Err(e) => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::GetOpts(e));
- }
- };
- if matches.opt_present("h") {
- show_audio_command_usage(program_name, command_name, &opts);
- return Ok(None);
- }
-
- let loopback_type = if matches.opt_defined("loopback") {
- match matches.opt_str("loopback").as_deref() {
- Some("pre_dsp") => Some(LoopbackType::PreDsp),
- Some("post_dsp") => Some(LoopbackType::PostDsp),
- Some(s) => {
- return Err(Error::InvalidArgument(
- "loopback".to_string(),
- s.to_string(),
- "Loopback type must be 'pre_dsp' or 'post_dsp'".to_string(),
- ))
- }
- None => None,
- }
- } else {
- None
- };
-
- let file_name = match matches.free.get(0) {
- None => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::MissingFilename);
- }
- Some(file_name) => PathBuf::from(file_name),
- };
-
- let extension = file_name
- .extension()
- .map(|s| s.to_string_lossy().into_owned());
- let file_type = match extension.as_deref() {
- Some("wav") | Some("wave") => FileType::Wav,
- Some("raw") | None => FileType::Raw,
- Some(extension) => return Err(Error::InvalidFiletype(extension.to_string())),
- };
-
- let buffer_size = get_usize_param(&matches, "buffer_size")?;
- let num_channels = get_usize_param(&matches, "channels")?;
- let frame_rate = get_u32_param(&matches, "rate")?;
- let format = match matches.opt_str("format").as_deref() {
- Some("U8") => Some(SampleFormat::U8),
- Some("S16_LE") => Some(SampleFormat::S16LE),
- Some("S24_LE") => Some(SampleFormat::S24LE),
- Some("S32_LE") => Some(SampleFormat::S32LE),
- Some(s) => {
- show_audio_command_usage(program_name, command_name, &opts);
- return Err(Error::InvalidArgument(
- "format".to_string(),
- s.to_string(),
- "Format must be 'U8', 'S16_LE', 'S24_LE', or 'S32_LE'".to_string(),
- ));
- }
- None => None,
- };
-
- Ok(Some(AudioOptions {
- loopback_type,
- file_name,
- file_type,
- buffer_size,
- num_channels,
- format,
- frame_rate,
- }))
- }
-}
-
-fn show_control_command_usage(program_name: &str) {
- eprintln!("Usage: {} control [command] <command args>", program_name);
- eprintln!("");
- eprintln!("Commands:");
- let commands = [
- ("help", "", "Print help message"),
- ("", "", ""),
- ("get_volume", "", "Get the system volume (0 - 100)"),
- (
- "set_volume",
- "VOLUME",
- "Set the system volume to VOLUME (0 - 100)",
- ),
- ("get_mute", "", "Get the system mute state (true or false)"),
- (
- "set_mute",
- "MUTE",
- "Set the system mute state to MUTE (true or false)",
- ),
- ("", "", ""),
- ("list_output_devices", "", "Print list of output devices"),
- ("list_input_devices", "", "Print list of input devices"),
- ("list_output_nodes", "", "Print list of output nodes"),
- ("list_input_nodes", "", "Print list of input nodes"),
- (
- "dump_audio_debug_info",
- "",
- "Print stream info, device info, and audio thread log.",
- ),
- ];
- for command in &commands {
- let command_string = format!("{} {}", command.0, command.1);
- eprintln!("\t{: <23} {}", command_string, command.2);
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum ControlCommand {
- GetSystemVolume,
- SetSystemVolume(u32),
- GetSystemMute,
- SetSystemMute(bool),
- ListOutputDevices,
- ListInputDevices,
- ListOutputNodes,
- ListInputNodes,
- DumpAudioDebugInfo,
-}
-
-impl ControlCommand {
- fn parse<T: AsRef<str>>(program_name: &str, args: &[T]) -> Result<Option<Self>> {
- let mut args = args.iter().map(|s| s.as_ref());
- match args.next() {
- Some("help") => {
- show_control_command_usage(program_name);
- Ok(None)
- }
- Some("get_volume") => Ok(Some(ControlCommand::GetSystemVolume)),
- Some("set_volume") => {
- let volume_str = args
- .next()
- .ok_or_else(|| Error::MissingArgument("set_volume".to_string()))?;
-
- let volume = volume_str.parse::<u32>().map_err(|e| {
- Error::InvalidArgument(
- "set_volume".to_string(),
- volume_str.to_string(),
- e.to_string(),
- )
- })?;
-
- Ok(Some(ControlCommand::SetSystemVolume(volume)))
- }
- Some("get_mute") => Ok(Some(ControlCommand::GetSystemMute)),
- Some("set_mute") => {
- let mute_str = args
- .next()
- .ok_or_else(|| Error::MissingArgument("set_mute".to_string()))?;
-
- let mute = mute_str.parse::<bool>().map_err(|e| {
- Error::InvalidArgument(
- "set_mute".to_string(),
- mute_str.to_string(),
- e.to_string(),
- )
- })?;
- Ok(Some(ControlCommand::SetSystemMute(mute)))
- }
- Some("list_output_devices") => Ok(Some(ControlCommand::ListOutputDevices)),
- Some("list_input_devices") => Ok(Some(ControlCommand::ListInputDevices)),
- Some("list_output_nodes") => Ok(Some(ControlCommand::ListOutputNodes)),
- Some("list_input_nodes") => Ok(Some(ControlCommand::ListInputNodes)),
- Some("dump_audio_debug_info") => Ok(Some(ControlCommand::DumpAudioDebugInfo)),
- Some(s) => {
- show_control_command_usage(program_name);
- Err(Error::UnknownCommand(s.to_string()))
- }
- None => {
- show_control_command_usage(program_name);
- Err(Error::MissingCommand)
- }
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn parse_command() {
- let command = Command::parse(&["cras_tests", "playback", "output.wav"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output.wav"),
- loopback_type: None,
- file_type: FileType::Wav,
- frame_rate: None,
- num_channels: None,
- format: None,
- buffer_size: None,
- })
- );
- let command = Command::parse(&["cras_tests", "capture", "input.raw"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Capture(AudioOptions {
- file_name: PathBuf::from("input.raw"),
- loopback_type: None,
- file_type: FileType::Raw,
- frame_rate: None,
- num_channels: None,
- format: None,
- buffer_size: None,
- })
- );
-
- let command = Command::parse(&[
- "cras_tests",
- "playback",
- "-r",
- "44100",
- "output.wave",
- "-c",
- "2",
- ])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output.wave"),
- loopback_type: None,
- file_type: FileType::Wav,
- frame_rate: Some(44100),
- num_channels: Some(2),
- format: None,
- buffer_size: None,
- })
- );
-
- let command =
- Command::parse(&["cras_tests", "playback", "-r", "44100", "output", "-c", "2"])
- .unwrap()
- .unwrap();
- assert_eq!(
- command,
- Command::Playback(AudioOptions {
- file_name: PathBuf::from("output"),
- loopback_type: None,
- file_type: FileType::Raw,
- frame_rate: Some(44100),
- num_channels: Some(2),
- format: None,
- buffer_size: None,
- })
- );
-
- assert!(Command::parse(&["cras_tests"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.mp3"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.ogg"]).is_err());
- assert!(Command::parse(&["cras_tests", "capture", "input.flac"]).is_err());
- assert!(Command::parse(&["cras_tests", "playback"]).is_err());
- assert!(Command::parse(&["cras_tests", "loopback"]).is_err());
- assert!(Command::parse(&["cras_tests", "loopback", "file.ogg"]).is_err());
- assert!(Command::parse(&["cras_tests", "filename.wav"]).is_err());
- assert!(Command::parse(&["cras_tests", "filename.wav", "capture"]).is_err());
- assert!(Command::parse(&["cras_tests", "help"]).is_ok());
- assert!(Command::parse(&[
- "cras_tests",
- "-c",
- "2",
- "playback",
- "output.wav",
- "-r",
- "44100"
- ])
- .is_err());
- }
-}
diff --git a/cras/client/cras_tests/src/audio.rs b/cras/client/cras_tests/src/audio.rs
deleted file mode 100644
index 23018fd7..00000000
--- a/cras/client/cras_tests/src/audio.rs
+++ /dev/null
@@ -1,414 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std::error;
-use std::fmt;
-use std::fs::File;
-use std::io::{self, BufReader, BufWriter, Read, Write};
-use std::os::raw::c_int;
-use std::path::Path;
-use std::sync::atomic::{AtomicBool, Ordering};
-
-use audio_streams::{SampleFormat, StreamSource};
-use hound::{WavReader, WavSpec, WavWriter};
-use libcras::{BoxError, CrasClient, CrasNodeType};
-use sys_util::{register_signal_handler, set_rt_prio_limit, set_rt_round_robin};
-
-use crate::arguments::{AudioOptions, FileType, LoopbackType};
-
-#[derive(Debug)]
-pub enum Error {
- CreateStream(BoxError),
- FetchStream(BoxError),
- FloatingPointSamples,
- InvalidWavFile(hound::Error),
- Io(io::Error),
- Libcras(libcras::Error),
- NoLoopbackNode(CrasNodeType),
- OpenFile(hound::Error),
- SampleBits(u16),
- SysUtil(sys_util::Error),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- CreateStream(e) => write!(f, "Failed to create stream: {}", e),
- FetchStream(e) => write!(f, "Failed to fetch buffer from stream: {}", e),
- FloatingPointSamples => write!(f, "Floating point audio samples are not supported"),
- InvalidWavFile(e) => write!(f, "Could not open file as WAV file: {}", e),
- Io(e) => write!(f, "IO Error: {}", e),
- Libcras(e) => write!(f, "Libcras Error: {}", e),
- NoLoopbackNode(typ) => write!(f, "No loopback node found with type {:?}", typ),
- OpenFile(e) => write!(f, "Could not open WAV file for writing: {}", e),
- SampleBits(bits) => write!(
- f,
- "Sample size {} is not supported, only 8, 16, 24, and 32 bit samples are supported",
- bits
- ),
- SysUtil(e) => write!(f, "SysUtil Error: {}", e),
- }
- }
-}
-
-type Result<T> = std::result::Result<T, Error>;
-
-static INTERRUPTED: AtomicBool = AtomicBool::new(false);
-
-extern "C" fn sigint_handler(_: c_int) {
- // Check if we've already received one SIGINT. If we have, the program may
- // be misbehaving and not terminating, so to be safe we'll forcefully exit.
- if INTERRUPTED.load(Ordering::Acquire) {
- std::process::exit(1);
- }
- INTERRUPTED.store(true, Ordering::Release);
-}
-
-fn add_sigint_handler() -> Result<()> {
- const SIGINT: c_int = 2;
- let result = unsafe { register_signal_handler(SIGINT, sigint_handler) };
- result.map_err(Error::SysUtil)
-}
-
-fn set_priority_to_realtime() {
- const AUDIO_THREAD_RTPRIO: u16 = 10;
- if set_rt_prio_limit(AUDIO_THREAD_RTPRIO as u64).is_err()
- || set_rt_round_robin(AUDIO_THREAD_RTPRIO as i32).is_err()
- {
- println!("Attempt to use real-time priority failed, running with default scheduler.");
- }
-}
-
-fn channel_string(num_channels: usize) -> String {
- match num_channels {
- 1 => "Mono".to_string(),
- 2 => "Stereo".to_string(),
- _ => format!("{} Channels", num_channels),
- }
-}
-
-struct WavSource {
- wav_reader: WavReader<BufReader<File>>,
- format: SampleFormat,
- num_channels: usize,
- frame_rate: u32,
-}
-
-impl WavSource {
- fn try_new(opts: &AudioOptions) -> Result<Self> {
- let wav_reader = WavReader::open(&opts.file_name).map_err(Error::InvalidWavFile)?;
- let spec = wav_reader.spec();
- if spec.sample_format == hound::SampleFormat::Float {
- return Err(Error::FloatingPointSamples);
- }
-
- let format = match spec.bits_per_sample {
- 8 => SampleFormat::U8,
- 16 => SampleFormat::S16LE,
- 24 => SampleFormat::S24LE,
- 32 => SampleFormat::S32LE,
- s => return Err(Error::SampleBits(s)),
- };
- if opts.format.is_some() && Some(format) != opts.format {
- eprintln!("Warning: format changed to {:?}", format);
- }
-
- let num_channels = spec.channels as usize;
- if opts.num_channels.is_some() && Some(num_channels) != opts.num_channels {
- eprintln!("Warning: number of channels changed to {}", num_channels);
- }
-
- let frame_rate = spec.sample_rate;
- if opts.frame_rate.is_some() && Some(frame_rate) != opts.frame_rate {
- eprintln!("Warning: frame rate changed to {}", frame_rate);
- }
-
- Ok(Self {
- wav_reader,
- format,
- num_channels,
- frame_rate,
- })
- }
-
- fn format(&self) -> SampleFormat {
- self.format
- }
-
- fn num_channels(&self) -> usize {
- self.num_channels
- }
-
- fn frame_rate(&self) -> u32 {
- self.frame_rate
- }
-}
-
-impl Read for WavSource {
- fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
- let frame_size = self.format.sample_bytes() * self.num_channels;
- let read_len = buf.len() - buf.len() % frame_size;
- let num_samples = read_len / self.format.sample_bytes();
- let samples = self.wav_reader.samples::<i32>();
- let mut read = 0;
- for s in samples.take(num_samples) {
- match s {
- Ok(sample) => {
- let result = match self.format {
- SampleFormat::U8 => buf.write_all(&((sample + 128) as u8).to_le_bytes()),
- SampleFormat::S16LE => buf.write_all(&(sample as i16).to_le_bytes()),
- SampleFormat::S24LE | SampleFormat::S32LE => {
- buf.write_all(&sample.to_le_bytes())
- }
- };
-
- match result {
- Ok(()) => read += self.format.sample_bytes(),
- Err(_) => return Ok(read),
- };
- }
- Err(_) => return Ok(read),
- };
- }
- Ok(read)
- }
-}
-
-pub fn playback(opts: AudioOptions) -> Result<()> {
- let num_channels;
- let frame_rate;
- let format;
- let mut sample_source: Box<dyn Read> = match opts.file_type {
- FileType::Wav => {
- let wav_source = WavSource::try_new(&opts)?;
- num_channels = wav_source.num_channels();
- frame_rate = wav_source.frame_rate();
- format = wav_source.format();
- Box::new(wav_source)
- }
- FileType::Raw => {
- num_channels = opts.num_channels.unwrap_or(2);
- frame_rate = opts.frame_rate.unwrap_or(48000);
- format = opts.format.unwrap_or(SampleFormat::S16LE);
- Box::new(BufReader::new(
- File::open(&opts.file_name).map_err(Error::Io)?,
- ))
- }
- };
-
- println!(
- "Playing {} '{}' : {}, Rate {} Hz, {}",
- opts.file_type,
- opts.file_name.display(),
- format,
- frame_rate,
- channel_string(num_channels)
- );
-
- let mut cras_client = CrasClient::new().map_err(Error::Libcras)?;
- let (_control, mut stream) = cras_client
- .new_playback_stream(
- num_channels,
- format,
- frame_rate,
- opts.buffer_size.unwrap_or(256),
- )
- .map_err(Error::CreateStream)?;
- set_priority_to_realtime();
-
- add_sigint_handler()?;
- while !INTERRUPTED.load(Ordering::Acquire) {
- let mut buffer = stream.next_playback_buffer().map_err(Error::FetchStream)?;
-
- let frame_size = num_channels * format.sample_bytes();
- let frames = buffer.frame_capacity();
-
- let mut chunk = (&mut sample_source).take((frames * frame_size) as u64);
- let transferred = io::copy(&mut chunk, &mut buffer).map_err(Error::Io)?;
- if transferred == 0 {
- break;
- }
- }
- // Stream and client should gracefully be closed out of this scope
-
- Ok(())
-}
-
-struct WavSink {
- wav_writer: WavWriter<BufWriter<File>>,
- format: SampleFormat,
-}
-
-impl WavSink {
- fn try_new<P: AsRef<Path>>(
- path: P,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- ) -> Result<Self> {
- let spec = WavSpec {
- channels: num_channels as u16,
- sample_rate: frame_rate,
- bits_per_sample: (format.sample_bytes() * 8) as u16,
- sample_format: hound::SampleFormat::Int,
- };
- let wav_writer = WavWriter::create(path, spec).map_err(Error::OpenFile)?;
- Ok(Self { wav_writer, format })
- }
-}
-
-impl Write for WavSink {
- fn write(&mut self, samples: &[u8]) -> io::Result<usize> {
- let sample_bytes = self.format.sample_bytes();
- if samples.len() % sample_bytes != 0 {
- return Err(io::Error::new(
- io::ErrorKind::InvalidInput,
- format!(
- "u8 samples vector of length {} cannot be interpreted as {:?} samples",
- samples.len(),
- self.format
- ),
- ));
- }
- let num_samples = samples.len() / sample_bytes;
- match self.format {
- SampleFormat::U8 => {
- for sample in samples {
- self.wav_writer.write_sample(*sample as i8).map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("Failed to write sample: {}", e),
- )
- })?;
- }
- }
- SampleFormat::S16LE => {
- // hound offers an optimized i16 writer, so special case here.
- let mut writer = self.wav_writer.get_i16_writer(num_samples as u32);
- for i in 0..num_samples {
- let sample = i16::from_le_bytes([
- samples[sample_bytes * i],
- samples[sample_bytes * i + 1],
- ]);
- writer.write_sample(sample);
- }
- // I16Writer buffers internally and must be explicitly flushed to write
- // samples to the backing writer. Flush is not called automatically
- // on drop.
- // The flush method only writes data from the i16_writer to the underlying
- // WavWriter, it does not actually guarantee a flush to disk.
- writer.flush().map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("Failed to flush SampleWriter: {}", e),
- )
- })?;
- }
- SampleFormat::S24LE | SampleFormat::S32LE => {
- for i in 0..num_samples {
- let mut sample = i32::from_le_bytes([
- samples[sample_bytes * i],
- samples[sample_bytes * i + 1],
- samples[sample_bytes * i + 2],
- samples[sample_bytes * i + 3],
- ]);
-
- // Upsample to 32 bit since CRAS doesn't support S24_3LE.
- // Our wav encoder/decoder, hound, does have support for
- // S24_LE, but it hasn't released a new version since the
- // support was added. If getting that support is an issue,
- // push upstream to cut a new a release.
- if self.format == SampleFormat::S24LE {
- sample <<= 8;
- }
-
- self.wav_writer.write_sample(sample).map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("Failed to write sample: {}", e),
- )
- })?;
- }
- }
- }
-
- Ok(samples.len())
- }
-
- fn flush(&mut self) -> io::Result<()> {
- self.wav_writer.flush().map_err(|e| {
- io::Error::new(
- io::ErrorKind::Other,
- format!("Failed to flush WavWriter: {}", e),
- )
- })
- }
-}
-
-pub fn capture(opts: AudioOptions) -> Result<()> {
- let num_channels = opts.num_channels.unwrap_or(2);
- let format = opts.format.unwrap_or(SampleFormat::S16LE);
- let frame_rate = opts.frame_rate.unwrap_or(48000);
- let buffer_size = opts.buffer_size.unwrap_or(256);
-
- let mut sample_sink: Box<dyn Write> = match opts.file_type {
- FileType::Raw => Box::new(BufWriter::new(
- File::create(&opts.file_name).map_err(Error::Io)?,
- )),
- FileType::Wav => Box::new(WavSink::try_new(
- &opts.file_name,
- num_channels,
- format,
- frame_rate,
- )?),
- };
-
- println!(
- "Recording {} '{}' : {}, Rate {} Hz, {}",
- opts.file_type,
- opts.file_name.display(),
- format,
- frame_rate,
- channel_string(num_channels)
- );
-
- let mut cras_client = CrasClient::new().map_err(Error::Libcras)?;
- cras_client.enable_cras_capture();
- let (_control, mut stream) = match opts.loopback_type {
- Some(loopback_type) => {
- let node_type = match loopback_type {
- LoopbackType::PreDsp => CrasNodeType::CRAS_NODE_TYPE_POST_MIX_PRE_DSP,
- LoopbackType::PostDsp => CrasNodeType::CRAS_NODE_TYPE_POST_DSP,
- };
-
- let loopback_node = cras_client
- .input_nodes()
- .find(|node| node.node_type == node_type)
- .ok_or(Error::NoLoopbackNode(node_type))?;
-
- cras_client
- .new_pinned_capture_stream(
- loopback_node.iodev_index,
- num_channels,
- format,
- frame_rate,
- buffer_size,
- )
- .map_err(Error::CreateStream)?
- }
- None => cras_client
- .new_capture_stream(num_channels, format, frame_rate, buffer_size)
- .map_err(Error::CreateStream)?,
- };
- set_priority_to_realtime();
- add_sigint_handler()?;
- while !INTERRUPTED.load(Ordering::Acquire) {
- let mut buf = stream.next_capture_buffer().map_err(Error::FetchStream)?;
- io::copy(&mut buf, &mut sample_sink).map_err(Error::Io)?;
- }
- Ok(())
-}
diff --git a/cras/client/cras_tests/src/audio_options.rs b/cras/client/cras_tests/src/audio_options.rs
new file mode 100644
index 00000000..d71aac5b
--- /dev/null
+++ b/cras/client/cras_tests/src/audio_options.rs
@@ -0,0 +1,194 @@
+// Copyright 2019 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+use std::fmt;
+use std::io;
+use std::path::PathBuf;
+
+use getopts::Options;
+
+type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
+
+#[derive(Debug, PartialEq)]
+pub enum Subcommand {
+ Capture,
+ Playback,
+}
+
+impl fmt::Display for Subcommand {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Subcommand::Capture => write!(f, "capture"),
+ Subcommand::Playback => write!(f, "playback"),
+ }
+ }
+}
+
+fn show_usage<T: AsRef<str>>(program_name: T) {
+ println!(
+ "Usage: {} [subcommand] <subcommand args>",
+ program_name.as_ref()
+ );
+ println!("\nSubcommands:\n");
+ println!("capture - Capture to a file from CRAS");
+ println!("playback - Playback to CRAS from a file");
+ println!("\nhelp - Print help message");
+}
+
+fn show_subcommand_usage<T: AsRef<str>>(program_name: T, subcommand: &Subcommand, opts: &Options) {
+ let brief = format!(
+ "Usage: {} {} [options] [filename]",
+ program_name.as_ref(),
+ subcommand
+ );
+ print!("{}", opts.usage(&brief));
+}
+
+pub struct AudioOptions {
+ pub subcommand: Subcommand,
+ pub file_name: PathBuf,
+ pub buffer_size: Option<usize>,
+ pub num_channels: Option<usize>,
+ pub frame_rate: Option<usize>,
+}
+
+impl AudioOptions {
+ pub fn parse_from_args<T: AsRef<str>>(args: &[T]) -> Result<Option<Self>> {
+ let mut opts = Options::new();
+ opts.optopt("b", "buffer_size", "Buffer size in frames", "SIZE")
+ .optopt("c", "", "Number of channels", "NUM")
+ .optopt("r", "rate", "Audio frame rate (Hz)", "RATE")
+ .optflag("h", "help", "Print help message");
+
+ let mut args = args.into_iter().map(|s| s.as_ref());
+
+ let program_name = args.next().ok_or_else(|| {
+ Box::new(io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "Program name must be specified",
+ ))
+ })?;
+
+ let subcommand = match args.next() {
+ None => {
+ println!("Must specify a subcommand.");
+ show_usage(program_name);
+ return Err(Box::new(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "No subcommand",
+ )));
+ }
+ Some("help") => {
+ show_usage(&program_name);
+ return Ok(None);
+ }
+ Some("capture") => Subcommand::Capture,
+ Some("playback") => Subcommand::Playback,
+ Some(s) => {
+ println!("Subcommand \"{}\" does not exist.", s);
+ show_usage(&program_name);
+ return Err(Box::new(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "Subcommand does not exist",
+ )));
+ }
+ };
+
+ let matches = match opts.parse(args) {
+ Ok(m) => m,
+ Err(e) => {
+ show_subcommand_usage(&program_name, &subcommand, &opts);
+ return Err(Box::new(e));
+ }
+ };
+ if matches.opt_present("h") {
+ show_subcommand_usage(&program_name, &subcommand, &opts);
+ return Ok(None);
+ }
+ let file_name = match matches.free.get(0) {
+ None => {
+ println!("Must provide file name.");
+ show_subcommand_usage(&program_name, &subcommand, &opts);
+ return Err(Box::new(std::io::Error::new(
+ std::io::ErrorKind::InvalidInput,
+ "Must provide file name.",
+ )));
+ }
+ Some(file_name) => PathBuf::from(file_name),
+ };
+ let buffer_size = matches.opt_get::<usize>("b")?;
+ let num_channels = matches.opt_get::<usize>("c")?;
+ let frame_rate = matches.opt_get::<usize>("r")?;
+
+ Ok(Some(AudioOptions {
+ subcommand,
+ file_name,
+ buffer_size,
+ num_channels,
+ frame_rate,
+ }))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::ffi::OsString;
+
+ #[test]
+ fn parse_from_args() {
+ let opts = AudioOptions::parse_from_args(&["cras_tests", "playback", "output.wav"])
+ .unwrap()
+ .unwrap();
+ assert_eq!(opts.subcommand, Subcommand::Playback);
+ assert_eq!(opts.file_name, OsString::from("output.wav"));
+ assert_eq!(opts.frame_rate, None);
+ assert_eq!(opts.num_channels, None);
+ assert_eq!(opts.buffer_size, None);
+
+ let opts = AudioOptions::parse_from_args(&["cras_tests", "capture", "input.flac"])
+ .unwrap()
+ .unwrap();
+ assert_eq!(opts.subcommand, Subcommand::Capture);
+ assert_eq!(opts.file_name, OsString::from("input.flac"));
+ assert_eq!(opts.frame_rate, None);
+ assert_eq!(opts.num_channels, None);
+ assert_eq!(opts.buffer_size, None);
+
+ let opts = AudioOptions::parse_from_args(&[
+ "cras_tests",
+ "playback",
+ "-r",
+ "44100",
+ "output.wav",
+ "-c",
+ "2",
+ ])
+ .unwrap()
+ .unwrap();
+ assert_eq!(opts.subcommand, Subcommand::Playback);
+ assert_eq!(opts.file_name, OsString::from("output.wav"));
+ assert_eq!(opts.frame_rate, Some(44100));
+ assert_eq!(opts.num_channels, Some(2));
+ assert_eq!(opts.buffer_size, None);
+
+ assert!(AudioOptions::parse_from_args(&["cras_tests"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "capture"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "playback"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "loopback"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "loopback", "file.ogg"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "filename.wav"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "filename.wav", "capture"]).is_err());
+ assert!(AudioOptions::parse_from_args(&["cras_tests", "help"]).is_ok());
+ assert!(AudioOptions::parse_from_args(&[
+ "cras_tests",
+ "-c",
+ "2",
+ "playback",
+ "output.wav",
+ "-r",
+ "44100"
+ ])
+ .is_err());
+ }
+}
diff --git a/cras/client/cras_tests/src/control.rs b/cras/client/cras_tests/src/control.rs
deleted file mode 100644
index 3a98ec98..00000000
--- a/cras/client/cras_tests/src/control.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std::error;
-use std::fmt;
-
-use libcras::{AudioDebugInfo, CrasClient, CrasIonodeInfo};
-
-use crate::arguments::ControlCommand;
-
-/// An enumeration of errors that can occur when running `ControlCommand` using
-/// the `control()` function.
-#[derive(Debug)]
-pub enum Error {
- Libcras(libcras::Error),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- Libcras(e) => write!(f, "Libcras Error: {}", e),
- }
- }
-}
-
-type Result<T> = std::result::Result<T, Error>;
-
-fn print_nodes(nodes: impl Iterator<Item = CrasIonodeInfo>) {
- println!(
- "{: <13}{: <7}{: <6}{: <10}{: <13}{: <20} {: <10}",
- "Stable ID", "ID", "Vol", "Plugged", "Time", "Type", "Name"
- );
- for node in nodes {
- let id = format!("{}:{}", node.iodev_index, node.ionode_index);
- let stable_id = format!("({:08x})", node.stable_id);
- let plugged_time = node.plugged_time.tv_sec;
- let active = if node.active { "*" } else { " " };
- println!(
- "{: <13}{: <7}{: <6}{: <10}{: <13}{: <20}{}{: <10}",
- stable_id,
- id,
- node.volume,
- node.plugged,
- plugged_time,
- node.type_name,
- active,
- node.name
- );
- }
-}
-
-fn print_audio_debug_info(info: &AudioDebugInfo) {
- println!("Audio Debug Stats:");
- println!("-------------devices------------");
- for device in &info.devices {
- println!("{}", device);
- println!();
- }
-
- println!("-------------stream_dump------------");
- for stream in &info.streams {
- println!("{}", stream);
- println!();
- }
-}
-
-/// Connect to CRAS and run the given `ControlCommand`.
-pub fn control(command: ControlCommand) -> Result<()> {
- use ControlCommand::*;
- let mut cras_client = CrasClient::new().map_err(Error::Libcras)?;
- match command {
- GetSystemVolume => println!("{}", cras_client.get_system_volume()),
- SetSystemVolume(volume) => {
- cras_client
- .set_system_volume(volume)
- .map_err(Error::Libcras)?;
- }
- GetSystemMute => println!("{}", cras_client.get_system_mute()),
- SetSystemMute(mute) => {
- cras_client.set_system_mute(mute).map_err(Error::Libcras)?;
- }
- ListOutputDevices => {
- println!("{: <5}{: <10}", "ID", "Name");
- for dev in cras_client.output_devices() {
- println!("{: <5}{: <10}", dev.index, dev.name);
- }
- }
- ListInputDevices => {
- println!("{: <5}{: <10}", "ID", "Name");
- for dev in cras_client.input_devices() {
- println!("{: <5}{: <10}", dev.index, dev.name);
- }
- }
- ListOutputNodes => print_nodes(cras_client.output_nodes()),
- ListInputNodes => print_nodes(cras_client.input_nodes()),
- DumpAudioDebugInfo => {
- let debug_info = cras_client.get_audio_debug_info().map_err(Error::Libcras)?;
- print_audio_debug_info(&debug_info);
- }
- };
- Ok(())
-}
diff --git a/cras/client/cras_tests/src/main.rs b/cras/client/cras_tests/src/main.rs
index 50ffd090..97094042 100644
--- a/cras/client/cras_tests/src/main.rs
+++ b/cras/client/cras_tests/src/main.rs
@@ -2,57 +2,130 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-mod arguments;
-mod audio;
-mod control;
-
-use std::error;
-use std::fmt;
-
-use crate::arguments::Command;
-use crate::audio::{capture, playback};
-use crate::control::control;
-
-#[derive(Debug)]
-pub enum Error {
- Audio(audio::Error),
- ParseArgs(arguments::Error),
- Control(control::Error),
+mod audio_options;
+
+use std::fs::File;
+use std::io::{self, BufRead, BufReader, Write};
+use std::thread::spawn;
+use sys_util::{set_rt_prio_limit, set_rt_round_robin};
+type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
+
+use audio_streams::StreamSource;
+use libcras::CrasClient;
+
+use crate::audio_options::{AudioOptions, Subcommand};
+
+fn set_priority_to_realtime() {
+ const AUDIO_THREAD_RTPRIO: u16 = 10;
+ if set_rt_prio_limit(AUDIO_THREAD_RTPRIO as u64).is_err()
+ || set_rt_round_robin(AUDIO_THREAD_RTPRIO as i32).is_err()
+ {
+ println!("Attempt to use real-time priority failed, running with default scheduler.");
+ }
}
-impl error::Error for Error {}
+fn channel_string(num_channels: usize) -> String {
+ match num_channels {
+ 1 => "Mono".to_string(),
+ 2 => "Stereo".to_string(),
+ _ => format!("{} Channels", num_channels),
+ }
+}
+
+fn playback(opts: AudioOptions) -> Result<()> {
+ let file = File::open(&opts.file_name).expect("failed to open file");
+ let mut buffered_file = BufReader::new(file);
+
+ let num_channels = opts.num_channels.unwrap_or(2);
+ let frame_rate = opts.frame_rate.unwrap_or(48000);
+
+ println!(
+ "Playing raw data '{}' : Signed 16 bit Little Endian, Rate {} Hz, {}",
+ opts.file_name.display(),
+ frame_rate,
+ channel_string(num_channels)
+ );
+
+ let mut cras_client = CrasClient::new()?;
+ let (_control, mut stream) = cras_client.new_playback_stream(
+ num_channels,
+ frame_rate,
+ opts.buffer_size.unwrap_or(256),
+ )?;
+ let thread = spawn(move || {
+ set_priority_to_realtime();
+ loop {
+ let local_buffer = buffered_file
+ .fill_buf()
+ .expect("failed to read from input file");
+
+ // Reached EOF
+ if local_buffer.len() == 0 {
+ break;
+ }
+
+ // Gets writable buffer from stream
+ let mut buffer = stream
+ .next_playback_buffer()
+ .expect("failed to get next playback buffer");
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- Audio(e) => e.fmt(f),
- ParseArgs(e) => write!(f, "Failed to parse arguments: {}", e),
- Control(e) => e.fmt(f),
+ // Writes data to stream buffer
+ let write_frames = buffer
+ .write(&local_buffer)
+ .expect("failed to write output data to buffer");
+
+ // Mark the file data as written
+ buffered_file.consume(write_frames);
}
- }
+ });
+ thread.join().expect("Failed to join playback thread");
+ // Stream and client should gracefully be closed out of this scope
+
+ Ok(())
}
-type Result<T> = std::result::Result<T, Error>;
+fn capture(opts: AudioOptions) -> Result<()> {
+ let num_channels = opts.num_channels.unwrap_or(2);
+ let frame_rate = opts.frame_rate.unwrap_or(48000);
+
+ println!(
+ "Recording raw data '{}' : Signed 16 bit Little Endian, Rate {} Hz, {}",
+ opts.file_name.display(),
+ frame_rate,
+ channel_string(num_channels)
+ );
+
+ let mut cras_client = CrasClient::new()?;
+ cras_client.enable_cras_capture();
+ let (_control, mut stream) = cras_client.new_capture_stream(
+ num_channels,
+ frame_rate,
+ opts.buffer_size.unwrap_or(256),
+ )?;
+ let mut file = File::create(&opts.file_name).unwrap();
+ loop {
+ let _frames = match stream.next_capture_buffer() {
+ Err(e) => {
+ return Err(e.into());
+ }
+ Ok(mut buf) => {
+ let written = io::copy(&mut buf, &mut file)?;
+ written
+ }
+ };
+ }
+}
-fn run() -> Result<()> {
+fn main() -> Result<()> {
let args: Vec<String> = std::env::args().collect();
- let command = match Command::parse(&args).map_err(Error::ParseArgs)? {
+ let opts = match AudioOptions::parse_from_args(&args)? {
None => return Ok(()),
Some(v) => v,
};
- match command {
- Command::Capture(audio_opts) => capture(audio_opts).map_err(Error::Audio),
- Command::Control(command) => control(command).map_err(Error::Control),
- Command::Playback(audio_opts) => playback(audio_opts).map_err(Error::Audio),
- }
-}
-
-fn main() {
- // Use run() instead of returning a Result from main() so that we can print
- // errors using Display instead of Debug.
- if let Err(e) = run() {
- eprintln!("{}", e);
- }
+ match opts.subcommand {
+ Subcommand::Capture => capture(opts)?,
+ Subcommand::Playback => playback(opts)?,
+ };
+ Ok(())
}
diff --git a/cras/client/libcras/.gitignore b/cras/client/libcras/.gitignore
index fa8d85ac..41cebfd4 100644
--- a/cras/client/libcras/.gitignore
+++ b/cras/client/libcras/.gitignore
@@ -1,2 +1,3 @@
-Cargo.lock
-target
+target/
+.rustfmt.toml
+.*.rustfmt.toml
diff --git a/cras/client/libcras/Android.bp b/cras/client/libcras/Android.bp
index aecb27a2..33c4ddb1 100644
--- a/cras/client/libcras/Android.bp
+++ b/cras/client/libcras/Android.bp
@@ -1,23 +1,15 @@
-// This file is generated by cargo2android.py --run --device --test --global_defaults=crosvm_defaults --dependencies.
+// This file is generated by cargo2android.py, added defaults.
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_adhd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-BSD
- default_applicable_licenses: ["external_adhd_license"],
-}
-
-rust_defaults {
- name: "libcras_defaults",
+rust_test_host {
+ name: "libcras_tests_libcras",
defaults: ["crosvm_defaults"],
+ deny_warnings: false,
crate_name: "libcras",
srcs: ["src/libcras.rs"],
+ relative_install_path: "libcras_tests",
test_suites: ["general-tests"],
auto_gen_config: true,
- edition: "2018",
- rustlibs: [
+ rlibs: [
"libaudio_streams",
"libcras_sys",
"libdata_model",
@@ -26,24 +18,13 @@ rust_defaults {
],
}
-rust_test_host {
- name: "libcras_host_test_src_libcras",
- defaults: ["libcras_defaults"],
-}
-
-rust_test {
- name: "libcras_device_test_src_libcras",
- defaults: ["libcras_defaults"],
-}
-
-rust_library {
+rust_library_host_rlib {
name: "liblibcras",
defaults: ["crosvm_defaults"],
- host_supported: true,
+ deny_warnings: false,
crate_name: "libcras",
srcs: ["src/libcras.rs"],
- edition: "2018",
- rustlibs: [
+ rlibs: [
"libaudio_streams",
"libcras_sys",
"libdata_model",
@@ -51,19 +32,3 @@ rust_library {
"libsys_util",
],
}
-
-// dependent_library ["feature_list"]
-// ../../../../crosvm/assertions/src/lib.rs
-// ../../../../crosvm/data_model/src/lib.rs
-// ../../../../crosvm/sync/src/lib.rs
-// ../../../../crosvm/sys_util/poll_token_derive/poll_token_derive.rs
-// ../../../../crosvm/sys_util/src/lib.rs
-// ../../../../crosvm/syscall_defines/src/lib.rs
-// ../../../../crosvm/tempfile/src/lib.rs
-// ../../../audio_streams/src/audio_streams.rs
-// ../cras-sys/src/lib.rs
-// libc-0.2.76 "default,std"
-// proc-macro2-1.0.19 "default,proc-macro"
-// quote-1.0.7 "default,proc-macro"
-// syn-1.0.39 "clone-impls,default,derive,parsing,printing,proc-macro,quote"
-// unicode-xid-0.2.1 "default"
diff --git a/cras/client/libcras/Cargo.toml b/cras/client/libcras/Cargo.toml
index b52a2612..cc2a3e13 100644
--- a/cras/client/libcras/Cargo.toml
+++ b/cras/client/libcras/Cargo.toml
@@ -11,5 +11,5 @@ path = "src/libcras.rs"
audio_streams = { path = "../../../audio_streams" } # provided by ebuild
libc = "*"
cras-sys = { path = "../cras-sys" } # provided by ebuild
-data_model = { path = "../../../../crosvm/data_model" } # provided by ebuild
-sys_util = { path = "../../../../crosvm/sys_util" } # provided by ebuild
+data_model = { path = "../../../../../platform/crosvm/data_model" } # provided by ebuild
+sys_util = { path = "../../../../../platform/crosvm/sys_util" } # provided by ebuild
diff --git a/cras/client/libcras/src/cras_client_message.rs b/cras/client/libcras/src/cras_client_message.rs
index c1c5ec5c..0921c5f2 100644
--- a/cras/client/libcras/src/cras_client_message.rs
+++ b/cras/client/libcras/src/cras_client_message.rs
@@ -16,7 +16,7 @@ use crate::cras_shm::*;
use crate::cras_stream;
#[derive(Debug)]
-pub enum Error {
+enum ErrorType {
IoError(io::Error),
SysUtilError(sys_util::Error),
CrasStreamError(cras_stream::Error),
@@ -29,21 +29,32 @@ pub enum Error {
MessageFromSliceError,
}
+#[derive(Debug)]
+pub struct Error {
+ error_type: ErrorType,
+}
+
+impl Error {
+ fn new(error_type: ErrorType) -> Error {
+ Error { error_type }
+ }
+}
+
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Error::IoError(ref err) => err.fmt(f),
- Error::SysUtilError(ref err) => err.fmt(f),
- Error::MessageTypeError => write!(f, "Message type error"),
- Error::CrasStreamError(ref err) => err.fmt(f),
- Error::ArrayTryFromSliceError(ref err) => err.fmt(f),
- Error::MessageNumFdError => write!(f, "Message the number of fds is not matched"),
- Error::MessageTruncated => write!(f, "Read truncated message"),
- Error::MessageIdError => write!(f, "No such id"),
- Error::MessageFromSliceError => write!(f, "Message from slice error"),
- Error::InvalidSize => write!(f, "Invalid data size"),
+ match self.error_type {
+ ErrorType::IoError(ref err) => err.fmt(f),
+ ErrorType::SysUtilError(ref err) => err.fmt(f),
+ ErrorType::MessageTypeError => write!(f, "Message type error"),
+ ErrorType::CrasStreamError(ref err) => err.fmt(f),
+ ErrorType::ArrayTryFromSliceError(ref err) => err.fmt(f),
+ ErrorType::MessageNumFdError => write!(f, "Message the number of fds is not matched"),
+ ErrorType::MessageTruncated => write!(f, "Read truncated message"),
+ ErrorType::MessageIdError => write!(f, "No such id"),
+ ErrorType::MessageFromSliceError => write!(f, "Message from slice error"),
+ ErrorType::InvalidSize => write!(f, "Invalid data size"),
}
}
}
@@ -52,25 +63,25 @@ type Result<T> = std::result::Result<T, Error>;
impl From<io::Error> for Error {
fn from(io_err: io::Error) -> Self {
- Error::IoError(io_err)
+ Self::new(ErrorType::IoError(io_err))
}
}
impl From<sys_util::Error> for Error {
fn from(sys_util_err: sys_util::Error) -> Self {
- Error::SysUtilError(sys_util_err)
+ Self::new(ErrorType::SysUtilError(sys_util_err))
}
}
impl From<cras_stream::Error> for Error {
fn from(err: cras_stream::Error) -> Self {
- Error::CrasStreamError(err)
+ Self::new(ErrorType::CrasStreamError(err))
}
}
impl From<TryFromSliceError> for Error {
fn from(err: TryFromSliceError) -> Self {
- Error::ArrayTryFromSliceError(err)
+ Self::new(ErrorType::ArrayTryFromSliceError(err))
}
}
@@ -80,7 +91,6 @@ pub enum ServerResult {
Connected(u32, CrasServerStateShmFd),
/// stream_id, header_fd, samples_fd
StreamConnected(u32, CrasAudioShmHeaderFd, CrasShmFd),
- DebugInfoReady,
}
impl ServerResult {
@@ -112,10 +122,7 @@ impl ServerResult {
unsafe { CrasShmFd::new(message.fds[1], cmsg.samples_shm_size as usize) },
))
}
- CRAS_CLIENT_MESSAGE_ID::CRAS_CLIENT_AUDIO_DEBUG_INFO_READY => {
- Ok(ServerResult::DebugInfoReady)
- }
- _ => Err(Error::MessageTypeError),
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
}
}
}
@@ -147,7 +154,7 @@ impl CrasClientMessage {
let (len, fd_nums) = server_socket.recv_with_fds(&mut message.data, &mut message.fds)?;
if len < mem::size_of::<cras_client_message>() {
- Err(Error::MessageTruncated)
+ Err(Error::new(ErrorType::MessageTruncated))
} else {
message.len = len;
message.check_fd_nums(fd_nums)?;
@@ -160,20 +167,16 @@ impl CrasClientMessage {
match self.get_id()? {
CRAS_CLIENT_CONNECTED => match fd_nums {
1 => Ok(()),
- _ => Err(Error::MessageNumFdError),
+ _ => Err(Error::new(ErrorType::MessageNumFdError)),
},
CRAS_CLIENT_STREAM_CONNECTED => match fd_nums {
// CRAS should return two shared memory areas the first which has
// mem::size_of::<cras_audio_shm_header>() bytes, and the second which has
// `samples_shm_size` bytes.
2 => Ok(()),
- _ => Err(Error::MessageNumFdError),
+ _ => Err(Error::new(ErrorType::MessageNumFdError)),
},
- CRAS_CLIENT_AUDIO_DEBUG_INFO_READY => match fd_nums {
- 0 => Ok(()),
- _ => Err(Error::MessageNumFdError),
- },
- _ => Err(Error::MessageTypeError),
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
}
}
@@ -183,18 +186,16 @@ impl CrasClientMessage {
match u32::from_le_bytes(self.data[offset..offset + 4].try_into()?) {
id if id == (CRAS_CLIENT_CONNECTED as u32) => Ok(CRAS_CLIENT_CONNECTED),
id if id == (CRAS_CLIENT_STREAM_CONNECTED as u32) => Ok(CRAS_CLIENT_STREAM_CONNECTED),
- id if id == (CRAS_CLIENT_AUDIO_DEBUG_INFO_READY as u32) => {
- Ok(CRAS_CLIENT_AUDIO_DEBUG_INFO_READY)
- }
- _ => Err(Error::MessageIdError),
+ _ => Err(Error::new(ErrorType::MessageIdError)),
}
}
// Gets a reference to the message content
fn get_message<T: DataInit>(&self) -> Result<&T> {
if self.len != mem::size_of::<T>() {
- return Err(Error::InvalidSize);
+ return Err(Error::new(ErrorType::InvalidSize));
}
- T::from_slice(&self.data[..mem::size_of::<T>()]).ok_or(Error::MessageFromSliceError)
+ T::from_slice(&self.data[..mem::size_of::<T>()])
+ .ok_or_else(|| Error::new(ErrorType::MessageFromSliceError))
}
}
diff --git a/cras/client/libcras/src/cras_server_socket.rs b/cras/client/libcras/src/cras_server_socket.rs
index 4a7d9151..139382a8 100644
--- a/cras/client/libcras/src/cras_server_socket.rs
+++ b/cras/client/libcras/src/cras_server_socket.rs
@@ -1,31 +1,14 @@
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+use std::io;
use std::os::unix::io::{AsRawFd, RawFd};
-use std::{io, mem};
-use cras_sys::gen::{cras_disconnect_stream_message, cras_server_message, CRAS_SERVER_MESSAGE_ID};
use sys_util::{net::UnixSeqpacket, ScmSocket};
use data_model::DataInit;
-/// Server socket type to connect.
-pub enum CrasSocketType {
- /// A server socket type supports only playback function.
- Legacy,
- /// A server socket type supports both playback and capture functions.
- Unified,
-}
-
-impl CrasSocketType {
- fn sock_path(&self) -> &str {
- match self {
- Self::Legacy => "/run/cras/.cras_socket",
- Self::Unified => "/run/cras/.cras_unified",
- }
- }
-}
-
+const CRAS_SERVER_SOCKET_PATH: &str = "/run/cras/.cras_socket";
/// A socket connecting to the CRAS audio server.
pub struct CrasServerSocket {
socket: UnixSeqpacket,
@@ -33,18 +16,8 @@ pub struct CrasServerSocket {
impl CrasServerSocket {
pub fn new() -> io::Result<CrasServerSocket> {
- Self::with_type(CrasSocketType::Legacy)
- }
-
- /// Creates a `CrasServerSocket` with given `CrasSocketType`.
- ///
- /// # Errors
- ///
- /// Returns the `io::Error` generated when connecting to the socket on failure.
- pub fn with_type(socket_type: CrasSocketType) -> io::Result<CrasServerSocket> {
- Ok(CrasServerSocket {
- socket: UnixSeqpacket::connect(socket_type.sock_path())?,
- })
+ let socket = UnixSeqpacket::connect(CRAS_SERVER_SOCKET_PATH)?;
+ Ok(CrasServerSocket { socket })
}
/// Sends a sized and packed server messge to the server socket. The message
@@ -65,13 +38,10 @@ impl CrasServerSocket {
) -> io::Result<usize> {
match fds.len() {
0 => self.socket.send(message.as_slice()),
- _ => {
- let ioslice = io::IoSlice::new(message.as_slice());
- match self.send_with_fds(&[ioslice], fds) {
- Ok(len) => Ok(len),
- Err(err) => Err(io::Error::new(io::ErrorKind::Other, format!("{}", err))),
- }
- }
+ _ => match self.send_with_fds(message.as_slice(), fds) {
+ Ok(len) => Ok(len),
+ Err(err) => Err(io::Error::new(io::ErrorKind::Other, format!("{}", err))),
+ },
}
}
@@ -81,32 +51,6 @@ impl CrasServerSocket {
let new_sock = self.socket.try_clone()?;
Ok(CrasServerSocket { socket: new_sock })
}
-
- /// Send a message to request disconnection of the given stream.
- ///
- /// Builds a `cras_disconnect_stream_message` containing `stream_id` and
- /// sends it to the server.
- /// No response is expected.
- ///
- /// # Arguments
- ///
- /// * `stream_id` - The id of the stream that should be disconnected.
- ///
- /// # Errors
- ///
- /// * If the message was not written to the server socket successfully.
- pub fn disconnect_stream(&self, stream_id: u32) -> io::Result<()> {
- let msg_header = cras_server_message {
- length: mem::size_of::<cras_disconnect_stream_message>() as u32,
- id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DISCONNECT_STREAM,
- };
- let server_cmsg = cras_disconnect_stream_message {
- header: msg_header,
- stream_id,
- };
- self.send_server_message_with_fds(&server_cmsg, &[])
- .map(|_| ())
- }
}
// For using `recv_with_fds` and `send_with_fds`.
diff --git a/cras/client/libcras/src/cras_shm.rs b/cras/client/libcras/src/cras_shm.rs
index 05533753..55474976 100644
--- a/cras/client/libcras/src/cras_shm.rs
+++ b/cras/client/libcras/src/cras_shm.rs
@@ -1,26 +1,19 @@
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-use std::convert::TryFrom;
use std::io;
use std::mem;
use std::os::unix::io::{AsRawFd, RawFd};
use std::ptr;
use std::ptr::NonNull;
use std::slice;
-use std::sync::atomic::{self, Ordering};
-use std::thread;
+
+use libc;
use cras_sys::gen::{
- audio_dev_debug_info, audio_stream_debug_info, cras_audio_shm_header, cras_iodev_info,
- cras_ionode_info, cras_server_state, CRAS_MAX_IODEVS, CRAS_MAX_IONODES, CRAS_NUM_SHM_BUFFERS,
- CRAS_SERVER_STATE_VERSION, CRAS_SHM_BUFFERS_MASK, MAX_DEBUG_DEVS, MAX_DEBUG_STREAMS,
-};
-use cras_sys::{
- AudioDebugInfo, AudioDevDebugInfo, AudioStreamDebugInfo, CrasIodevInfo, CrasIonodeInfo,
+ cras_audio_shm_header, cras_server_state, CRAS_NUM_SHM_BUFFERS, CRAS_SHM_BUFFERS_MASK,
};
-use data_model::{VolatileRef, VolatileSlice};
-use sys_util::warn;
+use data_model::VolatileRef;
/// A structure wrapping a fd which contains a shared `cras_audio_shm_header`.
/// * `shm_fd` - A shared memory fd contains a `cras_audio_shm_header`
@@ -52,6 +45,7 @@ impl CrasAudioShmHeaderFd {
/// A wrapper for the raw structure `cras_audio_shm_header` with
/// size information for the separate audio samples shm area and several
/// `VolatileRef` to sub fields for safe access to the header.
+#[allow(dead_code)]
pub struct CrasAudioHeader<'a> {
addr: *mut libc::c_void,
/// Size of the buffer for samples in CrasAudioBuffer
@@ -62,7 +56,7 @@ pub struct CrasAudioHeader<'a> {
write_buf_idx: VolatileRef<'a, u32>,
read_offset: [VolatileRef<'a, u32>; CRAS_NUM_SHM_BUFFERS as usize],
write_offset: [VolatileRef<'a, u32>; CRAS_NUM_SHM_BUFFERS as usize],
- buffer_offset: [VolatileRef<'a, u64>; CRAS_NUM_SHM_BUFFERS as usize],
+ buffer_offset: [VolatileRef<'a, u32>; CRAS_NUM_SHM_BUFFERS as usize],
}
// It is safe to send audio buffers between threads as this struct has exclusive ownership of the
@@ -232,13 +226,8 @@ impl<'a> CrasAudioHeader<'a> {
self.frame_size.load() as usize
}
- /// Gets the max size in bytes of each shared memory buffer within
- /// the samples area.
- ///
- /// # Returns
- ///
- /// * `usize` - Value of `used_size` fetched from the shared memory header.
- pub fn get_used_size(&self) -> usize {
+ /// Gets the size in bytes of the shared memory buffer.
+ fn get_used_size(&self) -> usize {
self.used_size.load() as usize
}
@@ -310,7 +299,7 @@ impl<'a> CrasAudioHeader<'a> {
Ok(())
}
- /// Sets `read_offset[idx]` to count of written bytes.
+ /// Sets `read_offset[idx]` of to count of written bytes.
///
/// # Arguments
/// `idx` - 0 <= `idx` < `CRAS_NUM_SHM_BUFFERS`
@@ -345,23 +334,13 @@ impl<'a> CrasAudioHeader<'a> {
.load() as usize;
let other_end = other_start + self.buffer_len_from_offset(other_start)?;
if start < other_end && other_start < end {
- // Special case: occasionally we get the same buffer offset twice
- // from the intel8x0 kernel driver in crosvm's AC97 device, and we
- // don't want to crash in that case.
- if start == other_start && end == other_end {
- warn!(
- "Setting buffer {} to same index/offset as buffer {}, [{}, {})",
- idx, other_idx, other_start, other_end
- );
- } else {
- return Err(io::Error::new(
- io::ErrorKind::InvalidInput,
- format!(
- "Setting buffer {} to [{}, {}) overlaps buffer {} at [{}, {})",
- idx, start, end, other_idx, other_start, other_end,
- ),
- ));
- }
+ return Err(io::Error::new(
+ io::ErrorKind::InvalidInput,
+ format!(
+ "Setting buffer {} to [{}, {}) overlaps buffer {} at [{}, {})",
+ idx, start, end, other_idx, other_start, other_end,
+ ),
+ ));
}
Ok(())
}
@@ -381,11 +360,11 @@ impl<'a> CrasAudioHeader<'a> {
/// * overlaps some other buffer `[other_offset, other_offset + used_size)`
/// * is close enough to the end of the samples area that the buffer would
/// be shorter than `frame_size`.
- pub fn set_buffer_offset(&mut self, idx: usize, offset: usize) -> io::Result<()> {
+ fn set_buffer_offset(&mut self, idx: usize, offset: usize) -> io::Result<()> {
self.check_buffer_offset(idx, offset)?;
let buffer_offset = self.buffer_offset.get(idx).ok_or_else(index_out_of_range)?;
- buffer_offset.store(offset as u64);
+ buffer_offset.store(offset as u32);
Ok(())
}
@@ -520,252 +499,45 @@ unsafe fn cras_mmap(
cras_mmap_offset(len, prot, fd, 0)
}
-/// An unsafe macro for getting a `VolatileSlice` representing an entire array
-/// field from a given NonNull pointer.
-///
-/// To use this macro safely, we need to
-/// - Make sure the pointer address is readable and writeable for its struct.
-/// - Make sure all `VolatileSlice`s generated from this macro have exclusive ownership for the same
-/// pointer.
-/// - Make sure the length of the array field is non-zero.
-#[macro_export]
-macro_rules! vslice_from_addr {
- ($addr:ident, $($field:ident).*) => {{
- let ptr = &mut $addr.as_mut().$($field).* as *mut _ as *mut u8;
- let size = std::mem::size_of_val(&$addr.as_mut().$($field).*);
- VolatileSlice::from_raw_parts(ptr, size)
- }};
-}
-
/// A structure that points to RO shared memory area - `cras_server_state`
/// The structure is created from a shared memory fd which contains the structure.
-#[derive(Debug)]
-pub struct CrasServerState<'a> {
+#[allow(dead_code)]
+pub struct CrasServerState {
addr: *mut libc::c_void,
- volume: VolatileRef<'a, u32>,
- mute: VolatileRef<'a, i32>,
- num_output_devs: VolatileRef<'a, u32>,
- output_devs: VolatileSlice<'a>,
- num_input_devs: VolatileRef<'a, u32>,
- input_devs: VolatileSlice<'a>,
- num_output_nodes: VolatileRef<'a, u32>,
- num_input_nodes: VolatileRef<'a, u32>,
- output_nodes: VolatileSlice<'a>,
- input_nodes: VolatileSlice<'a>,
- update_count: VolatileRef<'a, u32>,
- debug_info_num_devs: VolatileRef<'a, u32>,
- debug_info_devs: VolatileSlice<'a>,
- debug_info_num_streams: VolatileRef<'a, u32>,
- debug_info_streams: VolatileSlice<'a>,
+ size: usize,
}
-// It is safe to send server_state between threads as this struct has exclusive
-// ownership of the shared memory area contained in it.
-unsafe impl<'a> Send for CrasServerState<'a> {}
-
-impl<'a> CrasServerState<'a> {
- /// Create a CrasServerState
- pub fn try_new(state_fd: CrasServerStateShmFd) -> io::Result<Self> {
- // Safe because the creator of CrasServerStateShmFd already
- // ensured that state_fd contains a cras_server_state.
- let mmap_addr =
- unsafe { cras_mmap(state_fd.fd.size, libc::PROT_READ, state_fd.fd.as_raw_fd())? };
-
- let mut addr = NonNull::new(mmap_addr as *mut cras_server_state).ok_or_else(|| {
- io::Error::new(io::ErrorKind::Other, "Failed to create CrasServerState.")
- })?;
-
- // Safe because we know that addr is a non-null pointer to cras_server_state.
- let state_version = unsafe { vref_from_addr!(addr, state_version) };
- if state_version.load() != CRAS_SERVER_STATE_VERSION {
- return Err(io::Error::new(
- io::ErrorKind::Other,
- format!(
- "CrasServerState version {} does not match expected version {}",
- state_version.load(),
- CRAS_SERVER_STATE_VERSION
- ),
- ));
- }
-
- // Safe because we know that mmap_addr (contained in addr) contains a
- // cras_server_state, and the mapped area will be exclusively
- // owned by this struct.
- unsafe {
- Ok(CrasServerState {
- addr: addr.as_ptr() as *mut libc::c_void,
- volume: vref_from_addr!(addr, volume),
- mute: vref_from_addr!(addr, mute),
- num_output_devs: vref_from_addr!(addr, num_output_devs),
- num_input_devs: vref_from_addr!(addr, num_input_devs),
- output_devs: vslice_from_addr!(addr, output_devs),
- input_devs: vslice_from_addr!(addr, input_devs),
- num_output_nodes: vref_from_addr!(addr, num_output_nodes),
- num_input_nodes: vref_from_addr!(addr, num_input_nodes),
- output_nodes: vslice_from_addr!(addr, output_nodes),
- input_nodes: vslice_from_addr!(addr, input_nodes),
- update_count: vref_from_addr!(addr, update_count),
- debug_info_num_devs: vref_from_addr!(addr, audio_debug_info.num_devs),
- debug_info_devs: vslice_from_addr!(addr, audio_debug_info.devs),
- debug_info_num_streams: vref_from_addr!(addr, audio_debug_info.num_streams),
- debug_info_streams: vslice_from_addr!(addr, audio_debug_info.streams),
- })
- }
- }
-
- /// Gets the system volume.
- ///
- /// Read the current value for system volume from shared memory.
- pub fn get_system_volume(&self) -> u32 {
- self.volume.load()
- }
-
- /// Gets the system mute.
- ///
- /// Read the current value for system mute from shared memory.
- pub fn get_system_mute(&self) -> bool {
- self.mute.load() != 0
- }
-
- /// Runs a closure safely such that it can be sure that the server state
- /// was not updated during the read.
- /// This can be used for an "atomic" read of non-atomic data from the
- /// state shared memory.
- fn synchronized_state_read<F, T>(&self, mut func: F) -> T
- where
- F: FnMut() -> T,
- {
- // Waits until the server has completed a state update before returning
- // the current update count.
- let begin_server_state_read = || -> u32 {
- loop {
- let update_count = self.update_count.load();
- if update_count % 2 == 0 {
- atomic::fence(Ordering::Acquire);
- return update_count;
- } else {
- thread::yield_now();
- }
- }
- };
-
- // Checks that the update count has not changed since the start
- // of the server state read.
- let end_server_state_read = |count: u32| -> bool {
- let result = count == self.update_count.load();
- atomic::fence(Ordering::Release);
- result
- };
-
- // Get the state's update count and run the provided closure.
- // If the update count has not changed once the closure is finished,
- // return the result, otherwise repeat the process.
- loop {
- let update_count = begin_server_state_read();
- let result = func();
- if end_server_state_read(update_count) {
- return result;
- }
+impl CrasServerState {
+ /// An unsafe function for creating `CrasServerState`. To use this function safely, we need to
+ /// - Make sure that the `shm_fd` must come from the server's message that provides the shared
+ /// memory region. The Id for the message is `CRAS_CLIENT_MESSAGE_ID::CRAS_CLIENT_CONNECTED`.
+ #[allow(dead_code)]
+ pub unsafe fn new(shm_fd: CrasShmFd) -> io::Result<Self> {
+ let size = mem::size_of::<cras_server_state>();
+ if size > shm_fd.size {
+ Err(io::Error::new(
+ io::ErrorKind::InvalidInput,
+ "Invalid shared memory size.",
+ ))
+ } else {
+ let addr = cras_mmap(size, libc::PROT_READ, shm_fd.as_raw_fd())?;
+ Ok(CrasServerState { addr, size })
}
}
- /// Gets a list of output devices
- ///
- /// Read a list of the currently attached output devices from shared memory.
- pub fn output_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
- let mut devs: Vec<cras_iodev_info> = vec![Default::default(); CRAS_MAX_IODEVS as usize];
- let num_devs = self.synchronized_state_read(|| {
- self.output_devs.copy_to(&mut devs);
- self.num_output_devs.load()
- });
- devs.into_iter()
- .take(num_devs as usize)
- .map(CrasIodevInfo::from)
- }
-
- /// Gets a list of input devices
- ///
- /// Read a list of the currently attached input devices from shared memory.
- pub fn input_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
- let mut devs: Vec<cras_iodev_info> = vec![Default::default(); CRAS_MAX_IODEVS as usize];
- let num_devs = self.synchronized_state_read(|| {
- self.input_devs.copy_to(&mut devs);
- self.num_input_devs.load()
- });
- devs.into_iter()
- .take(num_devs as usize)
- .map(CrasIodevInfo::from)
- }
-
- /// Gets a list of output nodes
- ///
- /// Read a list of the currently attached output nodes from shared memory.
- pub fn output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
- let mut nodes: Vec<cras_ionode_info> = vec![Default::default(); CRAS_MAX_IONODES as usize];
- let num_nodes = self.synchronized_state_read(|| {
- self.output_nodes.copy_to(&mut nodes);
- self.num_output_nodes.load()
- });
- nodes
- .into_iter()
- .take(num_nodes as usize)
- .map(CrasIonodeInfo::from)
- }
-
- /// Gets a list of input nodes
- ///
- /// Read a list of the currently attached input nodes from shared memory.
- pub fn input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
- let mut nodes: Vec<cras_ionode_info> = vec![Default::default(); CRAS_MAX_IONODES as usize];
- let num_nodes = self.synchronized_state_read(|| {
- self.input_nodes.copy_to(&mut nodes);
- self.num_input_nodes.load()
- });
- nodes
- .into_iter()
- .take(num_nodes as usize)
- .map(CrasIonodeInfo::from)
- }
-
- /// Get audio debug info
- ///
- /// Loads the server's audio_debug_info struct and converts it into an
- /// idiomatic rust representation.
- ///
- /// # Errors
- /// * If any of the stream debug information structs are invalid.
- pub fn get_audio_debug_info(&self) -> Result<AudioDebugInfo, cras_sys::Error> {
- let mut devs: Vec<audio_dev_debug_info> = vec![Default::default(); MAX_DEBUG_DEVS as usize];
- let mut streams: Vec<audio_stream_debug_info> =
- vec![Default::default(); MAX_DEBUG_STREAMS as usize];
- let (num_devs, num_streams) = self.synchronized_state_read(|| {
- self.debug_info_devs.copy_to(&mut devs);
- self.debug_info_streams.copy_to(&mut streams);
- (
- self.debug_info_num_devs.load(),
- self.debug_info_num_streams.load(),
- )
- });
- let dev_info = devs
- .into_iter()
- .take(num_devs as usize)
- .map(AudioDevDebugInfo::from)
- .collect();
- let stream_info = streams
- .into_iter()
- .take(num_streams as usize)
- .map(AudioStreamDebugInfo::try_from)
- .collect::<Result<Vec<_>, _>>()?;
- Ok(AudioDebugInfo::new(dev_info, stream_info))
+ // Gets `cras_server_state` reference from the structure.
+ #[allow(dead_code)]
+ fn get_ref(&self) -> VolatileRef<cras_server_state> {
+ unsafe { VolatileRef::new(self.addr as *mut _) }
}
}
-impl<'a> Drop for CrasServerState<'a> {
+impl Drop for CrasServerState {
/// Call `munmap` for `addr`.
fn drop(&mut self) {
unsafe {
// Safe because all references must be gone by the time drop is called.
- libc::munmap(self.addr, mem::size_of::<cras_server_state>());
+ libc::munmap(self.addr, self.size);
}
}
}
@@ -830,16 +602,6 @@ pub fn create_header_and_buffers<'a>(
Ok((header, buffer))
}
-/// Creates header from header shared memory fds. Use this function
-/// when mapping the samples shm is not necessary, for instance with a
-/// client-provided shm stream.
-pub fn create_header<'a>(
- header_fd: CrasAudioShmHeaderFd,
- samples_len: usize,
-) -> io::Result<CrasAudioHeader<'a>> {
- Ok(CrasAudioHeader::new(header_fd, samples_len)?)
-}
-
/// A structure wrapping a fd which contains a shared memory area and its size.
/// * `fd` - The shared memory file descriptor, a `libc::c_int`.
/// * `size` - Size of the shared memory area.
@@ -888,7 +650,8 @@ impl Drop for CrasShmFd {
/// A structure wrapping a fd which contains a shared `cras_server_state`.
/// * `shm_fd` - A shared memory fd contains a `cras_server_state`
pub struct CrasServerStateShmFd {
- fd: CrasShmFd,
+ #[allow(dead_code)]
+ shm_fd: CrasShmFd,
}
impl CrasServerStateShmFd {
@@ -907,7 +670,7 @@ impl CrasServerStateShmFd {
/// - The shared memory area in the input fd contains a `cras_server_state`.
pub unsafe fn new(fd: libc::c_int) -> Self {
Self {
- fd: CrasShmFd::new(fd, mem::size_of::<cras_server_state>()),
+ shm_fd: CrasShmFd::new(fd, mem::size_of::<cras_server_state>()),
}
}
}
@@ -917,8 +680,6 @@ mod tests {
use super::*;
use std::fs::File;
use std::os::unix::io::IntoRawFd;
- use std::sync::{Arc, Mutex};
- use std::thread;
use sys_util::{kernel_has_memfd, SharedMemory};
#[test]
@@ -1124,16 +885,13 @@ mod tests {
header.write_offset[1].store(0);
header.buffer_offset[1].store(10);
- // Setting buffer_offset to exactly overlap with other buffer is okay
- assert!(header.set_buffer_offset(0, 10).is_ok());
-
- // Setting buffer_offset to partially overlap other buffer is not okay
- assert!(header.set_buffer_offset(0, 9).is_err());
+ // Setting buffer_offset to overlap with other buffer is not okay
+ assert!(header.set_buffer_offset(0, 10).is_err());
header.buffer_offset[0].store(0);
header.write_offset[1].store(8);
// With samples, it's still an error.
- assert!(header.set_buffer_offset(0, 9).is_err());
+ assert!(header.set_buffer_offset(0, 10).is_err());
// Setting the offset past the end of the other buffer is okay
assert!(header.set_buffer_offset(0, 20).is_ok());
@@ -1148,9 +906,9 @@ mod tests {
assert!(header.set_buffer_offset(0, 30).is_err());
// If we try to overlap another buffer with that other buffer at the end,
- // it's not okay, unless it's the exact same index.
+ // it's not okay.
assert!(header.set_buffer_offset(1, 25).is_err());
- assert!(header.set_buffer_offset(1, 27).is_ok());
+ assert!(header.set_buffer_offset(1, 27).is_err());
assert!(header.set_buffer_offset(1, 28).is_err());
// Setting buffer offset past the end of samples is an error.
@@ -1208,101 +966,4 @@ mod tests {
let rc = unsafe { cras_mmap(10, libc::PROT_READ, -1) };
assert!(rc.is_err());
}
-
- #[test]
- fn cras_server_state() {
- let size = mem::size_of::<cras_server_state>();
- let shm = create_shm(size);
- unsafe {
- let addr = cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd())
- .expect("failed to mmap state shm");
- {
- let state: &mut cras_server_state = &mut *(addr as *mut cras_server_state);
- state.state_version = CRAS_SERVER_STATE_VERSION;
- state.volume = 47;
- state.mute = 1;
- }
- libc::munmap(addr, size);
- };
- let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) };
- let state =
- CrasServerState::try_new(state_fd).expect("try_new failed for valid server_state fd");
- assert_eq!(state.get_system_volume(), 47);
- assert_eq!(state.get_system_mute(), true);
- }
-
- #[test]
- fn cras_server_state_old_version() {
- let size = mem::size_of::<cras_server_state>();
- let shm = create_shm(size);
- unsafe {
- let addr = cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd())
- .expect("failed to mmap state shm");
- {
- let state: &mut cras_server_state = &mut *(addr as *mut cras_server_state);
- state.state_version = CRAS_SERVER_STATE_VERSION - 1;
- state.volume = 29;
- state.mute = 0;
- }
- libc::munmap(addr, size);
- };
- let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) };
- CrasServerState::try_new(state_fd)
- .expect_err("try_new succeeded for invalid state version");
- }
-
- #[test]
- fn cras_server_sync_state_read() {
- let size = mem::size_of::<cras_server_state>();
- let shm = create_shm(size);
- let addr = unsafe { cras_mmap(size, libc::PROT_WRITE, shm.as_raw_fd()).unwrap() };
- let state: &mut cras_server_state = unsafe { &mut *(addr as *mut cras_server_state) };
- state.state_version = CRAS_SERVER_STATE_VERSION;
- state.update_count = 14;
- state.volume = 12;
-
- let state_fd = unsafe { CrasServerStateShmFd::new(shm.into_raw_fd()) };
- let state_struct = CrasServerState::try_new(state_fd).unwrap();
-
- // Create a lock so that we can block the reader while we change the
- // update_count;
- let lock = Arc::new(Mutex::new(()));
- let thread_lock = lock.clone();
- let reader_thread = {
- let _guard = lock.lock().unwrap();
-
- // Create reader thread that will get the value of volume. Since we
- // hold the lock currently, this will block until we release the lock.
- let reader_thread = thread::spawn(move || {
- state_struct.synchronized_state_read(|| {
- let _guard = thread_lock.lock().unwrap();
- state_struct.volume.load()
- })
- });
-
- // Update volume and change update count so that the synchronized read
- // will not return (odd update count means update in progress).
- state.volume = 27;
- state.update_count = 15;
-
- reader_thread
- };
-
- // The lock has been released, but the reader thread should still not
- // terminate, because of the update in progress.
-
- // Yield thread to give reader_thread a chance to get scheduled.
- thread::yield_now();
- {
- let _guard = lock.lock().unwrap();
-
- // Update volume and change update count to indicate the write has
- // finished.
- state.volume = 42;
- state.update_count = 16;
- }
-
- let read_value = reader_thread.join().unwrap();
- assert_eq!(read_value, 42);
- }
}
diff --git a/cras/client/libcras/src/cras_shm_stream.rs b/cras/client/libcras/src/cras_shm_stream.rs
deleted file mode 100644
index f72cc07c..00000000
--- a/cras/client/libcras/src/cras_shm_stream.rs
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::time::Duration;
-use std::{error, fmt};
-
-use audio_streams::{
- shm_streams::{BufferSet, ServerRequest, ShmStream},
- BoxError, SampleFormat, StreamDirection,
-};
-use cras_sys::gen::CRAS_AUDIO_MESSAGE_ID;
-use sys_util::error;
-
-use crate::audio_socket::{AudioMessage, AudioSocket};
-use crate::cras_server_socket::CrasServerSocket;
-use crate::cras_shm::{self, CrasAudioHeader, CrasAudioShmHeaderFd};
-
-#[derive(Debug)]
-pub enum Error {
- MessageTypeError,
- CaptureBufferTooSmall,
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Error::MessageTypeError => write!(f, "Message type error"),
- Error::CaptureBufferTooSmall => write!(
- f,
- "Capture buffer too small, must have size at least 'used_size'."
- ),
- }
- }
-}
-
-/// An object that handles interactions with CRAS for a shm stream.
-/// The object implements `ShmStream` and so can be used to wait for
-/// `ServerRequest` and `BufferComplete` messages.
-pub struct CrasShmStream<'a> {
- stream_id: u32,
- server_socket: CrasServerSocket,
- audio_socket: AudioSocket,
- direction: StreamDirection,
- header: CrasAudioHeader<'a>,
- frame_size: usize,
- num_channels: usize,
- frame_rate: u32,
- // The index of the next buffer within SHM to set the buffer offset for.
- next_buffer_idx: usize,
-}
-
-impl<'a> CrasShmStream<'a> {
- /// Attempt to creates a CrasShmStream with the given arguments.
- ///
- /// # Arguments
- ///
- /// * `stream_id` - The server's ID for the stream.
- /// * `server_socket` - The socket that is connected to the server.
- /// * `audio_socket` - The socket for audio request and audio available messages.
- /// * `direction` - The direction of the stream, `Playback` or `Capture`.
- /// * `num_channels` - The number of audio channels for the stream.
- /// * `format` - The format to use for the stream's samples.
- /// * `header_fd` - The file descriptor for the audio header shm area.
- /// * `samples_len` - The size of the audio samples shm area.
- ///
- /// # Returns
- ///
- /// `CrasShmStream` - CRAS client stream.
- ///
- /// # Errors
- ///
- /// * If `header_fd` could not be successfully mmapped.
- #[allow(clippy::too_many_arguments)]
- pub fn try_new(
- stream_id: u32,
- server_socket: CrasServerSocket,
- audio_socket: AudioSocket,
- direction: StreamDirection,
- num_channels: usize,
- frame_rate: u32,
- format: SampleFormat,
- header_fd: CrasAudioShmHeaderFd,
- samples_len: usize,
- ) -> Result<Self, BoxError> {
- let header = cras_shm::create_header(header_fd, samples_len)?;
- Ok(Self {
- stream_id,
- server_socket,
- audio_socket,
- direction,
- header,
- frame_size: format.sample_bytes() * num_channels,
- num_channels,
- frame_rate,
- // We have either sent zero or two offsets to the server, so we will
- // need to update index 0 next.
- next_buffer_idx: 0,
- })
- }
-}
-
-impl<'a> Drop for CrasShmStream<'a> {
- /// Send the disconnect stream message and log an error if sending fails.
- fn drop(&mut self) {
- if let Err(e) = self.server_socket.disconnect_stream(self.stream_id) {
- error!("CrasShmStream::drop error: {}", e);
- }
- }
-}
-
-impl<'a> ShmStream for CrasShmStream<'a> {
- fn frame_size(&self) -> usize {
- self.frame_size
- }
-
- fn num_channels(&self) -> usize {
- self.num_channels
- }
-
- fn frame_rate(&self) -> u32 {
- self.frame_rate
- }
-
- fn wait_for_next_action_with_timeout(
- &mut self,
- timeout: Duration,
- ) -> Result<Option<ServerRequest>, BoxError> {
- let expected_id = match self.direction {
- StreamDirection::Playback => CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA,
- StreamDirection::Capture => CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY,
- };
-
- match self
- .audio_socket
- .read_audio_message_with_timeout(Some(timeout))?
- {
- Some(AudioMessage::Success { id, frames }) if id == expected_id => {
- Ok(Some(ServerRequest::new(frames as usize, self)))
- }
- None => Ok(None),
- _ => Err(Box::new(Error::MessageTypeError)),
- }
- }
-}
-
-impl BufferSet for CrasShmStream<'_> {
- fn callback(&mut self, offset: usize, frames: usize) -> Result<(), BoxError> {
- self.header
- .set_buffer_offset(self.next_buffer_idx, offset)?;
- self.next_buffer_idx ^= 1;
- let frames = frames as u32;
-
- match self.direction {
- StreamDirection::Playback => {
- self.header.commit_written_frames(frames)?;
-
- // Notify CRAS that we've made playback data available.
- self.audio_socket.data_ready(frames)?
- }
- StreamDirection::Capture => {
- let used_size = self.header.get_used_size();
- // Because CRAS doesn't know how long our buffer in shm is, we
- // must make sure that there are always at least buffer_size
- // frames available so that it doesn't write outside the buffer.
- if frames < (used_size / self.frame_size) as u32 {
- return Err(Box::new(Error::CaptureBufferTooSmall));
- }
-
- self.header.commit_read_frames(frames)?;
- self.audio_socket.capture_ready(frames)?;
- }
- }
-
- Ok(())
- }
-
- fn ignore(&mut self) -> Result<(), BoxError> {
- // We send an empty buffer for an ignored playback request since the
- // server will not read from a 0-length buffer. We don't do anything for
- // an ignored capture request, since we don't have a way to communicate
- // buffer length to the server, and we don't want the server writing
- // data to offsets within the SHM area that aren't audio buffers.
- if self.direction == StreamDirection::Playback {
- self.callback(0, 0)?;
- }
-
- Ok(())
- }
-}
diff --git a/cras/client/libcras/src/cras_stream.rs b/cras/client/libcras/src/cras_stream.rs
index f6004802..bd9520a1 100644
--- a/cras/client/libcras/src/cras_stream.rs
+++ b/cras/client/libcras/src/cras_stream.rs
@@ -4,13 +4,17 @@
use std::cmp::min;
use std::io;
use std::marker::PhantomData;
+use std::mem;
use std::{error, fmt};
use audio_streams::{
capture::{CaptureBuffer, CaptureBufferStream},
- BoxError, BufferDrop, PlaybackBuffer, PlaybackBufferStream,
+ BufferDrop, PlaybackBuffer, PlaybackBufferStream,
+};
+use cras_sys::gen::{
+ cras_disconnect_stream_message, cras_server_message, snd_pcm_format_t, CRAS_AUDIO_MESSAGE_ID,
+ CRAS_SERVER_MESSAGE_ID, CRAS_STREAM_DIRECTION,
};
-use cras_sys::gen::{snd_pcm_format_t, CRAS_AUDIO_MESSAGE_ID, CRAS_STREAM_DIRECTION};
use sys_util::error;
use crate::audio_socket::{AudioMessage, AudioSocket};
@@ -18,25 +22,38 @@ use crate::cras_server_socket::CrasServerSocket;
use crate::cras_shm::*;
#[derive(Debug)]
-pub enum Error {
+pub enum ErrorType {
IoError(io::Error),
MessageTypeError,
+ NoShmError,
+}
+
+#[derive(Debug)]
+pub struct Error {
+ error_type: ErrorType,
+}
+
+impl Error {
+ fn new(error_type: ErrorType) -> Error {
+ Error { error_type }
+ }
}
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Error::IoError(ref err) => err.fmt(f),
- Error::MessageTypeError => write!(f, "Message type error"),
+ match self.error_type {
+ ErrorType::IoError(ref err) => err.fmt(f),
+ ErrorType::MessageTypeError => write!(f, "Message type error"),
+ ErrorType::NoShmError => write!(f, "Shared memory area is not created"),
}
}
}
impl From<io::Error> for Error {
fn from(io_err: io::Error) -> Error {
- Error::IoError(io_err)
+ Error::new(ErrorType::IoError(io_err))
}
}
@@ -44,23 +61,31 @@ impl From<io::Error> for Error {
/// interacts with server's audio thread through `AudioSocket`.
pub trait CrasStreamData<'a>: Send {
// Creates `CrasStreamData` with only `AudioSocket`.
- fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self;
- fn header_mut(&mut self) -> &mut CrasAudioHeader<'a>;
+ fn new(audio_sock: AudioSocket) -> Self;
+ fn set_header(&mut self, header: CrasAudioHeader<'a>);
+ fn header_mut(&mut self) -> &mut Option<CrasAudioHeader<'a>>;
fn audio_sock_mut(&mut self) -> &mut AudioSocket;
}
/// `CrasStreamData` implementation for `PlaybackBufferStream`.
pub struct CrasPlaybackData<'a> {
audio_sock: AudioSocket,
- header: CrasAudioHeader<'a>,
+ header: Option<CrasAudioHeader<'a>>,
}
impl<'a> CrasStreamData<'a> for CrasPlaybackData<'a> {
- fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self {
- Self { audio_sock, header }
+ fn new(audio_sock: AudioSocket) -> Self {
+ Self {
+ audio_sock,
+ header: None,
+ }
+ }
+
+ fn set_header(&mut self, header: CrasAudioHeader<'a>) {
+ self.header = Some(header);
}
- fn header_mut(&mut self) -> &mut CrasAudioHeader<'a> {
+ fn header_mut(&mut self) -> &mut Option<CrasAudioHeader<'a>> {
&mut self.header
}
@@ -72,8 +97,10 @@ impl<'a> CrasStreamData<'a> for CrasPlaybackData<'a> {
impl<'a> BufferDrop for CrasPlaybackData<'a> {
fn trigger(&mut self, nframes: usize) {
let log_err = |e| error!("BufferDrop error: {}", e);
- if let Err(e) = self.header.commit_written_frames(nframes as u32) {
- log_err(e);
+ if let Some(header) = &mut self.header {
+ if let Err(e) = header.commit_written_frames(nframes as u32) {
+ log_err(e);
+ }
}
if let Err(e) = self.audio_sock.data_ready(nframes as u32) {
log_err(e);
@@ -84,15 +111,22 @@ impl<'a> BufferDrop for CrasPlaybackData<'a> {
/// `CrasStreamData` implementation for `CaptureBufferStream`.
pub struct CrasCaptureData<'a> {
audio_sock: AudioSocket,
- header: CrasAudioHeader<'a>,
+ header: Option<CrasAudioHeader<'a>>,
}
impl<'a> CrasStreamData<'a> for CrasCaptureData<'a> {
- fn new(audio_sock: AudioSocket, header: CrasAudioHeader<'a>) -> Self {
- Self { audio_sock, header }
+ fn new(audio_sock: AudioSocket) -> Self {
+ Self {
+ audio_sock,
+ header: None,
+ }
}
- fn header_mut(&mut self) -> &mut CrasAudioHeader<'a> {
+ fn set_header(&mut self, header: CrasAudioHeader<'a>) {
+ self.header = Some(header);
+ }
+
+ fn header_mut(&mut self) -> &mut Option<CrasAudioHeader<'a>> {
&mut self.header
}
@@ -104,8 +138,10 @@ impl<'a> CrasStreamData<'a> for CrasCaptureData<'a> {
impl<'a> BufferDrop for CrasCaptureData<'a> {
fn trigger(&mut self, nframes: usize) {
let log_err = |e| error!("BufferDrop error: {}", e);
- if let Err(e) = self.header.commit_read_frames(nframes as u32) {
- log_err(e);
+ if let Some(header) = &mut self.header {
+ if let Err(e) = header.commit_read_frames(nframes as u32) {
+ log_err(e);
+ }
}
if let Err(e) = self.audio_sock.capture_ready(nframes as u32) {
log_err(e);
@@ -119,14 +155,14 @@ pub struct CrasStream<'a, T: CrasStreamData<'a> + BufferDrop> {
server_socket: CrasServerSocket,
block_size: u32,
direction: CRAS_STREAM_DIRECTION,
- rate: u32,
+ rate: usize,
num_channels: usize,
format: snd_pcm_format_t,
/// A structure for stream to interact with server audio thread.
controls: T,
/// The `PhantomData` is used by `controls: T`
phantom: PhantomData<CrasAudioHeader<'a>>,
- audio_buffer: CrasAudioBuffer,
+ audio_buffer: Option<CrasAudioBuffer>,
}
impl<'a, T: CrasStreamData<'a> + BufferDrop> CrasStream<'a, T> {
@@ -134,22 +170,17 @@ impl<'a, T: CrasStreamData<'a> + BufferDrop> CrasStream<'a, T> {
///
/// # Returns
/// `CrasStream` - CRAS client stream.
- #[allow(clippy::too_many_arguments)]
- pub fn try_new(
+ pub fn new(
stream_id: u32,
server_socket: CrasServerSocket,
block_size: u32,
direction: CRAS_STREAM_DIRECTION,
- rate: u32,
+ rate: usize,
num_channels: usize,
format: snd_pcm_format_t,
audio_sock: AudioSocket,
- header_fd: CrasAudioShmHeaderFd,
- samples_fd: CrasShmFd,
- ) -> Result<Self, Error> {
- let (header, audio_buffer) = create_header_and_buffers(header_fd, samples_fd)?;
-
- Ok(Self {
+ ) -> Self {
+ Self {
stream_id,
server_socket,
block_size,
@@ -157,29 +188,41 @@ impl<'a, T: CrasStreamData<'a> + BufferDrop> CrasStream<'a, T> {
rate,
num_channels,
format,
- controls: T::new(audio_sock, header),
+ controls: T::new(audio_sock),
phantom: PhantomData,
- audio_buffer,
- })
+ audio_buffer: None,
+ }
+ }
+
+ /// Receives shared memory fd and initialize stream audio shared memory area
+ pub fn init_shm(
+ &mut self,
+ header_fd: CrasAudioShmHeaderFd,
+ samples_fd: CrasShmFd,
+ ) -> Result<(), Error> {
+ let (header, buffer) = create_header_and_buffers(header_fd, samples_fd)?;
+ self.controls.set_header(header);
+ self.audio_buffer = Some(buffer);
+ Ok(())
}
fn wait_request_data(&mut self) -> Result<(), Error> {
match self.controls.audio_sock_mut().read_audio_message()? {
- AudioMessage::Success {
- id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA,
- ..
- } => Ok(()),
- _ => Err(Error::MessageTypeError),
+ AudioMessage::Success { id, .. } => match id {
+ CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_REQUEST_DATA => Ok(()),
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
+ },
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
}
}
fn wait_data_ready(&mut self) -> Result<u32, Error> {
match self.controls.audio_sock_mut().read_audio_message()? {
- AudioMessage::Success {
- id: CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY,
- frames,
- } => Ok(frames),
- _ => Err(Error::MessageTypeError),
+ AudioMessage::Success { id, frames } => match id {
+ CRAS_AUDIO_MESSAGE_ID::AUDIO_MESSAGE_DATA_READY => Ok(frames),
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
+ },
+ _ => Err(Error::new(ErrorType::MessageTypeError)),
}
}
}
@@ -189,36 +232,57 @@ impl<'a, T: CrasStreamData<'a> + BufferDrop> Drop for CrasStream<'a, T> {
/// the return message.
/// Logs an error message to stderr if the method fails.
fn drop(&mut self) {
- if let Err(e) = self.server_socket.disconnect_stream(self.stream_id) {
+ // Send stream disconnect message
+ let msg_header = cras_server_message {
+ length: mem::size_of::<cras_disconnect_stream_message>() as u32,
+ id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DISCONNECT_STREAM,
+ };
+ let server_cmsg = cras_disconnect_stream_message {
+ header: msg_header,
+ stream_id: self.stream_id,
+ };
+ if let Err(e) = self
+ .server_socket
+ .send_server_message_with_fds(&server_cmsg, &[])
+ {
error!("CrasStream::Drop error: {}", e);
}
}
}
impl<'a, T: CrasStreamData<'a> + BufferDrop> PlaybackBufferStream for CrasStream<'a, T> {
- fn next_playback_buffer(&mut self) -> Result<PlaybackBuffer, BoxError> {
+ fn next_playback_buffer(&mut self) -> Result<PlaybackBuffer, Box<dyn error::Error>> {
// Wait for request audio message
self.wait_request_data()?;
- let header = self.controls.header_mut();
- let frame_size = header.get_frame_size();
- let (offset, len) = header.get_write_offset_and_len()?;
- let buf = &mut self.audio_buffer.get_buffer()[offset..offset + len];
-
+ let (frame_size, (offset, len)) = match self.controls.header_mut() {
+ None => return Err(Error::new(ErrorType::NoShmError).into()),
+ Some(header) => (header.get_frame_size(), header.get_write_offset_and_len()?),
+ };
+ let buf = match self.audio_buffer.as_mut() {
+ None => return Err(Error::new(ErrorType::NoShmError).into()),
+ Some(audio_buffer) => &mut audio_buffer.get_buffer()[offset..offset + len],
+ };
PlaybackBuffer::new(frame_size, buf, &mut self.controls).map_err(Box::from)
}
}
impl<'a, T: CrasStreamData<'a> + BufferDrop> CaptureBufferStream for CrasStream<'a, T> {
- fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, BoxError> {
+ fn next_capture_buffer(&mut self) -> Result<CaptureBuffer, Box<dyn error::Error>> {
// Wait for data ready message
let frames = self.wait_data_ready()?;
- let header = self.controls.header_mut();
- let frame_size = header.get_frame_size();
- let shm_frames = header.get_readable_frames()?;
+ let (frame_size, shm_frames, offset) = match self.controls.header_mut() {
+ None => return Err(Error::new(ErrorType::NoShmError).into()),
+ Some(header) => (
+ header.get_frame_size(),
+ header.get_readable_frames()?,
+ header.get_read_buffer_offset()?,
+ ),
+ };
let len = min(shm_frames, frames as usize) * frame_size;
- let offset = header.get_read_buffer_offset()?;
- let buf = &mut self.audio_buffer.get_buffer()[offset..offset + len];
-
+ let buf = match self.audio_buffer.as_mut() {
+ None => return Err(Error::new(ErrorType::NoShmError).into()),
+ Some(audio_buffer) => &mut audio_buffer.get_buffer()[offset..offset + len],
+ };
CaptureBuffer::new(frame_size, buf, &mut self.controls).map_err(Box::from)
}
}
diff --git a/cras/client/libcras/src/libcras.rs b/cras/client/libcras/src/libcras.rs
index 402a4a27..c81e540d 100644
--- a/cras/client/libcras/src/libcras.rs
+++ b/cras/client/libcras/src/libcras.rs
@@ -23,15 +23,14 @@
//! use std::fs::File;
//! use std::io::{Read, Write};
//! use std::thread::{spawn, JoinHandle};
-//! type Result<T> = std::result::Result<T, BoxError>;
+//! type Result<T> = std::result::Result<T, Box<std::error::Error>>;
//!
-//! use libcras::{BoxError, CrasClient, CrasClientType};
-//! use audio_streams::{SampleFormat, StreamSource};
+//! use libcras::{CrasClient, CrasClientType};
+//! use audio_streams::StreamSource;
//!
//! const BUFFER_SIZE: usize = 256;
-//! const FRAME_RATE: u32 = 44100;
+//! const FRAME_RATE: usize = 44100;
//! const NUM_CHANNELS: usize = 2;
-//! const FORMAT: SampleFormat = SampleFormat::S16LE;
//!
//! # fn main() -> Result<()> {
//! # let args: Vec<String> = env::args().collect();
@@ -40,7 +39,7 @@
//! let mut cras_client = CrasClient::new()?;
//! cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST);
//! let (_control, mut stream) = cras_client
-//! .new_playback_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?;
+//! .new_playback_stream(NUM_CHANNELS, FRAME_RATE, BUFFER_SIZE)?;
//!
//! // Plays 1000 * BUFFER_SIZE samples from the given file
//! let mut file = File::open(&args[1])?;
@@ -76,15 +75,14 @@
//! use std::fs::File;
//! use std::io::{Read, Write};
//! use std::thread::{spawn, JoinHandle};
-//! type Result<T> = std::result::Result<T, BoxError>;
+//! type Result<T> = std::result::Result<T, Box<std::error::Error>>;
//!
-//! use libcras::{BoxError, CrasClient, CrasClientType};
-//! use audio_streams::{SampleFormat, StreamSource};
+//! use libcras::{CrasClient, CrasClientType};
+//! use audio_streams::StreamSource;
//!
//! const BUFFER_SIZE: usize = 256;
-//! const FRAME_RATE: u32 = 44100;
+//! const FRAME_RATE: usize = 44100;
//! const NUM_CHANNELS: usize = 2;
-//! const FORMAT: SampleFormat = SampleFormat::S16LE;
//!
//! # fn main() -> Result<()> {
//! # let args: Vec<String> = env::args().collect();
@@ -93,7 +91,7 @@
//! let mut cras_client = CrasClient::new()?;
//! cras_client.set_client_type(CrasClientType::CRAS_CLIENT_TYPE_TEST);
//! let (_control, mut stream) = cras_client
-//! .new_capture_stream(NUM_CHANNELS, FORMAT, FRAME_RATE, BUFFER_SIZE)?;
+//! .new_capture_stream(NUM_CHANNELS, FRAME_RATE, BUFFER_SIZE)?;
//!
//! // Capture 1000 * BUFFER_SIZE samples to the given file
//! let mut file = File::create(&args[1])?;
@@ -124,58 +122,56 @@ use std::os::unix::{
};
use std::{error, fmt};
-pub use audio_streams::BoxError;
use audio_streams::{
- capture::{CaptureBufferStream, NoopCaptureStream},
- shm_streams::{NullShmStream, ShmStream, ShmStreamSource},
- BufferDrop, NoopStreamControl, PlaybackBufferStream, SampleFormat, StreamControl,
- StreamDirection, StreamEffect, StreamSource,
+ capture::{CaptureBufferStream, DummyCaptureStream},
+ BufferDrop, DummyStreamControl, PlaybackBufferStream, StreamControl, StreamSource,
};
+pub use cras_sys::gen::CRAS_CLIENT_TYPE as CrasClientType;
use cras_sys::gen::*;
-pub use cras_sys::gen::{
- CRAS_CLIENT_TYPE as CrasClientType, CRAS_NODE_TYPE as CrasNodeType,
- CRAS_STREAM_EFFECT as CrasStreamEffect,
-};
-pub use cras_sys::{AudioDebugInfo, CrasIodevInfo, CrasIonodeInfo, Error as CrasSysError};
-use sys_util::{PollContext, PollToken, SharedMemory};
+use sys_util::{PollContext, PollToken};
mod audio_socket;
use crate::audio_socket::AudioSocket;
mod cras_server_socket;
use crate::cras_server_socket::CrasServerSocket;
-pub use crate::cras_server_socket::CrasSocketType;
mod cras_shm;
-use crate::cras_shm::CrasServerState;
-pub mod cras_shm_stream;
-use crate::cras_shm_stream::CrasShmStream;
mod cras_stream;
use crate::cras_stream::{CrasCaptureData, CrasPlaybackData, CrasStream, CrasStreamData};
mod cras_client_message;
use crate::cras_client_message::*;
#[derive(Debug)]
-pub enum Error {
+pub enum ErrorType {
CrasClientMessageError(cras_client_message::Error),
CrasStreamError(cras_stream::Error),
- CrasSysError(cras_sys::Error),
IoError(io::Error),
SysUtilError(sys_util::Error),
MessageTypeError,
UnexpectedExit,
}
+#[derive(Debug)]
+pub struct Error {
+ error_type: ErrorType,
+}
+
+impl Error {
+ fn new(error_type: ErrorType) -> Self {
+ Self { error_type }
+ }
+}
+
impl error::Error for Error {}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match self {
- Error::CrasClientMessageError(ref err) => err.fmt(f),
- Error::CrasStreamError(ref err) => err.fmt(f),
- Error::CrasSysError(ref err) => err.fmt(f),
- Error::IoError(ref err) => err.fmt(f),
- Error::SysUtilError(ref err) => err.fmt(f),
- Error::MessageTypeError => write!(f, "Message type error"),
- Error::UnexpectedExit => write!(f, "Unexpected exit"),
+ match self.error_type {
+ ErrorType::CrasClientMessageError(ref err) => err.fmt(f),
+ ErrorType::CrasStreamError(ref err) => err.fmt(f),
+ ErrorType::IoError(ref err) => err.fmt(f),
+ ErrorType::SysUtilError(ref err) => err.fmt(f),
+ ErrorType::MessageTypeError => write!(f, "Message type error"),
+ ErrorType::UnexpectedExit => write!(f, "Unexpected exit"),
}
}
}
@@ -184,40 +180,39 @@ type Result<T> = std::result::Result<T, Error>;
impl From<io::Error> for Error {
fn from(io_err: io::Error) -> Self {
- Error::IoError(io_err)
+ Self::new(ErrorType::IoError(io_err))
}
}
impl From<sys_util::Error> for Error {
fn from(sys_util_err: sys_util::Error) -> Self {
- Error::SysUtilError(sys_util_err)
+ Self::new(ErrorType::SysUtilError(sys_util_err))
}
}
impl From<cras_stream::Error> for Error {
fn from(err: cras_stream::Error) -> Self {
- Error::CrasStreamError(err)
+ Self::new(ErrorType::CrasStreamError(err))
}
}
impl From<cras_client_message::Error> for Error {
fn from(err: cras_client_message::Error) -> Self {
- Error::CrasClientMessageError(err)
+ Self::new(ErrorType::CrasClientMessageError(err))
}
}
-/// A CRAS server client, which implements StreamSource and ShmStreamSource.
-/// It can create audio streams connecting to CRAS server.
-pub struct CrasClient<'a> {
+/// A CRAS server client, which implements StreamSource. It can create audio streams connecting
+/// to CRAS server.
+pub struct CrasClient {
server_socket: CrasServerSocket,
- server_state: CrasServerState<'a>,
client_id: u32,
next_stream_id: u32,
cras_capture: bool,
client_type: CRAS_CLIENT_TYPE,
}
-impl<'a> CrasClient<'a> {
+impl CrasClient {
/// Blocks creating a `CrasClient` with registered `client_id`
///
/// # Results
@@ -229,33 +224,26 @@ impl<'a> CrasClient<'a> {
/// Returns error if error occurs while handling server message or message
/// type is incorrect
pub fn new() -> Result<Self> {
- Self::with_type(CrasSocketType::Legacy)
- }
-
- /// Tries to create a `CrasClient` with a given `CrasSocketType`.
- ///
- /// # Errors
- ///
- /// Returns error if error occurs while handling server message or message
- /// type is incorrect.
- pub fn with_type(socket_type: CrasSocketType) -> Result<Self> {
// Create a connection to the server.
- let mut server_socket = CrasServerSocket::with_type(socket_type)?;
- // Gets client ID and server state fd from server
- if let ServerResult::Connected(client_id, server_state_fd) =
- CrasClient::wait_for_message(&mut server_socket)?
- {
- Ok(Self {
- server_socket,
- server_state: CrasServerState::try_new(server_state_fd)?,
- client_id,
- next_stream_id: 0,
- cras_capture: false,
- client_type: CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_UNKNOWN,
- })
- } else {
- Err(Error::MessageTypeError)
- }
+ let mut server_socket = CrasServerSocket::new()?;
+
+ // Gets client ID from server
+ let client_id = {
+ match CrasClient::wait_for_message(&mut server_socket)? {
+ ServerResult::Connected(res, _server_state_fd) => res as u32,
+ _ => {
+ return Err(Error::new(ErrorType::MessageTypeError));
+ }
+ }
+ };
+
+ Ok(Self {
+ server_socket,
+ client_id,
+ next_stream_id: 0,
+ cras_capture: false,
+ client_type: CRAS_CLIENT_TYPE::CRAS_CLIENT_TYPE_UNKNOWN,
+ })
}
/// Enables capturing audio through CRAS server.
@@ -268,143 +256,31 @@ impl<'a> CrasClient<'a> {
self.client_type = client_type;
}
- /// Sets the system volume to `volume`.
- ///
- /// Send a message to the server to request setting the system volume
- /// to `volume`. No response is returned from the server.
- ///
- /// # Errors
- ///
- /// If writing the message to the server socket failed.
- pub fn set_system_volume(&mut self, volume: u32) -> Result<()> {
- let header = cras_server_message {
- length: mem::size_of::<cras_set_system_volume>() as u32,
- id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_VOLUME,
- };
- let msg = cras_set_system_volume { header, volume };
-
- self.server_socket.send_server_message_with_fds(&msg, &[])?;
- Ok(())
- }
-
- /// Sets the system mute status to `mute`.
- ///
- /// Send a message to the server to request setting the system mute
- /// to `mute`. No response is returned from the server.
- ///
- /// # Errors
- ///
- /// If writing the message to the server socket failed.
- pub fn set_system_mute(&mut self, mute: bool) -> Result<()> {
- let header = cras_server_message {
- length: mem::size_of::<cras_set_system_mute>() as u32,
- id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_SET_SYSTEM_MUTE,
- };
- let msg = cras_set_system_mute {
- header,
- mute: mute as i32,
- };
-
- self.server_socket.send_server_message_with_fds(&msg, &[])?;
- Ok(())
- }
-
- /// Gets the system volume.
- ///
- /// Read the current value for system volume from the server shared memory.
- pub fn get_system_volume(&self) -> u32 {
- self.server_state.get_system_volume()
- }
-
- /// Gets the system mute.
- ///
- /// Read the current value for system mute from the server shared memory.
- pub fn get_system_mute(&self) -> bool {
- self.server_state.get_system_mute()
- }
-
- /// Gets a list of output devices
- ///
- /// Read a list of the currently attached output devices from the server shared memory.
- pub fn output_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
- self.server_state.output_devices()
- }
-
- /// Gets a list of input devices
- ///
- /// Read a list of the currently attached input devices from the server shared memory.
- pub fn input_devices(&self) -> impl Iterator<Item = CrasIodevInfo> {
- self.server_state.input_devices()
- }
-
- /// Gets a list of output nodes
- ///
- /// Read a list of the currently attached output nodes from the server shared memory.
- pub fn output_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
- self.server_state.output_nodes()
- }
-
- /// Gets a list of input nodes
- ///
- /// Read a list of the currently attached input nodes from the server shared memory.
- pub fn input_nodes(&self) -> impl Iterator<Item = CrasIonodeInfo> {
- self.server_state.input_nodes()
- }
-
- /// Gets the server's audio debug info.
- ///
- /// Sends a message to the server requesting an update of audio debug info,
- /// waits for the response, and then reads the info from the server state.
- ///
- /// # Errors
- ///
- /// * If sending the message to the server failed.
- /// * If an unexpected response message is received.
- pub fn get_audio_debug_info(&mut self) -> Result<AudioDebugInfo> {
- let header = cras_server_message {
- length: mem::size_of::<cras_dump_audio_thread>() as u32,
- id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_DUMP_AUDIO_THREAD,
- };
- let msg = cras_dump_audio_thread { header };
-
- self.server_socket.send_server_message_with_fds(&msg, &[])?;
-
- match CrasClient::wait_for_message(&mut self.server_socket)? {
- ServerResult::DebugInfoReady => Ok(self
- .server_state
- .get_audio_debug_info()
- .map_err(Error::CrasSysError)?),
- _ => Err(Error::MessageTypeError),
- }
- }
-
// Gets next server_stream_id from client and increment stream_id counter.
- fn next_server_stream_id(&mut self) -> u32 {
+ fn next_server_stream_id(&mut self) -> Result<u32> {
let res = self.next_stream_id;
self.next_stream_id += 1;
- self.server_stream_id(res)
+ self.server_stream_id(&res)
}
// Gets server_stream_id from given stream_id
- fn server_stream_id(&self, stream_id: u32) -> u32 {
- (self.client_id << 16) | stream_id
+ fn server_stream_id(&self, stream_id: &u32) -> Result<u32> {
+ Ok((self.client_id << 16) | stream_id)
}
// Creates general stream with given parameters
- fn create_stream<'b, T: BufferDrop + CrasStreamData<'b>>(
+ fn create_stream<'a, T: BufferDrop + CrasStreamData<'a>>(
&mut self,
- device_index: Option<u32>,
block_size: u32,
direction: CRAS_STREAM_DIRECTION,
- rate: u32,
+ rate: usize,
channel_num: usize,
- format: SampleFormat,
- ) -> Result<CrasStream<'b, T>> {
- let stream_id = self.next_server_stream_id();
+ format: snd_pcm_format_t,
+ ) -> Result<CrasStream<'a, T>> {
+ let stream_id = self.next_server_stream_id()?;
// Prepares server message
- let audio_format =
- cras_audio_format_packed::new(format.into(), rate, channel_num, direction);
+ let audio_format = cras_audio_format_packed::new(format, rate, channel_num);
let msg_header = cras_server_message {
length: mem::size_of::<cras_connect_message>() as u32,
id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM,
@@ -419,11 +295,10 @@ impl<'a> CrasClient<'a> {
cb_threshold: block_size,
flags: 0,
format: audio_format,
- dev_idx: device_index.unwrap_or(CRAS_SPECIAL_DEVICE::NO_DEVICE as u32),
+ dev_idx: CRAS_SPECIAL_DEVICE::NO_DEVICE as u32,
effects: 0,
client_type: self.client_type,
client_shm_size: 0,
- buffer_offsets: [0, 0],
};
// Creates AudioSocket pair
@@ -435,90 +310,26 @@ impl<'a> CrasClient<'a> {
.send_server_message_with_fds(&server_cmsg, &socks)?;
let audio_socket = AudioSocket::new(sock1);
+ let mut stream = CrasStream::new(
+ stream_id,
+ self.server_socket.try_clone()?,
+ block_size,
+ direction,
+ rate,
+ channel_num,
+ format,
+ audio_socket,
+ );
+
loop {
let result = CrasClient::wait_for_message(&mut self.server_socket)?;
if let ServerResult::StreamConnected(_stream_id, header_fd, samples_fd) = result {
- return CrasStream::try_new(
- stream_id,
- self.server_socket.try_clone()?,
- block_size,
- direction,
- rate,
- channel_num,
- format.into(),
- audio_socket,
- header_fd,
- samples_fd,
- )
- .map_err(Error::CrasStreamError);
+ stream.init_shm(header_fd, samples_fd)?;
+ break;
}
}
- }
- /// Creates a new playback stream pinned to the device at `device_index`.
- ///
- /// # Arguments
- ///
- /// * `device_index` - The device to which the stream will be attached.
- /// * `num_channels` - The count of audio channels for the stream.
- /// * `format` - The format to use for stream audio samples.
- /// * `frame_rate` - The sample rate of the stream.
- /// * `buffer_size` - The transfer size granularity in frames.
- #[allow(clippy::type_complexity)]
- pub fn new_pinned_playback_stream(
- &mut self,
- device_index: u32,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>
- {
- Ok((
- Box::new(NoopStreamControl::new()),
- Box::new(self.create_stream::<CrasPlaybackData>(
- Some(device_index),
- buffer_size as u32,
- CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT,
- frame_rate,
- num_channels,
- format,
- )?),
- ))
- }
-
- /// Creates a new capture stream pinned to the device at `device_index`.
- ///
- /// This is useful for, among other things, capturing from a loopback
- /// device.
- ///
- /// # Arguments
- ///
- /// * `device_index` - The device to which the stream will be attached.
- /// * `num_channels` - The count of audio channels for the stream.
- /// * `format` - The format to use for stream audio samples.
- /// * `frame_rate` - The sample rate of the stream.
- /// * `buffer_size` - The transfer size granularity in frames.
- #[allow(clippy::type_complexity)]
- pub fn new_pinned_capture_stream(
- &mut self,
- device_index: u32,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> {
- Ok((
- Box::new(NoopStreamControl::new()),
- Box::new(self.create_stream::<CrasCaptureData>(
- Some(device_index),
- buffer_size as u32,
- CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT,
- frame_rate,
- num_channels,
- format,
- )?),
- ))
+ Ok(stream)
}
// Blocks handling the first server message received from `socket`.
@@ -535,7 +346,7 @@ impl<'a> CrasClient<'a> {
let tokens: Vec<Token> = events.iter_readable().map(|e| e.token()).collect();
tokens
.get(0)
- .ok_or(Error::UnexpectedExit)
+ .ok_or_else(|| Error::new(ErrorType::UnexpectedExit))
.and_then(|ref token| {
match token {
Token::ServerMsg => ServerResult::handle_server_message(socket),
@@ -543,63 +354,55 @@ impl<'a> CrasClient<'a> {
.map_err(Into::into)
})
}
-
- /// Returns any open file descriptors needed by CrasClient.
- /// This function is shared between StreamSource and ShmStreamSource.
- fn keep_fds(&self) -> Vec<RawFd> {
- vec![self.server_socket.as_raw_fd()]
- }
}
-impl<'a> StreamSource for CrasClient<'a> {
- #[allow(clippy::type_complexity)]
+impl StreamSource for CrasClient {
fn new_playback_stream(
&mut self,
num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
+ frame_rate: usize,
buffer_size: usize,
- ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>), BoxError>
- {
+ ) -> std::result::Result<
+ (Box<dyn StreamControl>, Box<dyn PlaybackBufferStream>),
+ Box<dyn error::Error>,
+ > {
Ok((
- Box::new(NoopStreamControl::new()),
+ Box::new(DummyStreamControl::new()),
Box::new(self.create_stream::<CrasPlaybackData>(
- None,
buffer_size as u32,
CRAS_STREAM_DIRECTION::CRAS_STREAM_OUTPUT,
frame_rate,
num_channels,
- format,
+ _snd_pcm_format::SND_PCM_FORMAT_S16_LE,
)?),
))
}
- #[allow(clippy::type_complexity)]
fn new_capture_stream(
&mut self,
num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
+ frame_rate: usize,
buffer_size: usize,
- ) -> std::result::Result<(Box<dyn StreamControl>, Box<dyn CaptureBufferStream>), BoxError> {
+ ) -> std::result::Result<
+ (Box<dyn StreamControl>, Box<dyn CaptureBufferStream>),
+ Box<dyn error::Error>,
+ > {
if self.cras_capture {
Ok((
- Box::new(NoopStreamControl::new()),
+ Box::new(DummyStreamControl::new()),
Box::new(self.create_stream::<CrasCaptureData>(
- None,
buffer_size as u32,
CRAS_STREAM_DIRECTION::CRAS_STREAM_INPUT,
frame_rate,
num_channels,
- format,
+ _snd_pcm_format::SND_PCM_FORMAT_S16_LE,
)?),
))
} else {
Ok((
- Box::new(NoopStreamControl::new()),
- Box::new(NoopCaptureStream::new(
+ Box::new(DummyStreamControl::new()),
+ Box::new(DummyCaptureStream::new(
num_channels,
- format,
frame_rate,
buffer_size,
)),
@@ -608,92 +411,6 @@ impl<'a> StreamSource for CrasClient<'a> {
}
fn keep_fds(&self) -> Option<Vec<RawFd>> {
- Some(CrasClient::keep_fds(self))
- }
-}
-
-impl<'a> ShmStreamSource for CrasClient<'a> {
- fn new_stream(
- &mut self,
- direction: StreamDirection,
- num_channels: usize,
- format: SampleFormat,
- frame_rate: u32,
- buffer_size: usize,
- effects: &[StreamEffect],
- client_shm: &SharedMemory,
- buffer_offsets: [u64; 2],
- ) -> std::result::Result<Box<dyn ShmStream>, BoxError> {
- if direction == StreamDirection::Capture && !self.cras_capture {
- return Ok(Box::new(NullShmStream::new(
- buffer_size,
- num_channels,
- format,
- frame_rate,
- )));
- }
-
- let buffer_size = buffer_size as u32;
-
- // Prepares server message
- let stream_id = self.next_server_stream_id();
- let audio_format = cras_audio_format_packed::new(
- format.into(),
- frame_rate,
- num_channels,
- direction.into(),
- );
- let msg_header = cras_server_message {
- length: mem::size_of::<cras_connect_message>() as u32,
- id: CRAS_SERVER_MESSAGE_ID::CRAS_SERVER_CONNECT_STREAM,
- };
-
- let server_cmsg = cras_connect_message {
- header: msg_header,
- proto_version: CRAS_PROTO_VER,
- direction: direction.into(),
- stream_id,
- stream_type: CRAS_STREAM_TYPE::CRAS_STREAM_TYPE_DEFAULT,
- buffer_frames: buffer_size,
- cb_threshold: buffer_size,
- flags: 0,
- format: audio_format,
- dev_idx: CRAS_SPECIAL_DEVICE::NO_DEVICE as u32,
- effects: effects.iter().collect::<CrasStreamEffect>().into(),
- client_type: self.client_type,
- client_shm_size: client_shm.size(),
- buffer_offsets,
- };
-
- // Creates AudioSocket pair
- let (sock1, sock2) = UnixStream::pair()?;
-
- // Sends `CRAS_SERVER_CONNECT_STREAM` message
- let fds = [sock2.as_raw_fd(), client_shm.as_raw_fd()];
- self.server_socket
- .send_server_message_with_fds(&server_cmsg, &fds)?;
-
- loop {
- let result = CrasClient::wait_for_message(&mut self.server_socket)?;
- if let ServerResult::StreamConnected(_stream_id, header_fd, _samples_fd) = result {
- let audio_socket = AudioSocket::new(sock1);
- let stream = CrasShmStream::try_new(
- stream_id,
- self.server_socket.try_clone()?,
- audio_socket,
- direction,
- num_channels,
- frame_rate,
- format,
- header_fd,
- client_shm.size() as usize,
- )?;
- return Ok(Box::new(stream));
- }
- }
- }
-
- fn keep_fds(&self) -> Vec<RawFd> {
- CrasClient::keep_fds(self)
+ Some(vec![self.server_socket.as_raw_fd()])
}
}
diff --git a/cras/configure.ac b/cras/configure.ac
index f39a14a6..f00011c9 100644
--- a/cras/configure.ac
+++ b/cras/configure.ac
@@ -10,9 +10,6 @@ AC_CANONICAL_HOST
AM_INIT_AUTOMAKE([1.10 -Wall no-define])
#AC_CONFIG_HEADERS([config.h])
-# To compile with full logs, use V=1 with make instead.
-AM_SILENT_RULES([yes])
-
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
AC_PROG_CC
@@ -26,8 +23,6 @@ AC_CONFIG_FILES([Makefile src/Makefile libcras.pc])
PKG_CHECK_MODULES([LIBSPEEX], [ speexdsp >= 1.2 ])
PKG_CHECK_MODULES([ASOUNDLIB], [ alsa >= 1.1.0 ])
-AC_CHECK_HEADERS([iniparser/iniparser.h])
-
AC_ARG_ENABLE([dbus], AS_HELP_STRING([--disable-dbus], [Disable all DBUS uses]), have_dbus=$enableval, have_dbus=yes)
AM_CONDITIONAL(HAVE_DBUS, test "$have_dbus" = "yes")
if test "$have_dbus" = "yes"; then
@@ -53,7 +48,7 @@ AC_SUBST(SELINUX_CFLAGS)
AC_SUBST(SELINUX_LIBS)
# WEBRTC APM support
-AC_ARG_ENABLE([webrtc-apm], AS_HELP_STRING([--enable-webrtc-apm], [Enable webrtc-apm uses]), have_webrtc_apm=$enableval, have_webrtc_apm=no)
+AC_ARG_ENABLE([webrtc-apm], AS_HELP_STRING([--disable-webrtc-apm], [Disable webrtc-apm uses]), have_webrtc_apm=$enableval, have_webrtc_apm=yes)
AM_CONDITIONAL(HAVE_WEBRTC_APM, test "$have_webrtc_apm" = "yes")
if test "$have_webrtc_apm" = "yes"; then
PKG_CHECK_MODULES([WEBRTC_APM], [ libwebrtc_apm ])
@@ -63,23 +58,7 @@ else
fi
AC_SUBST(WEBRTC_APM_LIBS)
-# Build fuzzer binaries
-AC_ARG_ENABLE([fuzzer], AS_HELP_STRING([--enable-fuzzer], [Enable fuzzer build]), have_fuzzer=$enableval, have_fuzzer=no)
-AM_CONDITIONAL(HAVE_FUZZER, test "$have_fuzzer" = "yes")
-if test "$have_fuzzer" = "yes"; then
- AC_DEFINE(HAVE_FUZZER, 1, [Define to build fuzzers.])
-fi
-
PKG_CHECK_MODULES([SBC], [ sbc >= 1.0 ])
-AC_CHECK_HEADERS([iniparser/iniparser.h iniparser.h], [FOUND_INIPARSER=1;break])
-test [$FOUND_INIPARSER] || AC_MSG_ERROR([Missing iniparser, please install.])
-AC_SEARCH_LIBS([LADSPA], [ladspa-sdk], [], [
- AC_CHECK_HEADERS([ladspa.h], [], [
- AC_MSG_ERROR([Missing ladspa-sdk, please install.])
- ])
-])
-PKG_CHECK_MODULES([UDEV], [ libudev >= 1.0 ])
-PKG_CHECK_MODULES([GTEST], [ gtest >= 1.0 ])
AC_CHECK_LIB(asound, snd_pcm_ioplug_create,,
AC_ERROR([*** libasound has no external plugin SDK]), -ldl)
@@ -89,29 +68,12 @@ AC_ARG_ENABLE([alsa-plugin], AS_HELP_STRING([--disable-alsa-plugin],
AC_ARG_ENABLE([metrics], AS_HELP_STRING([--enable-metrics], [Enable metrics uses]), have_metrics=$enableval, have_metrics=no)
if test "$have_metrics" = "yes"; then
AC_DEFINE(HAVE_LIB_METRICS, 1, [Define to use libmetrics])
- METRICS_LIBS=-lmetrics
+ METRICS_LIBS=-lmetrics-${BASE_VER}
else
METRICS_LIBS=
fi
AC_SUBST(METRICS_LIBS)
-# Check if the system copy of the cras rust library should be used. If not, make sure cargo and rustc are present to build it.
-AC_ARG_WITH([system-cras-rust],
- AS_HELP_STRING([--with-system-cras-rust], [Use the system provided cras_rust library]),
- with_system_rust=$enableval,
- with_system_rust=no)
-AM_CONDITIONAL(WITH_SYSTEM_RUST, test "$with_system_rust" = "yes")
-if test "$with_system_rust" = "no"; then
- AC_CHECK_PROG(CARGO, [cargo], [yes], [no])
- AS_IF(test x$CARGO = xno,
- AC_MSG_ERROR([cargo is required to build cras rust lib.])
- )
- AC_CHECK_PROG(RUSTC, [rustc], [yes], [no])
- AS_IF(test x$RUSTC = xno,
- AC_MSG_ERROR([rustc is required to build cras rust lib.])
- )
-fi
-
# Determine ALSA plugin directory.
test "x$prefix" = xNONE && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix=$prefix
diff --git a/cras/install_deps.sh b/cras/install_deps.sh
deleted file mode 100755
index 6eac01a6..00000000
--- a/cras/install_deps.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-apt-get install -y \
- automake \
- build-essential \
- cmake \
- g++ \
- gdb \
- git \
- ladspa-sdk \
- libasound-dev \
- libdbus-1-dev \
- libncurses5-dev \
- libsbc-dev \
- libsndfile-dev \
- libspeexdsp-dev \
- libtool \
- libudev-dev \
- wget \
- zip
-cd /tmp
-git clone https://github.com/ndevilla/iniparser.git
-cd iniparser
-make
-cp libiniparser.* /usr/local/lib
-cp src/dictionary.h src/iniparser.h /usr/local/include
-chmod 644 /usr/local/include/dictionary.h /usr/local/include/iniparser.h
-chmod 644 /usr/local/lib/libiniparser.a
-chmod 755 /usr/local/lib/libiniparser.so.*
-
-cd /tmp
-git clone https://github.com/google/googletest.git -b v1.8.x
-cd googletest
-mkdir build
-cd build
-cmake .. -DBUILD_SHARED_LIBS=ON \
- -DINSTALL_GTEST=ON \
- -DCMAKE_INSTALL_PREFIX:PATH=/usr
-make
-make install
-
-# Need to build and install alsa so there is a static lib.
-mkdir -p /tmp/alsa-build &&
- cd /tmp/alsa-build && \
- wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.1.4.1.tar.bz2 && \
- bzip2 -f -d alsa-lib-* && \
- tar xf alsa-lib-* && \
- cd alsa-lib-* && \
- ./configure --enable-static --disable-shared && \
- make clean && \
- make -j$(nproc) all && \
- make install
diff --git a/cras/src/Android.bp b/cras/src/Android.bp
index 17b9919a..070e6cae 100644
--- a/cras/src/Android.bp
+++ b/cras/src/Android.bp
@@ -1,13 +1,3 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "external_adhd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-BSD
- // SPDX-license-identifier-LGPL
- default_applicable_licenses: ["external_adhd_license"],
-}
-
cc_library_static {
name: "libcras",
diff --git a/cras/src/Makefile.am b/cras/src/Makefile.am
index 1e89f811..acc62d4a 100644
--- a/cras/src/Makefile.am
+++ b/cras/src/Makefile.am
@@ -41,12 +41,10 @@ COMMON_CPPFLAGS = -O2 -Wall -Werror -Wno-error=cpp
COMMON_SIMD_CPPFLAGS = -O3 -Wall -Werror -Wno-error=cpp
bin_PROGRAMS = cras cras_test_client cras_monitor cras_router
-noinst_PROGRAMS =
if HAVE_DBUS
CRAS_DBUS_SOURCES = \
common/cras_sbc_codec.c \
- common/packet_status_logger.c \
server/cras_bt_manager.c \
server/cras_bt_adapter.c \
server/cras_bt_device.c \
@@ -55,7 +53,6 @@ CRAS_DBUS_SOURCES = \
server/cras_bt_player.c \
server/cras_bt_io.c \
server/cras_bt_profile.c \
- server/cras_bt_battery_provider.c \
server/cras_dbus.c \
server/cras_dbus_util.c \
server/cras_dbus_control.c \
@@ -109,7 +106,7 @@ cras_server_SOURCES = \
server/buffer_share.c \
server/config/cras_board_config.c \
server/config/cras_card_config.c \
- server/config/cras_device_blocklist.c \
+ server/config/cras_device_blacklist.c \
server/cras_alert.c \
server/cras_alsa_card.c \
server/cras_alsa_helpers.c \
@@ -117,7 +114,6 @@ cras_server_SOURCES = \
server/cras_alsa_jack.c \
server/cras_alsa_mixer.c \
server/cras_alsa_mixer_name.c \
- server/cras_alsa_plugin_io.c \
server/cras_alsa_ucm.c \
server/cras_alsa_ucm_section.c \
server/cras_audio_area.c \
@@ -147,9 +143,7 @@ cras_server_SOURCES = \
server/cras_control_rclient.c \
server/cras_playback_rclient.c \
server/cras_capture_rclient.c \
- server/cras_unified_rclient.c \
server/cras_rstream.c \
- server/cras_rstream_config.c \
server/cras_server_metrics.c \
server/cras_system_state.c \
server/cras_tm.c \
@@ -157,26 +151,22 @@ cras_server_SOURCES = \
server/cras_volume_curve.c \
server/dev_io.c \
server/dev_stream.c \
- server/ewma_power.c \
server/input_data.c \
server/linear_resampler.c \
server/polled_interval_checker.c \
server/server_stream.c \
server/stream_list.c \
server/test_iodev.c \
+ server/rate_estimator.c \
server/softvol_curve.c
-SERVER_RUST_SRCDIR = $(top_srcdir)/src/server/rust
-
libcrasserver_la_SOURCES = \
$(cras_server_SOURCES)
libcrasserver_la_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/dsp -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/server/config -I$(top_srcdir)/src/plc \
- -I$(SERVER_RUST_SRCDIR)/src/headers \
$(DBUS_CFLAGS) $(SBC_CFLAGS) $(SELINUX_CFLAGS)
libcrasserver_la_LIBADD = \
- $(CRAS_RUST) \
libcrasmix.la \
$(CRAS_SSE4_2) \
$(CRAS_AVX) \
@@ -203,7 +193,6 @@ cras_LDADD = \
$(CRAS_AVX) \
$(CRAS_AVX2) \
$(CRAS_FMA) \
- $(CRAS_RUST) \
-lpthread -lasound -lrt -liniparser -ludev -ldl -lm -lspeexdsp \
$(METRICS_LIBS) \
$(SBC_LIBS) \
@@ -283,7 +272,6 @@ include_HEADERS = \
common/cras_types.h \
common/cras_util.h \
common/edid_utils.h \
- common/packet_status_logger.h \
common/utlist.h \
libcras/cras_client.h \
libcras/cras_helpers.h
@@ -310,28 +298,6 @@ libasound_module_pcm_cras_la_LIBADD = -lasound libcras.la
libasound_module_ctl_cras_la_SOURCES = alsa_plugin/ctl_cras.c
libasound_module_ctl_cras_la_LIBADD = -lasound libcras.la
-if !WITH_SYSTEM_RUST
-RUST_FILES = \
- $(SERVER_RUST_SRCDIR)/Cargo.toml \
- $(SERVER_RUST_SRCDIR)/src/rate_estimator_bindings.rs \
- $(SERVER_RUST_SRCDIR)/src/rate_estimator.rs
-
-CRAS_RUST_TARGET_DIR = $(top_builddir)/src/server/rust/target
-CRAS_RUST = $(CRAS_RUST_TARGET_DIR)/release/libcras_rust.a
-$(CRAS_RUST): $(RUST_FILES)
- cargo build --release \
- --manifest-path $(SERVER_RUST_SRCDIR)/Cargo.toml \
- --target-dir $(CRAS_RUST_TARGET_DIR)
-
-clean-local:
- cargo clean --release \
- --manifest-path $(SERVER_RUST_SRCDIR)/Cargo.toml \
- --target-dir $(CRAS_RUST_TARGET_DIR)
-
-else
-CRAS_RUST = -lcras_rust
-endif
-
# Inject a dependency between the installation rules of libcras and its modules.
# This avoids a race when the modules are relinked before libcras is actually
# installed.
@@ -343,50 +309,6 @@ hide_install=install
$(hide_install)-asound_module_pcm_crasLTLIBRARIES: install-libLTLIBRARIES
$(hide_install)-asound_module_ctl_crasLTLIBRARIES: install-libLTLIBRARIES
-# ==== Fuzzer section
-if HAVE_FUZZER
-FUZZERS = \
- cras_rclient_message_fuzzer \
- cras_hfp_slc_fuzzer
-
-noinst_PROGRAMS += $(FUZZERS)
-
-FUZZER_CPPFLAGS = $(COMMON_CPPFLAGS) \
- -I$(top_srcdir)/src/common \
- -I$(top_srcdir)/src/dsp -I$(top_srcdir)/src/server \
- -I$(top_srcdir)/src/server/config -I$(top_srcdir)/src/plc \
- $(DBUS_CFLAGS) $(SBC_CFLAGS)
-
-FUZZER_LDADD = \
- libcrasmix.la \
- libcrasserver.la \
- $(CRAS_SSE4_2) \
- $(CRAS_AVX) \
- $(CRAS_AVX2) \
- $(CRAS_FMA) \
- $(CRAS_RUST) \
- -lpthread -lasound -lrt -liniparser -ludev -ldl -lm -lspeexdsp \
- $(METRICS_LIBS) \
- $(SBC_LIBS) \
- $(DBUS_LIBS) \
- $(WEBRTC_APM_LIBS)
-
-cras_rclient_message_fuzzer_SOURCES = \
- fuzz/rclient_message.cc
-
-cras_rclient_message_fuzzer_CPPFLAGS = $(FUZZER_CPPFLAGS)
-cras_rclient_message_fuzzer_LDFLAGS = $(FUZZER_LDFLAGS)
-cras_rclient_message_fuzzer_LDADD = $(FUZZER_LDADD)
-
-cras_hfp_slc_fuzzer_SOURCES = \
- fuzz/cras_hfp_slc.cc
-
-cras_hfp_slc_fuzzer_CPPFLAGS = $(FUZZER_CPPFLAGS)
-cras_hfp_slc_fuzzer_LDFLAGS = $(FUZZER_LDFLAGS)
-cras_hfp_slc_fuzzer_LDADD = $(FUZZER_LDADD)
-endif
-
-# ==== Tests section
if HAVE_DBUS
DBUS_TESTS = \
a2dp_info_unittest \
@@ -427,13 +349,12 @@ TESTS = \
byte_buffer_unittest \
card_config_unittest \
checksum_unittest \
- cras_abi_unittest \
cras_client_unittest \
cras_tm_unittest \
device_monitor_unittest \
dev_io_unittest \
dev_stream_unittest \
- device_blocklist_unittest \
+ device_blacklist_unittest \
dsp_core_unittest \
dsp_ini_unittest \
dsp_pipeline_unittest \
@@ -442,7 +363,6 @@ TESTS = \
edid_utils_unittest \
empty_iodev_unittest \
expr_unittest \
- ewma_power_unittest \
file_wait_unittest \
float_buffer_unittest \
fmt_conv_unittest \
@@ -615,7 +535,8 @@ a2dp_info_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/common
a2dp_info_unittest_LDADD = -lgtest -lpthread
-a2dp_iodev_unittest_SOURCES = tests/a2dp_iodev_unittest.cc
+a2dp_iodev_unittest_SOURCES = tests/a2dp_iodev_unittest.cc \
+ server/cras_a2dp_iodev.c common/sfh.c
a2dp_iodev_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/common $(DBUS_CFLAGS)
a2dp_iodev_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
@@ -676,8 +597,7 @@ audio_thread_unittest_SOURCES = tests/audio_thread_unittest.cc \
server/dev_io.c tests/empty_audio_stub.cc tests/metrics_stub.cc \
common/cras_shm.c
audio_thread_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
- -I$(top_srcdir)/src/common -I$(top_srcdir)/src/server \
- -I$(SERVER_RUST_SRCDIR)/src/headers
+ -I$(top_srcdir)/src/common -I$(top_srcdir)/src/server
audio_thread_unittest_LDADD = -lgtest -lpthread -lrt
audio_thread_monitor_unittest_SOURCES = tests/audio_thread_monitor_unittest.cc
@@ -687,8 +607,7 @@ audio_thread_monitor_unittest_LDADD = -lgtest -lpthread -lrt
if HAVE_DBUS
bt_device_unittest_SOURCES = tests/bt_device_unittest.cc \
- server/cras_bt_device.c \
- tests/metrics_stub.cc common/sfh.c
+ server/cras_bt_device.c
bt_device_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/common $(DBUS_CFLAGS)
bt_device_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
@@ -720,13 +639,6 @@ checksum_unittest_SOURCES = tests/checksum_unittest.cc common/cras_checksum.c
checksum_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common
checksum_unittest_LDADD = -lgtest -lpthread
-cras_abi_unittest_SOURCES = tests/cras_abi_unittest.cc \
- common/cras_config.c common/cras_shm.c common/cras_util.c \
- common/cras_file_wait.c common/cras_audio_format.c
-cras_abi_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
- -I$(top_srcdir)/src/libcras
-cras_abi_unittest_LDADD = -lgtest -lpthread -lrt -lspeexdsp
-
cras_client_unittest_SOURCES = tests/cras_client_unittest.cc \
common/cras_config.c common/cras_shm.c common/cras_util.c \
common/cras_file_wait.c
@@ -756,7 +668,6 @@ dev_io_unittest_CPPFLAGS = \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/server/config \
- -I$(SERVER_RUST_SRCDIR)/src/headers \
$(SELINUX_CFLAGS)
dev_io_unittest_LDADD = \
libcrasmix.la \
@@ -773,12 +684,12 @@ dev_stream_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common -I$(top_srcdir)/src/server
dev_stream_unittest_LDADD = -lgtest -liniparser -lpthread -lrt
-device_blocklist_unittest_SOURCES = tests/device_blocklist_unittest.cc \
- server/config/cras_device_blocklist.c
-device_blocklist_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
+device_blacklist_unittest_SOURCES = tests/device_blacklist_unittest.cc \
+ server/config/cras_device_blacklist.c
+device_blacklist_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/server/config $(CRAS_UT_TMPDIR_CFLAGS)
-device_blocklist_unittest_LDADD = -lgtest -liniparser -lpthread
+device_blacklist_unittest_LDADD = -lgtest -liniparser -lpthread
device_monitor_unittest_SOURCES = tests/device_monitor_unittest.cc
device_monitor_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
@@ -863,13 +774,13 @@ hfp_info_unittest_LDADD = -lgtest -lpthread
if HAVE_DBUS
hfp_iodev_unittest_SOURCES = tests/hfp_iodev_unittest.cc \
- server/cras_hfp_iodev.c
+ server/cras_hfp_iodev.c common/sfh.c
hfp_iodev_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server $(DBUS_CFLAGS)
hfp_iodev_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
hfp_alsa_iodev_unittest_SOURCES = tests/hfp_alsa_iodev_unittest.cc \
- server/cras_hfp_alsa_iodev.c
+ server/cras_hfp_alsa_iodev.c common/sfh.c
hfp_alsa_iodev_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common -I$(top_srcdir)/src/server $(DBUS_CFLAGS)
hfp_alsa_iodev_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
@@ -881,7 +792,7 @@ hfp_ag_profile_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
hfp_ag_profile_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
hfp_slc_unittest_SOURCES = tests/hfp_slc_unittest.cc \
- server/cras_hfp_slc.c tests/metrics_stub.cc
+ server/cras_hfp_slc.c
hfp_slc_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server $(DBUS_CFLAGS)
hfp_slc_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
@@ -893,14 +804,6 @@ buffer_share_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common -I$(top_srcdir)/src/server
buffer_share_unittest_LDADD = -lgtest -liniparser -lpthread
-ewma_power_unittest_SOURCES = tests/ewma_power_unittest.cc \
- common/cras_audio_format.c server/cras_audio_area.c \
- server/ewma_power.c
-
-ewma_power_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
- -I$(top_srcdir)/src/common -I$(top_srcdir)/src/server
-ewma_power_unittest_LDADD = -lgtest
-
iodev_list_unittest_SOURCES = tests/iodev_list_unittest.cc \
server/cras_iodev_list.c
iodev_list_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
@@ -908,11 +811,11 @@ iodev_list_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
iodev_list_unittest_LDADD = -lgtest -lpthread
loopback_iodev_unittest_SOURCES = tests/loopback_iodev_unittest.cc \
- server/cras_loopback_iodev.c common/cras_shm.c common/sfh.c
+ server/cras_loopback_iodev.c common/sfh.c
loopback_iodev_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server
-loopback_iodev_unittest_LDADD = -lgtest -lpthread -lrt
+loopback_iodev_unittest_LDADD = -lgtest -lpthread
input_data_unittest_SOURCES = tests/input_data_unittest.cc \
server/input_data.c
@@ -923,8 +826,7 @@ input_data_unittest_LDADD = -lgtest -lpthread
iodev_unittest_SOURCES = tests/iodev_unittest.cc \
server/cras_iodev.c common/cras_shm.c
iodev_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
- -I$(top_srcdir)/src/server \
- -I$(SERVER_RUST_SRCDIR)/src/headers
+ -I$(top_srcdir)/src/server
iodev_unittest_LDADD = -lgtest -lpthread -lrt
mix_unittest_SOURCES = tests/mix_unittest.cc server/cras_mix.c
@@ -960,37 +862,31 @@ ramp_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server
ramp_unittest_LDADD = -lgtest -lpthread
-rate_estimator_unittest_SOURCES = tests/rate_estimator_unittest.cc
+rate_estimator_unittest_SOURCES = tests/rate_estimator_unittest.cc server/rate_estimator.c
rate_estimator_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
- -I$(top_srcdir)/src/server \
- -I$(SERVER_RUST_SRCDIR)/src/headers
-rate_estimator_unittest_LDADD = $(CRAS_RUST) -lgtest -ldl -lpthread
+ -I$(top_srcdir)/src/server
+rate_estimator_unittest_LDADD = -lgtest -lpthread
-control_rclient_unittest_SOURCES = tests/control_rclient_unittest.cc \
- server/cras_rstream_config.c
+control_rclient_unittest_SOURCES = tests/control_rclient_unittest.cc
control_rclient_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common \
- -I$(top_srcdir)/src/server $(CRAS_UT_TMPDIR_CFLAGS) \
- $(DBUS_CFLAGS)
-control_rclient_unittest_LDADD = -lgtest -lpthread $(DBUS_LIBS)
+ -I$(top_srcdir)/src/server $(CRAS_UT_TMPDIR_CFLAGS)
+control_rclient_unittest_LDADD = -lgtest -lpthread
-playback_rclient_unittest_SOURCES = tests/playback_rclient_unittest.cc \
- server/cras_rstream_config.c
+playback_rclient_unittest_SOURCES = tests/playback_rclient_unittest.cc
playback_rclient_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server $(CRAS_UT_TMPDIR_CFLAGS)
playback_rclient_unittest_LDADD = -lgtest -lpthread
-capture_rclient_unittest_SOURCES = tests/capture_rclient_unittest.cc \
- server/cras_rstream_config.c
+capture_rclient_unittest_SOURCES = tests/capture_rclient_unittest.cc
capture_rclient_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server $(CRAS_UT_TMPDIR_CFLAGS)
capture_rclient_unittest_LDADD = -lgtest -lpthread
rstream_unittest_SOURCES = tests/rstream_unittest.cc server/cras_rstream.c \
- common/cras_shm.c tests/metrics_stub.cc \
- server/cras_rstream_config.c $(CRAS_SELINUX_UNITTEST_SOURCES)
+ common/cras_shm.c $(CRAS_SELINUX_UNITTEST_SOURCES)
rstream_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) -I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server $(SELINUX_CFLAGS)
rstream_unittest_LDADD = $(SELINUX_LIBS) \
@@ -1018,7 +914,7 @@ stream_list_unittest_LDADD = -lgtest -lpthread
system_state_unittest_SOURCES = tests/system_state_unittest.cc \
server/cras_system_state.c common/cras_shm.c \
- $(CRAS_SELINUX_UNITTEST_SOURCES)
+ server/config/cras_board_config.c $(CRAS_SELINUX_UNITTEST_SOURCES)
system_state_unittest_CPPFLAGS = $(COMMON_CPPFLAGS) \
-I$(top_srcdir)/src/common -I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/server/config $(SELINUX_CFLAGS)
@@ -1050,7 +946,6 @@ timing_unittest_CPPFLAGS = \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/server \
-I$(top_srcdir)/src/server/config \
- -I$(SERVER_RUST_SRCDIR)/src/headers \
$(SELINUX_CFLAGS)
timing_unittest_LDADD = \
libcrasmix.la \
diff --git a/cras/src/alsa_plugin/ctl_cras.c b/cras/src/alsa_plugin/ctl_cras.c
index 76b0c039..822b63ab 100644
--- a/cras/src/alsa_plugin/ctl_cras.c
+++ b/cras/src/alsa_plugin/ctl_cras.c
@@ -14,6 +14,8 @@ static const size_t MAX_IONODES = 20; /* Max ionodes to print out. */
enum CTL_CRAS_MIXER_CONTROLS {
CTL_CRAS_MIXER_PLAYBACK_SWITCH,
CTL_CRAS_MIXER_PLAYBACK_VOLUME,
+ CTL_CRAS_MIXER_CAPTURE_SWITCH,
+ CTL_CRAS_MIXER_CAPTURE_VOLUME,
NUM_CTL_CRAS_MIXER_ELEMS
};
@@ -31,6 +33,10 @@ static const struct cras_mixer_control cras_elems[NUM_CTL_CRAS_MIXER_ELEMS] = {
SND_CTL_EXT_ACCESS_READWRITE, 1 },
{ "Master Playback Volume", SND_CTL_ELEM_TYPE_INTEGER,
SND_CTL_EXT_ACCESS_READWRITE, 1 },
+ { "Capture Switch", SND_CTL_ELEM_TYPE_BOOLEAN,
+ SND_CTL_EXT_ACCESS_READWRITE, 1 },
+ { "Capture Volume", SND_CTL_ELEM_TYPE_INTEGER,
+ SND_CTL_EXT_ACCESS_READWRITE, 1 },
};
/* Holds the client and ctl plugin pointers. */
@@ -113,6 +119,46 @@ static int ctl_cras_get_integer_info(snd_ctl_ext_t *ext_ctl,
return 0;
}
+static long capture_index_to_gain(struct cras_client *client, long index)
+{
+ long min;
+ long max;
+ long dB_step;
+
+ min = cras_client_get_system_min_capture_gain(client);
+ max = cras_client_get_system_max_capture_gain(client);
+ if (min >= max)
+ return min;
+
+ dB_step = (max - min) / 100;
+
+ if (index <= 0)
+ return min;
+ if (index >= 100)
+ return max;
+ return index * dB_step + min;
+}
+
+static long capture_gain_to_index(struct cras_client *client, long gain)
+{
+ long min;
+ long max;
+ long dB_step;
+
+ min = cras_client_get_system_min_capture_gain(client);
+ max = cras_client_get_system_max_capture_gain(client);
+ if (min >= max)
+ return 0;
+
+ dB_step = (max - min) / 100;
+
+ if (gain <= min)
+ return 0;
+ if (gain >= max)
+ return 100;
+ return (gain - min) / dB_step;
+}
+
static int get_nodes(struct cras_client *client, enum CRAS_STREAM_DIRECTION dir,
struct cras_ionode_info *nodes, size_t num_nodes)
{
@@ -153,6 +199,20 @@ static int ctl_cras_read_integer(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
break;
}
break;
+ case CTL_CRAS_MIXER_CAPTURE_SWITCH:
+ *value = !cras_client_get_system_capture_muted(cras->client);
+ break;
+ case CTL_CRAS_MIXER_CAPTURE_VOLUME:
+ num_nodes = get_nodes(cras->client, CRAS_STREAM_INPUT, nodes,
+ MAX_IONODES);
+ for (i = 0; i < num_nodes; i++) {
+ if (!nodes[i].active)
+ continue;
+ *value = capture_gain_to_index(cras->client,
+ nodes[i].capture_gain);
+ break;
+ }
+ break;
default:
return -EINVAL;
}
@@ -167,6 +227,7 @@ static int ctl_cras_write_integer(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
struct ctl_cras *cras = (struct ctl_cras *)ext_ctl->private_data;
struct cras_ionode_info nodes[MAX_IONODES];
int num_nodes, i;
+ long gain;
switch (key) {
case CTL_CRAS_MIXER_PLAYBACK_SWITCH:
@@ -185,6 +246,23 @@ static int ctl_cras_write_integer(snd_ctl_ext_t *ext_ctl, snd_ctl_ext_key_t key,
*value);
}
break;
+ case CTL_CRAS_MIXER_CAPTURE_SWITCH:
+ cras_client_set_system_capture_mute(cras->client, !(*value));
+ break;
+ case CTL_CRAS_MIXER_CAPTURE_VOLUME:
+ gain = capture_index_to_gain(cras->client, *value);
+ num_nodes = get_nodes(cras->client, CRAS_STREAM_INPUT, nodes,
+ MAX_IONODES);
+ for (i = 0; i < num_nodes; i++) {
+ if (!nodes[i].active)
+ continue;
+ cras_client_set_node_capture_gain(
+ cras->client,
+ cras_make_node_id(nodes[i].iodev_idx,
+ nodes[i].ionode_idx),
+ gain);
+ }
+ break;
default:
return -EINVAL;
}
diff --git a/cras/src/alsa_plugin/pcm_cras.c b/cras/src/alsa_plugin/pcm_cras.c
index 7bc960bc..715db2cc 100644
--- a/cras/src/alsa_plugin/pcm_cras.c
+++ b/cras/src/alsa_plugin/pcm_cras.c
@@ -124,7 +124,7 @@ static int pcm_cras_process_cb(struct cras_client *client,
struct snd_pcm_cras *pcm_cras;
const snd_pcm_channel_area_t *areas;
snd_pcm_uframes_t copied_frames;
- char empty_byte;
+ char dummy_byte;
size_t chan, frame_bytes, sample_bytes;
int rc;
uint8_t *samples;
@@ -196,7 +196,7 @@ static int pcm_cras_process_cb(struct cras_client *client,
copied_frames += frames;
}
- rc = write(pcm_cras->fd, &empty_byte, 1); /* Wake up polling clients. */
+ rc = write(pcm_cras->fd, &dummy_byte, 1); /* Wake up polling clients. */
if (rc < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
fprintf(stderr, "%s write failed %d\n", __func__, errno);
diff --git a/cras/src/common/bluetooth.h b/cras/src/common/bluetooth.h
index 66beadad..155b5e00 100644
--- a/cras/src/common/bluetooth.h
+++ b/cras/src/common/bluetooth.h
@@ -74,11 +74,3 @@ struct bt_voice {
};
#define BT_VOICE_TRANSPARENT 0x0003
-
-#define BT_SNDMTU 12
-
-#define BT_RCVMTU 13
-
-#define BT_PKT_STATUS 16
-
-#define BT_SCM_PKT_STATUS 0x03
diff --git a/cras/src/common/cras_audio_format.c b/cras/src/common/cras_audio_format.c
index 8bd48656..f504dfc3 100644
--- a/cras/src/common/cras_audio_format.c
+++ b/cras/src/common/cras_audio_format.c
@@ -62,7 +62,7 @@ int cras_audio_format_set_channel_layout(struct cras_audio_format *format,
* channel count set in format.
*/
for (i = 0; i < CRAS_CH_MAX; i++)
- if (layout[i] < -1 || layout[i] >= (int)format->num_channels)
+ if (layout[i] >= (int)format->num_channels)
return -EINVAL;
for (i = 0; i < CRAS_CH_MAX; i++)
@@ -71,19 +71,6 @@ int cras_audio_format_set_channel_layout(struct cras_audio_format *format,
return 0;
}
-/* Verifies if all channel_layout[i] are in [-1, fmt->num_channels). */
-bool cras_audio_format_valid(const struct cras_audio_format *fmt)
-{
- int i;
- for (i = 0; i < CRAS_CH_MAX; i++) {
- if (fmt->channel_layout[i] < -1 ||
- fmt->channel_layout[i] >= (int)fmt->num_channels) {
- return false;
- }
- }
- return true;
-}
-
/* Destroy an audio format struct created with cras_audio_format_crate. */
void cras_audio_format_destroy(struct cras_audio_format *fmt)
{
diff --git a/cras/src/common/cras_audio_format.h b/cras/src/common/cras_audio_format.h
index f0cc94f4..47bb5c59 100644
--- a/cras/src/common/cras_audio_format.h
+++ b/cras/src/common/cras_audio_format.h
@@ -10,7 +10,6 @@
extern "C" {
#endif
-#include <stdbool.h>
#include <stdint.h>
#include <string.h>
@@ -106,16 +105,15 @@ static inline void pack_cras_audio_format(struct cras_audio_format_packed *dest,
sizeof(src->channel_layout));
}
-static inline struct cras_audio_format
-unpack_cras_audio_format(const struct cras_audio_format_packed *src)
+static inline void
+unpack_cras_audio_format(struct cras_audio_format *dest,
+ const struct cras_audio_format_packed *src)
{
- struct cras_audio_format dest;
- dest.format = (snd_pcm_format_t)src->format;
- dest.frame_rate = src->frame_rate;
- dest.num_channels = src->num_channels;
- memcpy(dest.channel_layout, src->channel_layout,
+ dest->format = (snd_pcm_format_t)src->format;
+ dest->frame_rate = src->frame_rate;
+ dest->num_channels = src->num_channels;
+ memcpy(dest->channel_layout, src->channel_layout,
sizeof(src->channel_layout));
- return dest;
}
/* Returns the number of bytes per sample.
@@ -145,9 +143,6 @@ struct cras_audio_format *cras_audio_format_create(snd_pcm_format_t format,
/* Destroy an audio format struct created with cras_audio_format_crate. */
void cras_audio_format_destroy(struct cras_audio_format *fmt);
-/* Returns true if the audio format is valid */
-bool cras_audio_format_valid(const struct cras_audio_format *fmt);
-
/* Sets the channel layout for given format.
* format - The format structure to carry channel layout info
* layout - An integer array representing the position of each
diff --git a/cras/src/common/cras_config.c b/cras/src/common/cras_config.c
index 75fa24e7..335b7849 100644
--- a/cras/src/common/cras_config.c
+++ b/cras/src/common/cras_config.c
@@ -38,18 +38,6 @@ int cras_fill_socket_path(enum CRAS_CONNECTION_TYPE conn_type, char *sock_path)
case CRAS_CAPTURE:
sock_file = CRAS_CAPTURE_SOCKET_FILE;
break;
- case CRAS_VMS_LEGACY:
- sock_file = CRAS_VMS_LEGACY_SOCKET_FILE;
- break;
- case CRAS_VMS_UNIFIED:
- sock_file = CRAS_VMS_UNIFIED_SOCKET_FILE;
- break;
- case CRAS_PLUGIN_PLAYBACK:
- sock_file = CRAS_PLUGIN_PLAYBACK_SOCKET_FILE;
- break;
- case CRAS_PLUGIN_UNIFIED:
- sock_file = CRAS_PLUGIN_UNIFIED_SOCKET_FILE;
- break;
default:
return -EINVAL;
}
diff --git a/cras/src/common/cras_config.h b/cras/src/common/cras_config.h
index 1c8e55fa..8b1e6135 100644
--- a/cras/src/common/cras_config.h
+++ b/cras/src/common/cras_config.h
@@ -9,7 +9,6 @@
#include "cras_types.h"
#define CRAS_MIN_BUFFER_TIME_IN_US 1000 /* 1 milliseconds */
-#define CRAS_MAX_BUFFER_TIME_IN_S 10 /* 10 seconds */
#define CRAS_SERVER_RT_THREAD_PRIORITY 12
#define CRAS_CLIENT_RT_THREAD_PRIORITY 10
@@ -17,12 +16,6 @@
#define CRAS_SOCKET_FILE ".cras_socket"
#define CRAS_PLAYBACK_SOCKET_FILE ".cras_playback"
#define CRAS_CAPTURE_SOCKET_FILE ".cras_capture"
-/* Socket file paths for VMs. */
-#define CRAS_VMS_LEGACY_SOCKET_FILE "vms/.cras_socket"
-#define CRAS_VMS_UNIFIED_SOCKET_FILE "vms/.cras_unified"
-/* Socket file paths for pluginVM. */
-#define CRAS_PLUGIN_PLAYBACK_SOCKET_FILE "vms/plugin/playback/.cras_socket"
-#define CRAS_PLUGIN_UNIFIED_SOCKET_FILE "vms/plugin/unified/.cras_socket"
/* Maximum socket_path size, which is equals to sizeof(sun_path) in sockaddr_un
* structure.
diff --git a/cras/src/common/cras_file_wait.c b/cras/src/common/cras_file_wait.c
index 190a5e10..9ad94486 100644
--- a/cras/src/common/cras_file_wait.c
+++ b/cras/src/common/cras_file_wait.c
@@ -190,7 +190,7 @@ int cras_file_wait_dispatch(struct cras_file_wait *file_wait)
strcpy(file_wait->watch_dir, file_wait->file_path);
watch_dir_len = file_wait->file_path_len;
- while (rc == -ENOENT || rc == -EACCES) {
+ while (rc == -ENOENT) {
strcpy(file_wait->watch_path, file_wait->watch_dir);
watch_path_len = watch_dir_len;
diff --git a/cras/src/common/cras_iodev_info.h b/cras/src/common/cras_iodev_info.h
index 85d20f90..5317ddee 100644
--- a/cras/src/common/cras_iodev_info.h
+++ b/cras/src/common/cras_iodev_info.h
@@ -19,13 +19,11 @@
* idx - iodev index.
* name - Name displayed to the user.
* stable_id - ID that does not change due to device plug/unplug or reboot.
- * max_supported_channels - Max supported channel count of this device.
*/
struct __attribute__((__packed__)) cras_iodev_info {
uint32_t idx;
char name[CRAS_IODEV_NAME_BUFFER_SIZE];
uint32_t stable_id;
- uint32_t max_supported_channels;
};
/* Identifying information about an ionode on an iodev.
@@ -36,9 +34,9 @@ struct __attribute__((__packed__)) cras_iodev_info {
* active - If this is the node currently being used.
* volume - per-node volume (0-100)
* capture_gain - per-node capture gain/attenuation (in 100*dBFS)
- * ui_gain_scaler - Adjustable gain scaler set by Chrome.
* left_right_swapped - Set true if left and right channels are swapped.
* stable_id - ID that does not change due to device plug/unplug or reboot.
+ * mic_positions - Positions of the mic array.
* type - Type displayed to the user.
* name - Name displayed to the user.
* active_hotword_model - name of the currently selected hotword model.
@@ -54,10 +52,10 @@ struct __attribute__((__packed__)) cras_ionode_info {
} plugged_time;
uint32_t volume;
int32_t capture_gain;
- float ui_gain_scaler;
int32_t left_right_swapped;
uint32_t type_enum;
uint32_t stable_id;
+ char mic_positions[CRAS_NODE_MIC_POS_BUFFER_SIZE];
char type[CRAS_NODE_TYPE_BUFFER_SIZE];
char name[CRAS_NODE_NAME_BUFFER_SIZE];
char active_hotword_model[CRAS_NODE_HOTWORD_MODEL_BUFFER_SIZE];
diff --git a/cras/src/common/cras_messages.h b/cras/src/common/cras_messages.h
index 50cbe7cd..195965bb 100644
--- a/cras/src/common/cras_messages.h
+++ b/cras/src/common/cras_messages.h
@@ -16,11 +16,11 @@
/* Rev when message format changes. If new messages are added, or message ID
* values change. */
-#define CRAS_PROTO_VER 7
+#define CRAS_PROTO_VER 5
#define CRAS_SERV_MAX_MSG_SIZE 256
#define CRAS_CLIENT_MAX_MSG_SIZE 256
#define CRAS_MAX_HOTWORD_MODELS 243
-#define CRAS_MAX_REMIX_CHANNELS 8
+#define CRAS_MAX_REMIX_CHANNELS 32
#define CRAS_MAX_TEST_DATA_LEN 224
#define CRAS_AEC_DUMP_FILE_NAME_LEN 128
@@ -34,7 +34,7 @@ enum CRAS_SERVER_MESSAGE_ID {
CRAS_SERVER_SET_SYSTEM_MUTE,
CRAS_SERVER_SET_USER_MUTE,
CRAS_SERVER_SET_SYSTEM_MUTE_LOCKED,
- CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN, /* Deprecated */
+ CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN,
CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE,
CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE_LOCKED,
CRAS_SERVER_SET_NODE_ATTR,
@@ -58,7 +58,6 @@ enum CRAS_SERVER_MESSAGE_ID {
CRAS_SERVER_DUMP_BT,
CRAS_SERVER_SET_BT_WBS_ENABLED,
CRAS_SERVER_GET_ATLOG_FD,
- CRAS_SERVER_DUMP_MAIN,
};
enum CRAS_CLIENT_MESSAGE_ID {
@@ -114,10 +113,28 @@ struct __attribute__((__packed__)) cras_connect_message {
uint32_t dev_idx; /* device to attach stream, 0 if none */
uint64_t effects; /* Bit map of requested effects. */
enum CRAS_CLIENT_TYPE client_type; /* chrome, or arc, etc. */
- uint64_t client_shm_size; /* Size of client-provided samples shm, if any */
- /* Initial values for shm samples buffer offsets. These will be 0 for
- * streams that do not use client-provided shm */
- uint64_t buffer_offsets[2];
+ uint32_t client_shm_size; /* Size of client-provided samples shm, if any */
+};
+
+/*
+ * Old version of connect message without 'cras_type' and 'client_shm_size'
+ * defined.
+ * Used to check against when receiving invalid size of connect message.
+ * Expected to have proto_version set to 3.
+ * TODO(yuhsuan): remove when all clients migrate to latest libcras.
+ */
+struct __attribute__((__packed__)) cras_connect_message_old {
+ struct cras_server_message header;
+ uint32_t proto_version;
+ enum CRAS_STREAM_DIRECTION direction; /* input/output/loopback */
+ cras_stream_id_t stream_id; /* unique id for this stream */
+ enum CRAS_STREAM_TYPE stream_type; /* media, or call, etc. */
+ uint32_t buffer_frames; /* Buffer size in frames. */
+ uint32_t cb_threshold; /* callback client when this much is left */
+ uint32_t flags;
+ struct cras_audio_format_packed format; /* rate, channel, sample size */
+ uint32_t dev_idx; /* device to attach stream, 0 if none */
+ uint64_t effects; /* Bit map of requested effects. */
};
static inline void cras_fill_connect_message(
@@ -125,7 +142,8 @@ static inline void cras_fill_connect_message(
cras_stream_id_t stream_id, enum CRAS_STREAM_TYPE stream_type,
enum CRAS_CLIENT_TYPE client_type, size_t buffer_frames,
size_t cb_threshold, uint32_t flags, uint64_t effects,
- struct cras_audio_format format, uint32_t dev_idx)
+ struct cras_audio_format format, uint32_t dev_idx,
+ uint32_t client_shm_size)
{
m->proto_version = CRAS_PROTO_VER;
m->direction = direction;
@@ -138,9 +156,7 @@ static inline void cras_fill_connect_message(
pack_cras_audio_format(&m->format, &format);
m->dev_idx = dev_idx;
m->client_type = client_type;
- m->client_shm_size = 0;
- m->buffer_offsets[0] = 0;
- m->buffer_offsets[1] = 0;
+ m->client_shm_size = client_shm_size;
m->header.id = CRAS_SERVER_CONNECT_STREAM;
m->header.length = sizeof(struct cras_connect_message);
}
@@ -179,6 +195,20 @@ static inline void cras_fill_set_system_volume(struct cras_set_system_volume *m,
m->header.length = sizeof(*m);
}
+/* Sets the capture gain. */
+struct __attribute__((__packed__)) cras_set_system_capture_gain {
+ struct cras_server_message header;
+ int32_t gain;
+};
+static inline void
+cras_fill_set_system_capture_gain(struct cras_set_system_capture_gain *m,
+ long gain)
+{
+ m->gain = gain;
+ m->header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN;
+ m->header.length = sizeof(*m);
+}
+
/* Set the system mute state. */
struct __attribute__((__packed__)) cras_set_system_mute {
struct cras_server_message header;
@@ -331,17 +361,6 @@ static inline void cras_fill_get_atlog_fd(struct cras_get_atlog_fd *m)
m->header.length = sizeof(*m);
}
-/* Dump events in CRAS main thread. */
-struct __attribute__((__packed__)) cras_dump_main {
- struct cras_server_message header;
-};
-
-static inline void cras_fill_dump_main(struct cras_dump_main *m)
-{
- m->header.id = CRAS_SERVER_DUMP_MAIN;
- m->header.length = sizeof(*m);
-}
-
/* Dump bluetooth events and state changes. */
struct __attribute__((__packed__)) cras_dump_bt {
struct cras_server_message header;
@@ -415,7 +434,7 @@ static inline void cras_fill_suspend_message(struct cras_server_message *m,
struct __attribute__((__packed__)) cras_config_global_remix {
struct cras_server_message header;
unsigned int num_channels;
- float coefficient[CRAS_MAX_REMIX_CHANNELS * CRAS_MAX_REMIX_CHANNELS];
+ float coefficient[CRAS_MAX_REMIX_CHANNELS];
};
static inline void
@@ -540,8 +559,8 @@ static inline void cras_fill_client_connected(struct cras_client_connected *m,
* Reply from server that a stream has been successfully added.
* Two file descriptors are added, input shm followed by out shm.
*
- * |samples_shm_size| is valid for normal streams, not client-provided
- * shm streams.
+ * samples_shm_size is shm_max_size for old clients.
+ * TODO(fletcherw) remove comment once all clients are on CRAS_PROTO_VER >= 3.
*/
struct __attribute__((__packed__)) cras_client_stream_connected {
struct cras_client_message header;
@@ -561,9 +580,6 @@ cras_fill_client_stream_connected(struct cras_client_stream_connected *m,
m->err = err;
m->stream_id = stream_id;
pack_cras_audio_format(&m->format, format);
- if (samples_shm_size > UINT32_MAX) {
- samples_shm_size = UINT32_MAX;
- }
m->samples_shm_size = samples_shm_size;
m->effects = effects;
m->header.id = CRAS_CLIENT_STREAM_CONNECTED;
diff --git a/cras/src/common/cras_observer_ops.h b/cras/src/common/cras_observer_ops.h
index e73845c9..70dd513c 100644
--- a/cras/src/common/cras_observer_ops.h
+++ b/cras/src/common/cras_observer_ops.h
@@ -47,19 +47,12 @@ struct cras_observer_ops {
void (*num_active_streams_changed)(void *context,
enum CRAS_STREAM_DIRECTION dir,
uint32_t num_active_streams);
- /* Number of input streams with permission changed. */
- void (*num_input_streams_with_permission_changed)(
- void *context,
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE]);
/* Hotword triggered. */
void (*hotword_triggered)(void *context, int64_t tv_sec,
int64_t tv_nsec);
/* State regarding whether non-empty audio is being played/captured has
* changed. */
void (*non_empty_audio_state_changed)(void *context, int non_empty);
- /* Bluetooth headset battery level changed. */
- void (*bt_battery_changed)(void *context, const char *address,
- uint32_t level);
};
#endif /* CRAS_OBSERVER_OPS_H */
diff --git a/cras/src/common/cras_shm.c b/cras/src/common/cras_shm.c
index ecb6169c..3e6c2b7e 100644
--- a/cras/src/common/cras_shm.c
+++ b/cras/src/common/cras_shm.c
@@ -116,31 +116,35 @@ int cras_audio_shm_create(struct cras_shm_info *header_info,
* The parameters are cleared, and the owner of cras_audio_shm is now
* responsible for closing the fds and unlinking any associated shm
* files using cras_audio_shm_destroy.
+ *
+ * The source pointers are updated to point to the moved structs so that
+ * they will be properly cleaned up in the error case.
*/
ret = cras_shm_info_move(header_info, &shm->header_info);
if (ret)
goto free_shm;
+ header_info = &shm->header_info;
ret = cras_shm_info_move(samples_info, &shm->samples_info);
if (ret)
goto free_shm;
+ samples_info = &shm->samples_info;
- shm->header =
- mmap(NULL, shm->header_info.length, PROT_READ | PROT_WRITE,
- MAP_SHARED, shm->header_info.fd, 0);
+ shm->header = mmap(NULL, header_info->length, PROT_READ | PROT_WRITE,
+ MAP_SHARED, header_info->fd, 0);
if (shm->header == (struct cras_audio_shm_header *)-1) {
- ret = -errno;
+ ret = errno;
syslog(LOG_ERR, "cras_shm: mmap failed to map shm for header.");
goto free_shm;
}
- shm->samples = mmap(NULL, shm->samples_info.length, samples_prot,
- MAP_SHARED, shm->samples_info.fd, 0);
+ shm->samples = mmap(NULL, samples_info->length, samples_prot,
+ MAP_SHARED, samples_info->fd, 0);
if (shm->samples == (uint8_t *)-1) {
- ret = -errno;
+ ret = errno;
syslog(LOG_ERR,
"cras_shm: mmap failed to map shm for samples.");
- goto free_shm;
+ goto unmap_header;
}
cras_shm_set_volume_scaler(shm, 1.0);
@@ -148,8 +152,10 @@ int cras_audio_shm_create(struct cras_shm_info *header_info,
*shm_out = shm;
return 0;
+unmap_header:
+ munmap(shm->header, shm->header_info.length);
free_shm:
- cras_audio_shm_destroy(shm);
+ free(shm);
cleanup_info:
cras_shm_info_cleanup(samples_info);
cras_shm_info_cleanup(header_info);
@@ -161,12 +167,9 @@ void cras_audio_shm_destroy(struct cras_audio_shm *shm)
if (!shm)
return;
- if (shm->samples != NULL && shm->samples != (uint8_t *)-1)
- munmap(shm->samples, shm->samples_info.length);
+ munmap(shm->samples, shm->samples_info.length);
cras_shm_info_cleanup(&shm->samples_info);
- if (shm->header != NULL &&
- shm->header != (struct cras_audio_shm_header *)-1)
- munmap(shm->header, shm->header_info.length);
+ munmap(shm->header, shm->header_info.length);
cras_shm_info_cleanup(&shm->header_info);
free(shm);
}
@@ -250,7 +253,7 @@ int cras_shm_open_rw(const char *name, size_t size)
strerror(-fd));
return fd;
}
- rc = posix_fallocate(fd, 0, size);
+ rc = ftruncate(fd, size);
if (rc) {
rc = -errno;
syslog(LOG_ERR, "failed to set size of shm %s: %s\n", name,
diff --git a/cras/src/common/cras_shm.h b/cras/src/common/cras_shm.h
index 47786c3b..f9c93920 100644
--- a/cras/src/common/cras_shm.h
+++ b/cras/src/common/cras_shm.h
@@ -59,7 +59,7 @@ struct __attribute__((__packed__)) cras_audio_shm_header {
int32_t callback_pending;
uint32_t num_overruns;
struct cras_timespec ts;
- uint64_t buffer_offset[CRAS_NUM_SHM_BUFFERS];
+ uint32_t buffer_offset[CRAS_NUM_SHM_BUFFERS];
};
/* Returns the number of bytes needed to hold a cras_audio_shm_header. */
@@ -146,8 +146,6 @@ struct cras_audio_shm {
* samples_prot - the mapping protections to use when mapping samples. Allowed
* values are PROT_READ or PROT_WRITE.
* shm_out - pointer where the created cras_audio_shm will be stored.
- *
- * Returns 0 on success or a negative error code on failure.
*/
int cras_audio_shm_create(struct cras_shm_info *header_info,
struct cras_shm_info *samples_info, int samples_prot,
@@ -564,12 +562,11 @@ static inline void cras_shm_set_used_size(struct cras_audio_shm *shm,
uint32_t i;
shm->config.used_size = used_size;
- if (shm->header) {
+ if (shm->header)
shm->header->config.used_size = used_size;
- for (i = 0; i < CRAS_NUM_SHM_BUFFERS; i++)
- cras_shm_set_buffer_offset(shm, i, i * used_size);
- }
+ for (i = 0; i < CRAS_NUM_SHM_BUFFERS; i++)
+ cras_shm_set_buffer_offset(shm, i, i * used_size);
}
/* Returns the used size of the shm region in bytes. */
@@ -585,7 +582,7 @@ static inline unsigned cras_shm_used_frames(const struct cras_audio_shm *shm)
}
/* Returns the size of the samples shm region. */
-static inline uint64_t cras_shm_samples_size(const struct cras_audio_shm *shm)
+static inline unsigned cras_shm_samples_size(const struct cras_audio_shm *shm)
{
return shm->samples_info.length;
}
diff --git a/cras/src/common/cras_types.h b/cras/src/common/cras_types.h
index 544ba02c..3dd9413a 100644
--- a/cras/src/common/cras_types.h
+++ b/cras/src/common/cras_types.h
@@ -15,7 +15,6 @@
#include "cras_audio_format.h"
#include "cras_iodev_info.h"
-#include "packet_status_logger.h"
/* Architecture independent timespec */
struct __attribute__((__packed__)) cras_timespec {
@@ -49,10 +48,6 @@ enum CRAS_CONNECTION_TYPE {
CRAS_CONTROL, // For legacy client.
CRAS_PLAYBACK, // For playback client.
CRAS_CAPTURE, // For capture client.
- CRAS_VMS_LEGACY, // For legacy client in vms.
- CRAS_VMS_UNIFIED, // For unified client in vms.
- CRAS_PLUGIN_PLAYBACK, // For playback client in vms/plugin.
- CRAS_PLUGIN_UNIFIED, // For unified client in vms/plugin.
CRAS_NUM_CONN_TYPE,
};
@@ -167,17 +162,8 @@ enum CRAS_CLIENT_TYPE {
CRAS_CLIENT_TYPE_ARC, /* ARC++ */
CRAS_CLIENT_TYPE_CROSVM, /* CROSVM */
CRAS_CLIENT_TYPE_SERVER_STREAM, /* Server stream */
- CRAS_CLIENT_TYPE_LACROS, /* LaCrOS */
- CRAS_CLIENT_TYPE_PLUGIN, /* PluginVM */
- CRAS_CLIENT_TYPE_ARCVM, /* ARCVM */
- CRAS_NUM_CLIENT_TYPE, /* numbers of CRAS_CLIENT_TYPE */
};
-static inline bool cras_validate_client_type(enum CRAS_CLIENT_TYPE client_type)
-{
- return 0 <= client_type && client_type < CRAS_NUM_CLIENT_TYPE;
-}
-
#define ENUM_STR(x) \
case x: \
return #x;
@@ -212,9 +198,6 @@ cras_client_type_str(enum CRAS_CLIENT_TYPE client_type)
ENUM_STR(CRAS_CLIENT_TYPE_ARC)
ENUM_STR(CRAS_CLIENT_TYPE_CROSVM)
ENUM_STR(CRAS_CLIENT_TYPE_SERVER_STREAM)
- ENUM_STR(CRAS_CLIENT_TYPE_LACROS)
- ENUM_STR(CRAS_CLIENT_TYPE_PLUGIN)
- ENUM_STR(CRAS_CLIENT_TYPE_ARCVM)
default:
return "INVALID_CLIENT_TYPE";
}
@@ -267,7 +250,6 @@ static inline uint32_t node_index_of(cras_node_id_t id)
#define MAX_DEBUG_STREAMS 8
#define AUDIO_THREAD_EVENT_LOG_SIZE (1024 * 6)
#define CRAS_BT_EVENT_LOG_SIZE 1024
-#define MAIN_THREAD_EVENT_LOG_SIZE 1024
/* There are 8 bits of space for events. */
enum AUDIO_THREAD_LOG_EVENTS {
@@ -288,8 +270,7 @@ enum AUDIO_THREAD_LOG_EVENTS {
AUDIO_THREAD_FETCH_STREAM,
AUDIO_THREAD_STREAM_ADDED,
AUDIO_THREAD_STREAM_REMOVED,
- AUDIO_THREAD_A2DP_FLUSH,
- AUDIO_THREAD_A2DP_THROTTLE_TIME,
+ AUDIO_THREAD_A2DP_ENCODE,
AUDIO_THREAD_A2DP_WRITE,
AUDIO_THREAD_DEV_STREAM_MIX,
AUDIO_THREAD_CAPTURE_POST,
@@ -315,48 +296,6 @@ enum AUDIO_THREAD_LOG_EVENTS {
AUDIO_THREAD_SEVERE_UNDERRUN,
AUDIO_THREAD_CAPTURE_DROP_TIME,
AUDIO_THREAD_DEV_DROP_FRAMES,
- AUDIO_THREAD_LOOPBACK_PUT,
- AUDIO_THREAD_LOOPBACK_GET,
- AUDIO_THREAD_LOOPBACK_SAMPLE_HOOK,
- AUDIO_THREAD_DEV_OVERRUN,
-};
-
-/* Important events in main thread.
- * MAIN_THREAD_DEV_CLOSE - When an iodev closes at stream removal.
- * MAIN_THREAD_DEV_DISABLE - When an iodev is removed from active dev list.
- * MAIN_THREAD_DEV_INIT - When an iodev opens when stream attachs.
- * MAIN_THREAD_DEV_REOPEN - When an iodev reopens for format change.
- * MAIN_THREAD_ADD_ACTIVE_NODE - When an iodev is set as an additional
- * active device.
- * MAIN_THREAD_SELECT_NODE - When UI selects an iodev as active.
- * MAIN_THREAD_NODE_PLUGGED - When a jack of iodev is plugged/unplugged.
- * MAIN_THREAD_ADD_TO_DEV_LIST - When iodev is added to list.
- * MAIN_THREAD_INPUT_NODE_GAIN - When input node gain changes.
- * MAIN_THREAD_OUTPUT_NODE_VOLUME - When output node volume changes.
- * MAIN_THREAD_SET_OUTPUT_USER_MUTE - When output mute state is set.
- * MAIN_THREAD_RESUME_DEVS - When system resumes and notifies CRAS.
- * MAIN_THREAD_SUSPEND_DEVS - When system suspends and notifies CRAS.
- * MAIN_THREAD_STREAM_ADDED - When an audio stream is added.
- * MAIN_THREAD_STREAM_REMOVED - When an audio stream is removed.
- */
-enum MAIN_THREAD_LOG_EVENTS {
- /* iodev related */
- MAIN_THREAD_DEV_CLOSE,
- MAIN_THREAD_DEV_DISABLE,
- MAIN_THREAD_DEV_INIT,
- MAIN_THREAD_DEV_REOPEN,
- MAIN_THREAD_ADD_ACTIVE_NODE,
- MAIN_THREAD_SELECT_NODE,
- MAIN_THREAD_NODE_PLUGGED,
- MAIN_THREAD_ADD_TO_DEV_LIST,
- MAIN_THREAD_INPUT_NODE_GAIN,
- MAIN_THREAD_OUTPUT_NODE_VOLUME,
- MAIN_THREAD_SET_OUTPUT_USER_MUTE,
- MAIN_THREAD_RESUME_DEVS,
- MAIN_THREAD_SUSPEND_DEVS,
- /* stream related */
- MAIN_THREAD_STREAM_ADDED,
- MAIN_THREAD_STREAM_REMOVED,
};
/* There are 8 bits of space for events. */
@@ -370,16 +309,12 @@ enum CRAS_BT_LOG_EVENTS {
BT_A2DP_START,
BT_A2DP_SUSPENDED,
BT_CODEC_SELECTION,
- BT_DEV_CONNECTED,
- BT_DEV_DISCONNECTED,
+ BT_DEV_CONNECTED_CHANGE,
BT_DEV_CONN_WATCH_CB,
BT_DEV_SUSPEND_CB,
BT_HFP_NEW_CONNECTION,
BT_HFP_REQUEST_DISCONNECT,
BT_HFP_SUPPORTED_FEATURES,
- BT_HFP_HF_INDICATOR,
- BT_HFP_SET_SPEAKER_GAIN,
- BT_HFP_UPDATE_SPEAKER_GAIN,
BT_HSP_NEW_CONNECTION,
BT_HSP_REQUEST_DISCONNECT,
BT_NEW_AUDIO_PROFILE_AFTER_CONNECT,
@@ -387,8 +322,6 @@ enum CRAS_BT_LOG_EVENTS {
BT_SCO_CONNECT,
BT_TRANSPORT_ACQUIRE,
BT_TRANSPORT_RELEASE,
- BT_TRANSPORT_SET_VOLUME,
- BT_TRANSPORT_UPDATE_VOLUME,
};
struct __attribute__((__packed__)) audio_thread_event {
@@ -460,24 +393,6 @@ struct __attribute__((__packed__)) audio_debug_info {
struct audio_thread_event_log log;
};
-struct __attribute__((__packed__)) main_thread_event {
- uint32_t tag_sec;
- uint32_t nsec;
- uint32_t data1;
- uint32_t data2;
- uint32_t data3;
-};
-
-struct __attribute__((__packed__)) main_thread_event_log {
- uint32_t write_pos;
- uint32_t len;
- struct main_thread_event log[MAIN_THREAD_EVENT_LOG_SIZE];
-};
-
-struct __attribute__((__packed__)) main_thread_debug_info {
- struct main_thread_event_log main_log;
-};
-
struct __attribute__((__packed__)) cras_bt_event {
uint32_t tag_sec;
uint32_t nsec;
@@ -493,7 +408,6 @@ struct __attribute__((__packed__)) cras_bt_event_log {
struct __attribute__((__packed__)) cras_bt_debug_info {
struct cras_bt_event_log bt_log;
- struct packet_status_logger wbs_logger;
};
/*
@@ -501,14 +415,11 @@ struct __attribute__((__packed__)) cras_bt_debug_info {
* or they will be ignored by the handler.
*/
enum CRAS_AUDIO_THREAD_EVENT_TYPE {
- AUDIO_THREAD_EVENT_A2DP_OVERRUN,
- AUDIO_THREAD_EVENT_A2DP_THROTTLE,
AUDIO_THREAD_EVENT_BUSYLOOP,
AUDIO_THREAD_EVENT_DEBUG,
AUDIO_THREAD_EVENT_SEVERE_UNDERRUN,
AUDIO_THREAD_EVENT_UNDERRUN,
AUDIO_THREAD_EVENT_DROP_SAMPLES,
- AUDIO_THREAD_EVENT_DEV_OVERRUN,
AUDIO_THREAD_EVENT_TYPE_COUNT,
};
@@ -540,8 +451,16 @@ struct __attribute__((__packed__)) cras_audio_thread_snapshot_buffer {
* mute_locked - 0 = unlocked, 1 = locked.
* suspended - 1 = suspended, 0 = resumed.
* capture_gain - Capture gain in dBFS * 100.
+ * capture_gain_target - Target capture gain in dBFS * 100. The actual
+ * capture gain will be subjected to current
+ * supported range. When active device/node changes,
+ * supported range changes accordingly. System state
+ * should try to re-apply target gain subjected to new
+ * range.
* capture_mute - 0 = unmuted, 1 = muted.
* capture_mute_locked - 0 = unlocked, 1 = locked.
+ * min_capture_gain - Min allowed capture gain in dBFS * 100.
+ * max_capture_gain - Max allowed capture gain in dBFS * 100.
* num_streams_attached - Total number of streams since server started.
* num_output_devs - Number of available output devices.
* num_input_devs - Number of available input devices.
@@ -571,17 +490,6 @@ struct __attribute__((__packed__)) cras_audio_thread_snapshot_buffer {
* snapshot_buffer - ring buffer for storing audio thread snapshots.
* bt_debug_info - ring buffer for storing bluetooth event logs.
* bt_wbs_enabled - Whether or not bluetooth wideband speech is enabled.
- * deprioritize_bt_wbs_mic - Whether Bluetooth wideband speech mic
- * should be deprioritized for selecting as default audio input.
- * main_thread_debug_info - ring buffer for storing main thread event logs.
- * num_input_streams_with_permission - An array containing numbers of input
- * streams with permission in each client type.
- * noise_cancellation_enabled - Whether or not Noise Cancellation is enabled.
- * hotword_pause_at_suspend - 1 = Pause hotword detection when the system
- * suspends. Hotword detection is resumed after system resumes.
- * 0 - Hotword detection is allowed to continue running after system
- * suspends, so a detected hotword can wake up the device.
- *
*/
#define CRAS_SERVER_STATE_VERSION 2
struct __attribute__((packed, aligned(4))) cras_server_state {
@@ -594,8 +502,11 @@ struct __attribute__((packed, aligned(4))) cras_server_state {
int32_t mute_locked;
int32_t suspended;
int32_t capture_gain;
+ int32_t capture_gain_target;
int32_t capture_mute;
int32_t capture_mute_locked;
+ int32_t min_capture_gain;
+ int32_t max_capture_gain;
uint32_t num_streams_attached;
uint32_t num_output_devs;
uint32_t num_input_devs;
@@ -618,11 +529,6 @@ struct __attribute__((packed, aligned(4))) cras_server_state {
struct cras_audio_thread_snapshot_buffer snapshot_buffer;
struct cras_bt_debug_info bt_debug_info;
int32_t bt_wbs_enabled;
- int32_t deprioritize_bt_wbs_mic;
- struct main_thread_debug_info main_thread_debug_info;
- uint32_t num_input_streams_with_permission[CRAS_NUM_CLIENT_TYPE];
- int32_t noise_cancellation_enabled;
- int32_t hotword_pause_at_suspend;
};
/* Actions for card add/remove/change. */
@@ -689,16 +595,12 @@ enum CRAS_NODE_TYPE {
CRAS_NODE_TYPE_HOTWORD,
CRAS_NODE_TYPE_POST_MIX_PRE_DSP,
CRAS_NODE_TYPE_POST_DSP,
- /* Type for the legacy BT narrow band mic .*/
- CRAS_NODE_TYPE_BLUETOOTH_NB_MIC,
/* These value can be used for both output and input nodes. */
CRAS_NODE_TYPE_USB,
CRAS_NODE_TYPE_BLUETOOTH,
CRAS_NODE_TYPE_FALLBACK_NORMAL,
CRAS_NODE_TYPE_FALLBACK_ABNORMAL,
CRAS_NODE_TYPE_UNKNOWN,
- CRAS_NODE_TYPE_ECHO_REFERENCE,
- CRAS_NODE_TYPE_ALSA_LOOPBACK,
};
/* Position values to described where a node locates on the system.
diff --git a/cras/src/common/cras_util.h b/cras/src/common/cras_util.h
index 96985ab2..01034242 100644
--- a/cras/src/common/cras_util.h
+++ b/cras/src/common/cras_util.h
@@ -187,33 +187,6 @@ static inline uint64_t cras_frames_since_time(const struct timespec *beg,
return cras_time_to_frames(&time_since, rate);
}
-/* Calculates frames until time end. */
-static inline uint64_t cras_frames_until_time(const struct timespec *end,
- unsigned int rate)
-{
- struct timespec now, time_until;
-
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- if (!timespec_after(end, &now))
- return 0;
-
- subtract_timespecs(end, &now, &time_until);
- return cras_time_to_frames(&time_until, rate);
-}
-
-/* Returns true if the difference between a and b is shorter than t. */
-static inline bool timespec_diff_shorter_than(const struct timespec *a,
- const struct timespec *b,
- const struct timespec *t)
-{
- struct timespec diff;
- if (timespec_after(a, b))
- subtract_timespecs(a, b, &diff);
- else
- subtract_timespecs(b, a, &diff);
- return timespec_after(t, &diff);
-}
-
/* Poll on the given file descriptors.
*
* See ppoll(). This implementation changes the value of timeout to the
diff --git a/cras/src/common/dumper.c b/cras/src/common/dumper.c
index 5da16df8..50789e8e 100644
--- a/cras/src/common/dumper.c
+++ b/cras/src/common/dumper.c
@@ -108,23 +108,18 @@ struct dumper *mem_dumper_create()
struct dumper *dumper = calloc(1, sizeof(struct dumper));
struct mem_data *data = calloc(1, sizeof(struct mem_data));
if (!dumper || !data)
- goto error;
+ return NULL;
data->size = 0;
data->capacity = 80;
data->buf = malloc(data->capacity);
- if (!data->buf)
- goto error;
+ if (!data->buf) {
+ free(data);
+ return NULL;
+ }
data->buf[0] = '\0';
dumper->data = data;
dumper->vprintf = &mem_vprintf;
return dumper;
-
-error:
- if (dumper)
- free(dumper);
- if (data)
- free(data);
- return NULL;
}
void mem_dumper_free(struct dumper *dumper)
diff --git a/cras/src/common/packet_status_logger.c b/cras/src/common/packet_status_logger.c
deleted file mode 100644
index f1be6965..00000000
--- a/cras/src/common/packet_status_logger.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <string.h>
-#include <time.h>
-
-#include "cras_util.h"
-#include "packet_status_logger.h"
-
-void packet_status_logger_init(struct packet_status_logger *logger)
-{
- memset(logger->data, 0, PACKET_STATUS_LEN_BYTES);
- logger->size = PACKET_STATUS_LEN_BYTES * 8;
- logger->wp = 0;
- logger->num_wraps = 0;
- clock_gettime(CLOCK_MONOTONIC_RAW, &logger->ts);
-}
-
-void packet_status_logger_update(struct packet_status_logger *logger, bool val)
-{
- if (val) {
- logger->data[logger->wp / 8] |= 1UL << (logger->wp % 8);
- } else {
- logger->data[logger->wp / 8] &= ~(1UL << (logger->wp % 8));
- }
- logger->wp++;
- if (logger->wp >= logger->size) {
- logger->wp %= logger->size;
- logger->num_wraps += 1;
- }
- if (logger->wp == 0 || (logger->num_wraps == 0 && logger->wp == 1))
- clock_gettime(CLOCK_MONOTONIC_RAW, &logger->ts);
-}
diff --git a/cras/src/common/packet_status_logger.h b/cras/src/common/packet_status_logger.h
deleted file mode 100644
index 3bc90041..00000000
--- a/cras/src/common/packet_status_logger.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef PACKET_STATUS_LOGGER_
-#define PACKET_STATUS_LOGGER_
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#define PACKET_STATUS_LEN_BYTES 64
-#define WBS_FRAME_NS 7500000
-
-/* Avoid 32, 40, 64 consecutive hex characters so CrOS feedback redact
- * tool doesn't trim our dump. */
-#define PACKET_STATUS_LOG_LINE_WRAP 50
-
-/*
- * Object to log consecutive packets' status.
- * Members:
- * data - Bytes to store packets' status.
- * size - Total number of bits in |data|.
- * wp - Position of the next bit to log packet status.
- * num_wraps - Number of times the ring buffer has wrapped.
- * ts - The timestamp of the last time when the first bit of |data| updated.
- */
-struct packet_status_logger {
- uint8_t data[PACKET_STATUS_LEN_BYTES];
- int size;
- int wp;
- int num_wraps;
- struct timespec ts;
-};
-
-/* Initializes the packet status logger. */
-void packet_status_logger_init(struct packet_status_logger *logger);
-
-/* Updates the next packet status to logger. */
-void packet_status_logger_update(struct packet_status_logger *logger, bool val);
-
-/* Rewinds logger's time stamp to calculate the beginning.
- * If logger's ring buffer hasn't wrapped, simply return logger_ts.
- * Otherwise beginning_ts = logger_ts - WBS_FRAME_NS * (size - wp)
- */
-static inline void
-packet_status_logger_begin_ts(const struct packet_status_logger *logger,
- struct timespec *ts)
-{
- long nsec = WBS_FRAME_NS * (logger->size - logger->wp);
-
- *ts = logger->ts;
- if (logger->num_wraps == 0)
- return;
- while (nsec > 1000000000L) {
- ts->tv_sec--;
- nsec -= 1000000000L;
- }
- ts->tv_nsec -= nsec;
- if (ts->tv_nsec < 0) {
- ts->tv_sec--;
- ts->tv_nsec += 1000000000L;
- }
-}
-
-/* Fast-forwards the logger's time stamp to calculate the end.
- * In other words, end_ts = logger_ts + WBS_FRAME_NS * wp
- */
-static inline void
-packet_status_logger_end_ts(const struct packet_status_logger *logger,
- struct timespec *ts)
-{
- *ts = logger->ts;
- ts->tv_nsec += WBS_FRAME_NS * logger->wp;
- while (ts->tv_nsec > 1000000000L) {
- ts->tv_sec++;
- ts->tv_nsec -= 1000000000L;
- }
-}
-
-/* Prints the logger data in hex format */
-static inline void
-packet_status_logger_dump_hex(const struct packet_status_logger *logger)
-{
- int i = logger->wp / 8;
-
- /* Print the bits after wp only if buffer has wrapped. */
- if (logger->num_wraps) {
- if (logger->wp % 8)
- printf("%.2x",
- logger->data[i] & (0xff << (logger->wp % 8)));
- for (; i < PACKET_STATUS_LEN_BYTES; i++)
- printf("%.2x", logger->data[i]);
- }
- for (i = 0; i < logger->wp / 8; i++)
- printf("%.2x", logger->data[i]);
- if (logger->wp % 8)
- printf("%.2x", logger->data[i] & (~(0xff << (logger->wp % 8))));
- printf("\n");
-}
-
-/* Prints the logger data in binary format */
-static inline void
-packet_status_logger_dump_binary(const struct packet_status_logger *logger)
-{
- /* Don't print the bits after wp if buffer hasn't wrapped. */
- int head = logger->num_wraps ? logger->wp : 0;
- int len = logger->num_wraps ? logger->size : logger->wp;
- int i, j;
-
- for (i = 0; i < len; ++i) {
- j = (head + i) % logger->size;
- printf("%d", (logger->data[j / 8] >> (j % 8)) & 1U);
- if ((i + 1) % PACKET_STATUS_LOG_LINE_WRAP == 0)
- printf("\n");
- }
- /* Fill indicator digit 'D' until the last line wraps. */
- if (len % PACKET_STATUS_LOG_LINE_WRAP) {
- while (len % PACKET_STATUS_LOG_LINE_WRAP) {
- printf("D");
- ++len;
- }
- printf("\n");
- }
-}
-
-#endif /* PACKET_STATUS_LOGGER_ */
diff --git a/cras/src/common/utlist.h b/cras/src/common/utlist.h
index 6c7f1e32..e3ee6304 100644
--- a/cras/src/common/utlist.h
+++ b/cras/src/common/utlist.h
@@ -194,7 +194,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define DL_DELETE(head, del) \
do { \
- assert((head) != NULL); \
assert((del)->prev != NULL); \
if ((del)->prev == (del)) { \
(head) = NULL; \
diff --git a/cras/src/dsp/drc.c b/cras/src/dsp/drc.c
index e6098419..1b2639a0 100644
--- a/cras/src/dsp/drc.c
+++ b/cras/src/dsp/drc.c
@@ -104,7 +104,7 @@ static void set_default_parameters(struct drc *drc)
param[PARAM_RELEASE_ZONE3] = 0.42f;
param[PARAM_RELEASE_ZONE4] = 0.98f;
- /* This is effectively a main volume on the compressed
+ /* This is effectively a master volume on the compressed
* signal */
param[PARAM_POST_GAIN] = 0; /* dB */
param[PARAM_ENABLED] = 0;
diff --git a/cras/src/dsp/drc_kernel.c b/cras/src/dsp/drc_kernel.c
index 8c3404fc..c0eb100b 100644
--- a/cras/src/dsp/drc_kernel.c
+++ b/cras/src/dsp/drc_kernel.c
@@ -257,7 +257,7 @@ void dk_set_parameters(struct drc_kernel *dk, float db_threshold, float db_knee,
/* Empirical/perceptual tuning. */
full_range_makeup_gain = powf(full_range_makeup_gain, 0.6f);
- dk->main_linear_gain =
+ dk->master_linear_gain =
decibels_to_linear(db_post_gain) * full_range_makeup_gain;
/* Attack parameters. */
@@ -566,7 +566,7 @@ static void dk_update_detector_average(struct drc_kernel *dk)
#include <arm_neon.h>
static void dk_compress_output(struct drc_kernel *dk)
{
- const float main_linear_gain = dk->main_linear_gain;
+ const float master_linear_gain = dk->master_linear_gain;
const float envelope_rate = dk->envelope_rate;
const float scaled_desired_gain = dk->scaled_desired_gain;
const float compressor_gain = dk->compressor_gain;
@@ -638,7 +638,7 @@ static void dk_compress_output(struct drc_kernel *dk)
[A7]"w"(A7),
[base]"w"(vdupq_n_f32(scaled_desired_gain)),
[r4]"w"(vdupq_n_f32(r*r*r*r)),
- [g]"w"(vdupq_n_f32(main_linear_gain))
+ [g]"w"(vdupq_n_f32(master_linear_gain))
: /* clobber */
"memory", "cc");
// clang-format on
@@ -698,7 +698,7 @@ static void dk_compress_output(struct drc_kernel *dk)
[A7]"w"(A7),
[one]"w"(vdupq_n_f32(1)),
[r4]"w"(vdupq_n_f32(r*r*r*r)),
- [g]"w"(vdupq_n_f32(main_linear_gain))
+ [g]"w"(vdupq_n_f32(master_linear_gain))
: /* clobber */
"memory", "cc");
// clang-format on
@@ -709,7 +709,7 @@ static void dk_compress_output(struct drc_kernel *dk)
#include <emmintrin.h>
static void dk_compress_output(struct drc_kernel *dk)
{
- const float main_linear_gain = dk->main_linear_gain;
+ const float master_linear_gain = dk->master_linear_gain;
const float envelope_rate = dk->envelope_rate;
const float scaled_desired_gain = dk->scaled_desired_gain;
const float compressor_gain = dk->compressor_gain;
@@ -789,7 +789,7 @@ static void dk_compress_output(struct drc_kernel *dk)
[A7]"x"(A7),
[base]"x"(_mm_set1_ps(scaled_desired_gain)),
[r4]"x"(_mm_set1_ps(r*r*r*r)),
- [g]"x"(_mm_set1_ps(main_linear_gain))
+ [g]"x"(_mm_set1_ps(master_linear_gain))
: /* clobber */
"memory", "cc");
// clang-format on
@@ -862,7 +862,7 @@ static void dk_compress_output(struct drc_kernel *dk)
[A7]"x"(A7),
[one]"x"(_mm_set1_ps(1)),
[r4]"x"(_mm_set1_ps(r*r*r*r)),
- [g]"x"(_mm_set1_ps(main_linear_gain))
+ [g]"x"(_mm_set1_ps(master_linear_gain))
: /* clobber */
"memory", "cc");
// clang-format on
@@ -872,7 +872,7 @@ static void dk_compress_output(struct drc_kernel *dk)
#else
static void dk_compress_output(struct drc_kernel *dk)
{
- const float main_linear_gain = dk->main_linear_gain;
+ const float master_linear_gain = dk->master_linear_gain;
const float envelope_rate = dk->envelope_rate;
const float scaled_desired_gain = dk->scaled_desired_gain;
const float compressor_gain = dk->compressor_gain;
@@ -902,8 +902,8 @@ static void dk_compress_output(struct drc_kernel *dk)
float post_warp_compressor_gain =
warp_sinf(x[j] + base);
- /* Calculate total gain using main gain. */
- float total_gain = main_linear_gain *
+ /* Calculate total gain using master gain. */
+ float total_gain = master_linear_gain *
post_warp_compressor_gain;
/* Apply final gain. */
@@ -936,8 +936,8 @@ static void dk_compress_output(struct drc_kernel *dk)
float post_warp_compressor_gain =
warp_sinf(x[j]);
- /* Calculate total gain using main gain. */
- float total_gain = main_linear_gain *
+ /* Calculate total gain using master gain. */
+ float total_gain = master_linear_gain *
post_warp_compressor_gain;
/* Apply final gain. */
diff --git a/cras/src/dsp/drc_kernel.h b/cras/src/dsp/drc_kernel.h
index 2ed9956e..1157f225 100644
--- a/cras/src/dsp/drc_kernel.h
+++ b/cras/src/dsp/drc_kernel.h
@@ -67,7 +67,7 @@ struct drc_kernel {
float kA, kB, kC, kD, kE;
/* Calculated parameters */
- float main_linear_gain;
+ float master_linear_gain;
float attack_frames;
float sat_release_frames_inv_neg;
float sat_release_rate_at_neg_two_db;
diff --git a/cras/src/fuzz/Dockerfile b/cras/src/fuzz/Dockerfile
index caffa995..cf08a6e4 100644
--- a/cras/src/fuzz/Dockerfile
+++ b/cras/src/fuzz/Dockerfile
@@ -1,13 +1,57 @@
-# Copyright 2017 The Chromium OS Authors. All rights reserved.
+# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Defines a docker image that can build cras fuzzers.
#
FROM gcr.io/oss-fuzz-base/base-builder
-LABEL maintainer="dgreid@chromium.org"
-COPY . "${SRC}/adhd"
-COPY cras/src/fuzz/build.sh "${SRC}/build.sh"
-RUN "${SRC}/adhd/cras/install_deps.sh"
-RUN mkdir -p /etc/cras && cp "${SRC}/adhd/cras-config/dsp.ini.sample" /etc/cras
+RUN apt-get -y update && \
+ apt-get install -y \
+ automake \
+ build-essential \
+ cmake \
+ ctags \
+ g++ \
+ gdb \
+ git \
+ ladspa-sdk \
+ libasound-dev \
+ libdbus-1-dev \
+ libgtest-dev \
+ libncurses5-dev \
+ libsbc-dev \
+ libsndfile-dev \
+ libspeexdsp-dev \
+ libtool \
+ libudev-dev \
+ wget
+RUN apt-get clean
+RUN cd /tmp && git clone https://github.com/ndevilla/iniparser.git && \
+ cd iniparser && \
+ make && \
+ cp libiniparser.* /usr/local/lib && \
+ cp src/dictionary.h src/iniparser.h /usr/local/include && \
+ chmod 644 /usr/local/include/dictionary.h /usr/local/include/iniparser.h && \
+ chmod 644 /usr/local/lib/libiniparser.a && \
+ chmod 755 /usr/local/lib/libiniparser.so.*
+RUN cd /usr/src/gtest && \
+ cmake . && \
+ make && \
+ chmod 644 *.a && \
+ cp *.a /usr/local/lib
+
+# Need to build and install alsa so there is a static lib.
+RUN mkdir -p /tmp/alsa-build && cd /tmp/alsa-build && \
+ wget ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.1.4.1.tar.bz2 && \
+ bzip2 -f -d alsa-lib-* && \
+ tar xf alsa-lib-* && \
+ cd alsa-lib-* && \
+ ./configure --enable-static --disable-shared && \
+ make clean && \
+ make -j$(nproc) all && \
+ make install
+
+
+COPY . /src/cras/
+COPY src/fuzz/build.sh /src/
diff --git a/cras/src/fuzz/README.md b/cras/src/fuzz/README.md
index 0d235cec..72716023 100644
--- a/cras/src/fuzz/README.md
+++ b/cras/src/fuzz/README.md
@@ -11,26 +11,22 @@ Detailed instructions are available at: https://github.com/google/oss-fuzz/blob/
```
sudo adduser $USER docker
```
-### Sync to the latest base-builder
-```
-docker pull gcr.io/oss-fuzz-base/base-builder
-```
-### Build a container from the adhd directory
+### Build a container from the cras directory
```
-docker build -t ossfuzz/cras -f cras/src/fuzz/Dockerfile .
+docker build -t ossfuzz/cras -f src/fuzz/Dockerfile .
```
-Add `--no-cache` if you want a complete rebuild.
### Build fuzzers
```
-docker run --cap-add=SYS_PTRACE -ti --rm -v /tmp/fuzzers:/out ossfuzz/cras
+docker run --cap-add=SYS_PTRACE -ti --rm -v $(pwd):/src/cras -v /tmp/fuzzers:/out \
+ ossfuzz/cras
```
### Look in /tmp/fuzzers to see the executables. Run them like so:
```
-docker run --cap-add=SYS_PTRACE -ti -v $(pwd)/cras/src/fuzz/corpus:/corpus \
- -v /tmp/fuzzers:/out ossfuzz/cras /out/rclient_message \
+docker run --cap-add=SYS_PTRACE -ti -v $(pwd)/src/fuzz/corpus:/corpus \
+ -v /tmp/fuzzers:/out ossfuzz/base-runner /out/rclient_message \
/corpus -runs=100
```
@@ -38,7 +34,7 @@ docker run --cap-add=SYS_PTRACE -ti -v $(pwd)/cras/src/fuzz/corpus:/corpus \
Go into docker console by
```
-docker run --cap-add=SYS_PTRACE -ti -v $(pwd)/cras/src/fuzz/corpus:/corpus \
- -v /tmp/fuzzers:/out ossfuzz/cras /bin/bash
+docker run --cap-add=SYS_PTRACE -ti -v $(pwd)/src/fuzz/corpus:/corpus \
+ -v /tmp/fuzzers:/out ossfuzz/base-runner /bin/bash
```
and start debugging.
diff --git a/cras/src/fuzz/build.sh b/cras/src/fuzz/build.sh
index 44413a7f..ac4ad2fb 100755
--- a/cras/src/fuzz/build.sh
+++ b/cras/src/fuzz/build.sh
@@ -1,24 +1,22 @@
#!/bin/bash -eux
-
-# Copyright 2017 The Chromium OS Authors. All rights reserved.
+# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
-# Builds fuzzers from within a container into ${OUT} directory.
-# Expects "${SRC}/adhd" to contain an adhd checkout.
+# Builds fuzzers from within a container into /out/ directory.
+# Expects /src/cras to contain a cras checkout.
-cd "${SRC}/adhd/cras"
+mkdir $WORK/cras
+cd $SRC/cras
./git_prepare.sh
-
-FUZZER_LDFLAGS="${FUZZER_LDFLAGS} ${LIB_FUZZING_ENGINE}"
-./configure --enable-fuzzer
-
-# Compile fuzzers
+./configure --disable-dbus --disable-webrtc-apm
make -j$(nproc)
-# Copy fuzzers and dependencies to "${OUT}" directory
-cp "${SRC}/adhd/cras/src/cras_rclient_message_fuzzer" "${OUT}/rclient_message"
-zip -j "${OUT}/rclient_message_corpus.zip" ./src/fuzz/corpus/*
-
-cp "${SRC}/adhd/cras/src/cras_hfp_slc_fuzzer" "${OUT}/cras_hfp_slc"
-cp "${SRC}/adhd/cras/src/fuzz/cras_hfp_slc.dict" "${OUT}/cras_hfp_slc.dict"
+$CXX $CXXFLAGS $FUZZER_LDFLAGS \
+ $SRC/cras/src/fuzz/rclient_message.cc -o $OUT/rclient_message \
+ -I $SRC/cras/src/server \
+ -I $SRC/cras/src/common \
+ $SRC/cras/src/.libs/libcrasserver.a \
+ -lpthread -lrt -ludev -ldl -lm \
+ -lFuzzingEngine \
+ -Wl,-Bstatic -liniparser -lasound -lspeexdsp -Wl,-Bdynamic
diff --git a/cras/src/fuzz/cras_hfp_slc.cc b/cras/src/fuzz/cras_hfp_slc.cc
deleted file mode 100644
index 4a76ea46..00000000
--- a/cras/src/fuzz/cras_hfp_slc.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <assert.h>
-#include <fuzzer/FuzzedDataProvider.h>
-#include <stddef.h>
-#include <stdint.h>
-
-extern "C" {
-#include "cras_bt_device.h"
-#include "cras_bt_log.h"
-#include "cras_hfp_slc.h"
-#include "cras_iodev_list.h"
-#include "cras_mix.h"
-#include "cras_observer.h"
-#include "cras_shm.h"
-#include "cras_system_state.h"
-
-struct cras_bt_event_log* btlog;
-}
-
-int disconnect_cb(struct hfp_slc_handle*) {
- return 0;
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider data_provider(data, size);
- bool is_hsp = data_provider.ConsumeIntegralInRange(0, 1);
- int ag_supported_features = data_provider.ConsumeIntegral<int>();
- std::string command = data_provider.ConsumeRemainingBytesAsString();
- int fd = open("/dev/null", O_RDWR);
-
- struct cras_bt_device* bt_dev = cras_bt_device_create(NULL, "");
- struct hfp_slc_handle* handle = hfp_slc_create(
- fd, is_hsp, ag_supported_features, bt_dev, NULL, &disconnect_cb);
- if (!handle)
- return 0;
-
- handle_at_command_for_test(handle, command.c_str());
-
- hfp_slc_destroy(handle);
- cras_bt_device_remove(bt_dev);
- return 0;
-}
-
-extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
- char* shm_name;
- if (asprintf(&shm_name, "/cras-%d", getpid()) < 0)
- exit(-ENOMEM);
- struct cras_server_state* exp_state =
- (struct cras_server_state*)calloc(1, sizeof(*exp_state));
- if (!exp_state)
- exit(-1);
- int rw_shm_fd = open("/dev/null", O_RDWR);
- int ro_shm_fd = open("/dev/null", O_RDONLY);
- cras_system_state_init("/tmp", shm_name, rw_shm_fd, ro_shm_fd, exp_state,
- sizeof(*exp_state));
- free(shm_name);
- cras_observer_server_init();
- cras_mix_init(0);
- cras_iodev_list_init();
- btlog = cras_bt_event_log_init();
- return 0;
-}
diff --git a/cras/src/fuzz/cras_hfp_slc.dict b/cras/src/fuzz/cras_hfp_slc.dict
deleted file mode 100644
index cfc49895..00000000
--- a/cras/src/fuzz/cras_hfp_slc.dict
+++ /dev/null
@@ -1,23 +0,0 @@
-"ATA"
-"ATD"
-"AT+BAC"
-"AT+BCS"
-"AT+BIA"
-"AT+BIEV"
-"AT+BIND"
-"AT+BLDN"
-"AT+BRSF"
-"AT+CCWA"
-"AT+CHUP"
-"AT+CIND"
-"AT+CKPD"
-"AT+CLCC"
-"AT+CLIP"
-"AT+CMEE"
-"AT+CMER"
-"AT+CNUM"
-"AT+COPS"
-"AT+IPHONEACCEV"
-"AT+VG"
-"AT+VTS"
-"AT+XAPL"
diff --git a/cras/src/fuzz/rclient_message.cc b/cras/src/fuzz/rclient_message.cc
index eacf9dab..a2a5650a 100644
--- a/cras/src/fuzz/rclient_message.cc
+++ b/cras/src/fuzz/rclient_message.cc
@@ -4,37 +4,21 @@
*/
#include <assert.h>
-#include <fuzzer/FuzzedDataProvider.h>
#include <stddef.h>
#include <stdint.h>
extern "C" {
-#include "cras_apm_list.h"
-#include "cras_bt_log.h"
-#include "cras_dsp.h"
#include "cras_iodev_list.h"
#include "cras_mix.h"
#include "cras_observer.h"
#include "cras_rclient.h"
#include "cras_shm.h"
#include "cras_system_state.h"
-
-struct cras_bt_event_log* btlog;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
cras_rclient* client = cras_rclient_create(0, 0, CRAS_CONTROL);
- if (size < 300) {
- /* Feeds input data directly if the given bytes is too short. */
- cras_rclient_buffer_from_client(client, data, size, NULL, 0);
- } else {
- FuzzedDataProvider data_provider(data, size);
- int fds[1] = {0};
- int num_fds = data_provider.ConsumeIntegralInRange(0, 1);
- std::vector<uint8_t> msg = data_provider.ConsumeRemainingBytes<uint8_t>();
- cras_rclient_buffer_from_client(client, msg.data(), msg.size(), fds,
- num_fds);
- }
+ cras_rclient_buffer_from_client(client, data, size, NULL, 0);
cras_rclient_destroy(client);
return 0;
@@ -56,13 +40,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
cras_observer_server_init();
cras_mix_init(0);
- cras_apm_list_init("/etc/cras");
cras_iodev_list_init();
- /* For cros fuzz, emerge adhd with USE=fuzzer will copy dsp.ini.sample to
- * etc/cras. For OSS-Fuzz the Dockerfile will be responsible for copying the
- * file. This shouldn't crash CRAS even if the dsp file does not exist. */
- cras_dsp_init("/etc/cras/dsp.ini.sample");
- /* Initializes btlog for CRAS_SERVER_DUMP_BT path with CRAS_DBUS defined. */
- btlog = cras_bt_event_log_init();
+
return 0;
}
diff --git a/cras/src/libcras/cras_client.c b/cras/src/libcras/cras_client.c
index 8420db1f..fe54e0e3 100644
--- a/cras/src/libcras/cras_client.c
+++ b/cras/src/libcras/cras_client.c
@@ -119,8 +119,7 @@ struct thread_state {
};
/* Parameters used when setting up a capture or playback stream. See comment
- * above cras_client_stream_params_create or libcras_stream_params_set in the
- * header for descriptions. */
+ * above cras_client_create_stream_params in the header for descriptions. */
struct cras_stream_params {
enum CRAS_STREAM_DIRECTION direction;
size_t buffer_frames;
@@ -134,14 +133,15 @@ struct cras_stream_params {
cras_unified_cb_t unified_cb;
cras_error_cb_t err_cb;
struct cras_audio_format format;
- libcras_stream_cb_t stream_cb;
+ int client_shm_fd;
+ size_t client_shm_size;
};
/* Represents an attached audio stream.
* id - Unique stream identifier.
* aud_fd - After server connects audio messages come in here.
* direction - playback, capture, or loopback (see CRAS_STREAM_DIRECTION).
- * flags - Currently only used for CRAS_INPUT_STREAM_FLAG.
+ * flags - Currently not used.
* volume_scaler - Amount to scale the stream by, 0.0 to 1.0. Client could
* change this scaler value before stream actually connected, so we need
* to cache it until shm is prepared and apply it.
@@ -276,92 +276,6 @@ struct cras_hotword_handle {
void *user_data;
};
-struct cras_stream_cb_data {
- cras_stream_id_t stream_id;
- enum CRAS_STREAM_DIRECTION direction;
- uint8_t *buf;
- unsigned int frames;
- struct timespec sample_ts;
- void *user_arg;
-};
-
-int stream_cb_get_stream_id(struct cras_stream_cb_data *data,
- cras_stream_id_t *id)
-{
- *id = data->stream_id;
- return 0;
-}
-
-int stream_cb_get_buf(struct cras_stream_cb_data *data, uint8_t **buf)
-{
- *buf = data->buf;
- return 0;
-}
-
-int stream_cb_get_frames(struct cras_stream_cb_data *data, unsigned int *frames)
-{
- *frames = data->frames;
- return 0;
-}
-
-int stream_cb_get_latency(struct cras_stream_cb_data *data,
- struct timespec *latency)
-{
- if (data->direction == CRAS_STREAM_INPUT)
- cras_client_calc_capture_latency(&data->sample_ts, latency);
- else
- cras_client_calc_playback_latency(&data->sample_ts, latency);
- return 0;
-}
-
-int stream_cb_get_user_arg(struct cras_stream_cb_data *data, void **user_arg)
-{
- *user_arg = data->user_arg;
- return 0;
-}
-
-struct libcras_stream_cb_data *
-libcras_stream_cb_data_create(cras_stream_id_t stream_id,
- enum CRAS_STREAM_DIRECTION direction,
- uint8_t *buf, unsigned int frames,
- struct timespec sample_ts, void *user_arg)
-{
- struct libcras_stream_cb_data *data =
- (struct libcras_stream_cb_data *)calloc(
- 1, sizeof(struct libcras_stream_cb_data));
- if (!data) {
- syslog(LOG_ERR, "cras_client: calloc: %s", strerror(errno));
- return NULL;
- }
- data->data_ = (struct cras_stream_cb_data *)calloc(
- 1, sizeof(struct cras_stream_cb_data));
- if (!data->data_) {
- syslog(LOG_ERR, "cras_client: calloc: %s", strerror(errno));
- free(data);
- return NULL;
- }
- data->api_version = CRAS_API_VERSION;
- data->get_stream_id = stream_cb_get_stream_id;
- data->get_buf = stream_cb_get_buf;
- data->get_frames = stream_cb_get_frames;
- data->get_latency = stream_cb_get_latency;
- data->get_user_arg = stream_cb_get_user_arg;
- data->data_->stream_id = stream_id;
- data->data_->direction = direction;
- data->data_->buf = buf;
- data->data_->frames = frames;
- data->data_->sample_ts = sample_ts;
- data->data_->user_arg = user_arg;
- return data;
-}
-
-void libcras_stream_cb_data_destroy(struct libcras_stream_cb_data *data)
-{
- if (data)
- free(data->data_);
- free(data);
-}
-
/*
* Local Helpers
*/
@@ -371,10 +285,6 @@ static int client_thread_rm_stream(struct cras_client *client,
static int handle_message_from_server(struct cras_client *client);
static int reregister_notifications(struct cras_client *client);
-static struct libcras_node_info *
-libcras_node_info_create(struct cras_iodev_info *iodev,
- struct cras_ionode_info *ionode);
-
/*
* Unlock the server_state_rwlock if lock_rc is 0.
*
@@ -1176,7 +1086,6 @@ static int handle_capture_data_ready(struct client_stream *stream,
uint8_t *captured_frames;
struct timespec ts;
int rc = 0;
- struct libcras_stream_cb_data *data;
config = stream->config;
/* If this message is for an output stream, log error and drop it. */
@@ -1191,24 +1100,14 @@ static int handle_capture_data_ready(struct client_stream *stream,
cras_timespec_to_timespec(&ts, &stream->shm->header->ts);
- if (config->stream_cb) {
- data = libcras_stream_cb_data_create(
- stream->id, stream->direction, captured_frames,
- num_frames, ts, config->user_data);
- if (!data)
- return -errno;
- frames = config->stream_cb(data);
- libcras_stream_cb_data_destroy(data);
- data = NULL;
- } else if (config->unified_cb) {
+ if (config->unified_cb)
frames = config->unified_cb(stream->client, stream->id,
captured_frames, NULL, num_frames,
&ts, NULL, config->user_data);
- } else {
+ else
frames = config->aud_cb(stream->client, stream->id,
captured_frames, num_frames, &ts,
config->user_data);
- }
if (frames < 0) {
send_stream_message(stream, CLIENT_STREAM_EOF);
rc = frames;
@@ -1255,7 +1154,6 @@ static int handle_playback_request(struct client_stream *stream,
struct cras_stream_params *config;
struct cras_audio_shm *shm = stream->shm;
struct timespec ts;
- struct libcras_stream_cb_data *data;
config = stream->config;
@@ -1273,24 +1171,13 @@ static int handle_playback_request(struct client_stream *stream,
cras_timespec_to_timespec(&ts, &shm->header->ts);
/* Get samples from the user */
- if (config->stream_cb) {
- data = libcras_stream_cb_data_create(stream->id,
- stream->direction, buf,
- num_frames, ts,
- config->user_data);
- if (!data)
- return -errno;
- frames = config->stream_cb(data);
- libcras_stream_cb_data_destroy(data);
- data = NULL;
- } else if (config->unified_cb) {
+ if (config->unified_cb)
frames = config->unified_cb(stream->client, stream->id, NULL,
buf, num_frames, NULL, &ts,
config->user_data);
- } else {
+ else
frames = config->aud_cb(stream->client, stream->id, buf,
num_frames, &ts, config->user_data);
- }
if (frames < 0) {
send_stream_message(stream, CLIENT_STREAM_EOF);
rc = frames;
@@ -1497,6 +1384,7 @@ static int stream_connected(struct client_stream *stream,
{
int rc, samples_prot;
unsigned int i;
+ struct cras_audio_format mfmt;
struct cras_shm_info header_info, samples_info;
if (msg->err || num_fds != 2) {
@@ -1506,6 +1394,8 @@ static int stream_connected(struct client_stream *stream,
goto err_ret;
}
+ unpack_cras_audio_format(&mfmt, &msg->format);
+
rc = cras_shm_info_init_with_fd(stream_fds[0], cras_shm_header_size(),
&header_info);
if (rc < 0)
@@ -1518,6 +1408,7 @@ static int stream_connected(struct client_stream *stream,
goto err_ret;
}
+ samples_prot = 0;
if (stream->direction == CRAS_STREAM_OUTPUT)
samples_prot = PROT_WRITE;
else
@@ -1552,6 +1443,8 @@ static int send_connect_message(struct cras_client *client,
int rc;
struct cras_connect_message serv_msg;
int sock[2] = { -1, -1 };
+ int fds[2] = { -1, -1 };
+ unsigned int num_fds;
/* Create a socket pair for the server to notify of audio events. */
rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
@@ -1561,16 +1454,21 @@ static int send_connect_message(struct cras_client *client,
goto fail;
}
- cras_fill_connect_message(&serv_msg, stream->config->direction,
- stream->id, stream->config->stream_type,
- stream->config->client_type,
- stream->config->buffer_frames,
- stream->config->cb_threshold, stream->flags,
- stream->config->effects,
- stream->config->format, dev_idx);
+ cras_fill_connect_message(
+ &serv_msg, stream->config->direction, stream->id,
+ stream->config->stream_type, stream->config->client_type,
+ stream->config->buffer_frames, stream->config->cb_threshold,
+ stream->flags, stream->config->effects, stream->config->format,
+ dev_idx, stream->config->client_shm_size);
+ fds[0] = sock[1];
+ num_fds = 1;
+ if (stream->config->client_shm_fd >= 0) {
+ fds[1] = stream->config->client_shm_fd;
+ num_fds++;
+ }
rc = cras_send_with_fds(client->server_fd, &serv_msg, sizeof(serv_msg),
- &sock[1], 1);
+ fds, num_fds);
if (rc != sizeof(serv_msg)) {
rc = EIO;
syslog(LOG_ERR,
@@ -1580,6 +1478,8 @@ static int send_connect_message(struct cras_client *client,
stream->aud_fd = sock[0];
close(sock[1]);
+ if (stream->config->client_shm_fd != -1)
+ close(stream->config->client_shm_fd);
return 0;
fail:
@@ -1587,6 +1487,8 @@ fail:
close(sock[0]);
if (sock[1] != -1)
close(sock[1]);
+ if (stream->config->client_shm_fd != -1)
+ close(stream->config->client_shm_fd);
return rc;
}
@@ -1602,30 +1504,18 @@ static int client_thread_add_stream(struct cras_client *client,
cras_stream_id_t new_id;
struct client_stream *out;
- if ((stream->flags & HOTWORD_STREAM) == HOTWORD_STREAM) {
+ /* Find the hotword device index. */
+ if ((stream->flags & HOTWORD_STREAM) == HOTWORD_STREAM &&
+ dev_idx == NO_DEVICE) {
int hotword_idx;
hotword_idx = cras_client_get_first_dev_type_idx(
client, CRAS_NODE_TYPE_HOTWORD, CRAS_STREAM_INPUT);
-
- /* Find the hotword device index. */
- if (dev_idx == NO_DEVICE) {
- if (hotword_idx < 0) {
- syslog(LOG_ERR,
- "cras_client: add_stream: No hotword dev");
- return hotword_idx;
- } else {
- dev_idx = (uint32_t)hotword_idx;
- }
- }
- /* A known Use case for client to pin hotword stream on a not
- * hotword device is to use internal mic for Assistant to work
- * on board without usable DSP hotwording. We assume there will
- * be only one hotword device exists. */
- else if (dev_idx != (uint32_t)hotword_idx) {
- /* Unmask the flag to fallback to normal pinned stream
- * on specified device. */
- stream->flags &= ~HOTWORD_STREAM;
+ if (hotword_idx < 0) {
+ syslog(LOG_ERR,
+ "cras_client: add_stream: Finding hotword dev");
+ return hotword_idx;
}
+ dev_idx = hotword_idx;
}
/* Find an available stream id. */
@@ -2252,7 +2142,7 @@ int cras_client_create_with_type(struct cras_client **client,
rc = fill_socket_file((*client), conn_type);
if (rc < 0) {
- goto free_server_event_fd;
+ goto free_error;
}
rc = cras_file_wait_create((*client)->sock_file,
@@ -2285,11 +2175,10 @@ int cras_client_create_with_type(struct cras_client **client,
return 0;
free_error:
- cras_file_wait_destroy((*client)->sock_file_wait);
- free((void *)(*client)->sock_file);
-free_server_event_fd:
if ((*client)->server_event_fd >= 0)
close((*client)->server_event_fd);
+ cras_file_wait_destroy((*client)->sock_file_wait);
+ free((void *)(*client)->sock_file);
free_cond:
pthread_cond_destroy(&(*client)->stream_start_cond);
free_lock:
@@ -2370,8 +2259,9 @@ struct cras_stream_params *cras_client_stream_params_create(
params->user_data = user_data;
params->aud_cb = aud_cb;
params->unified_cb = 0;
- params->stream_cb = 0;
params->err_cb = err_cb;
+ params->client_shm_fd = -1;
+ params->client_shm_size = 0;
memcpy(&(params->format), format, sizeof(*format));
return params;
}
@@ -2422,6 +2312,14 @@ void cras_client_stream_params_disable_vad(struct cras_stream_params *params)
params->effects &= ~APM_VOICE_DETECTION;
}
+void cras_client_stream_params_configure_client_shm(
+ struct cras_stream_params *params, int client_shm_fd,
+ size_t client_shm_size)
+{
+ params->client_shm_fd = client_shm_fd;
+ params->client_shm_size = client_shm_size;
+}
+
struct cras_stream_params *cras_client_unified_params_create(
enum CRAS_STREAM_DIRECTION direction, unsigned int block_size,
enum CRAS_STREAM_TYPE stream_type, uint32_t flags, void *user_data,
@@ -2444,8 +2342,9 @@ struct cras_stream_params *cras_client_unified_params_create(
params->user_data = user_data;
params->aud_cb = 0;
params->unified_cb = unified_cb;
- params->stream_cb = 0;
params->err_cb = err_cb;
+ params->client_shm_fd = -1;
+ params->client_shm_size = 0;
memcpy(&(params->format), format, sizeof(*format));
return params;
@@ -2467,8 +2366,7 @@ static inline int cras_client_send_add_stream_command_message(
if (client == NULL || config == NULL || stream_id_out == NULL)
return -EINVAL;
- if (config->stream_cb == NULL && config->aud_cb == NULL &&
- config->unified_cb == NULL)
+ if (config->aud_cb == NULL && config->unified_cb == NULL)
return -EINVAL;
if (config->err_cb == NULL)
@@ -2566,6 +2464,17 @@ int cras_client_set_system_volume(struct cras_client *client, size_t volume)
return write_message_to_server(client, &msg.header);
}
+int cras_client_set_system_capture_gain(struct cras_client *client, long gain)
+{
+ struct cras_set_system_capture_gain msg;
+
+ if (client == NULL)
+ return -EINVAL;
+
+ cras_fill_set_system_capture_gain(&msg, gain);
+ return write_message_to_server(client, &msg.header);
+}
+
int cras_client_set_system_mute(struct cras_client *client, int mute)
{
struct cras_set_system_mute msg;
@@ -2720,47 +2629,45 @@ long cras_client_get_system_max_volume(const struct cras_client *client)
return max_volume;
}
-int cras_client_get_default_output_buffer_size(struct cras_client *client)
+long cras_client_get_system_min_capture_gain(const struct cras_client *client)
{
- int default_output_buffer_size;
+ long min_gain;
int lock_rc;
lock_rc = server_state_rdlock(client);
if (lock_rc)
- return -EINVAL;
+ return 0;
- default_output_buffer_size =
- client->server_state->default_output_buffer_size;
+ min_gain = client->server_state->min_capture_gain;
server_state_unlock(client, lock_rc);
- return default_output_buffer_size;
+ return min_gain;
}
-const struct audio_debug_info *
-cras_client_get_audio_debug_info(const struct cras_client *client)
+long cras_client_get_system_max_capture_gain(const struct cras_client *client)
{
- const struct audio_debug_info *debug_info;
+ long max_gain;
int lock_rc;
lock_rc = server_state_rdlock(client);
if (lock_rc)
return 0;
- debug_info = &client->server_state->audio_debug_info;
+ max_gain = client->server_state->max_capture_gain;
server_state_unlock(client, lock_rc);
- return debug_info;
+ return max_gain;
}
-const struct main_thread_debug_info *
-cras_client_get_main_thread_debug_info(const struct cras_client *client)
+const struct audio_debug_info *
+cras_client_get_audio_debug_info(const struct cras_client *client)
{
- const struct main_thread_debug_info *debug_info;
+ const struct audio_debug_info *debug_info;
int lock_rc;
lock_rc = server_state_rdlock(client);
if (lock_rc)
return 0;
- debug_info = &client->server_state->main_thread_debug_info;
+ debug_info = &client->server_state->audio_debug_info;
server_state_unlock(client, lock_rc);
return debug_info;
}
@@ -3301,20 +3208,6 @@ int cras_client_read_atlog(struct cras_client *client, uint64_t *read_idx,
return len;
}
-int cras_client_update_main_thread_debug_info(
- struct cras_client *client, void (*debug_info_cb)(struct cras_client *))
-{
- struct cras_dump_main msg;
-
- if (client == NULL)
- return -EINVAL;
- if (client->debug_info_callback != NULL)
- return -EINVAL;
- client->debug_info_callback = debug_info_cb;
- cras_fill_dump_main(&msg);
- return write_message_to_server(client, &msg.header);
-}
-
int cras_client_update_bt_debug_info(
struct cras_client *client, void (*debug_info_cb)(struct cras_client *))
{
@@ -3347,71 +3240,6 @@ int cras_client_update_audio_thread_snapshots(
return write_message_to_server(client, &msg.header);
}
-int cras_client_get_max_supported_channels(const struct cras_client *client,
- cras_node_id_t node_id,
- uint32_t *max_channels)
-{
- size_t ndevs, nnodes;
- struct cras_iodev_info *devs = NULL;
- struct cras_ionode_info *nodes = NULL;
- int rc = -EINVAL;
- unsigned i;
-
- if (!client) {
- rc = -EINVAL;
- goto quit;
- }
-
- devs = (struct cras_iodev_info *)malloc(CRAS_MAX_IODEVS *
- sizeof(*devs));
- if (!devs) {
- rc = -ENOMEM;
- goto quit;
- }
-
- nodes = (struct cras_ionode_info *)malloc(CRAS_MAX_IONODES *
- sizeof(*nodes));
- if (!nodes) {
- rc = -ENOMEM;
- goto quit;
- }
-
- ndevs = CRAS_MAX_IODEVS;
- nnodes = CRAS_MAX_IONODES;
- rc = cras_client_get_output_devices(client, devs, nodes, &ndevs,
- &nnodes);
- if (rc < 0)
- goto quit;
-
- rc = -ENOENT;
- uint32_t iodev_idx;
- for (i = 0; i < nnodes; i++) {
- if (node_id == cras_make_node_id(nodes[i].iodev_idx,
- nodes[i].ionode_idx)) {
- iodev_idx = nodes[i].iodev_idx;
- rc = 0;
- break;
- }
- }
-
- if (rc < 0)
- goto quit;
-
- rc = -ENOENT;
- for (i = 0; i < ndevs; i++) {
- if (iodev_idx == devs[i].idx) {
- *max_channels = devs[i].max_supported_channels;
- rc = 0;
- break;
- }
- }
-
-quit:
- free(devs);
- free(nodes);
- return rc;
-}
-
int cras_client_set_node_volume(struct cras_client *client,
cras_node_id_t node_id, uint8_t volume)
{
@@ -3480,10 +3308,10 @@ int cras_client_config_global_remix(struct cras_client *client,
{
struct cras_config_global_remix *msg;
int rc;
- size_t nchan = (size_t)num_channels;
msg = (struct cras_config_global_remix *)malloc(
- sizeof(*msg) + nchan * nchan * sizeof(*coefficient));
+ sizeof(*msg) +
+ num_channels * num_channels * sizeof(*coefficient));
cras_fill_config_global_remix_command(msg, num_channels, coefficient,
num_channels * num_channels);
rc = write_message_to_server(client, &msg->header);
@@ -3933,317 +3761,3 @@ int cras_client_disable_hotword_callback(struct cras_client *client,
free(handle);
return 0;
}
-
-int get_nodes(struct cras_client *client, enum CRAS_STREAM_DIRECTION direction,
- struct libcras_node_info ***nodes, size_t *num)
-{
- struct cras_iodev_info iodevs[CRAS_MAX_IODEVS];
- struct cras_ionode_info ionodes[CRAS_MAX_IONODES];
- size_t num_devs = CRAS_MAX_IODEVS, num_nodes = CRAS_MAX_IONODES;
- int rc, i, j;
-
- *num = 0;
- if (direction == CRAS_STREAM_INPUT) {
- rc = cras_client_get_input_devices(client, iodevs, ionodes,
- &num_devs, &num_nodes);
- } else {
- rc = cras_client_get_output_devices(client, iodevs, ionodes,
- &num_devs, &num_nodes);
- }
-
- if (rc < 0) {
- syslog(LOG_ERR, "Failed to get devices: %d", rc);
- return rc;
- }
-
- *nodes = (struct libcras_node_info **)calloc(
- num_nodes, sizeof(struct libcras_node_info *));
-
- for (i = 0; i < num_devs; i++) {
- for (j = 0; j < num_nodes; j++) {
- if (iodevs[i].idx != ionodes[j].iodev_idx)
- continue;
- (*nodes)[*num] = libcras_node_info_create(&iodevs[i],
- &ionodes[j]);
- if ((*nodes)[*num] == NULL) {
- rc = -errno;
- goto clean;
- }
- (*num)++;
- }
- }
- return 0;
-clean:
- for (i = 0; i < *num; i++)
- libcras_node_info_destroy((*nodes)[i]);
- free(*nodes);
- *nodes = NULL;
- *num = 0;
- return rc;
-}
-
-int get_default_output_buffer_size(struct cras_client *client, int *size)
-{
- int rc = cras_client_get_default_output_buffer_size(client);
- if (rc < 0)
- return rc;
- *size = rc;
- return 0;
-}
-
-int get_aec_group_id(struct cras_client *client, int *id)
-{
- int rc = cras_client_get_aec_group_id(client);
- if (rc < 0)
- return rc;
- *id = rc;
- return 0;
-}
-
-int get_aec_supported(struct cras_client *client, int *supported)
-{
- *supported = cras_client_get_aec_supported(client);
- return 0;
-}
-
-int get_system_muted(struct cras_client *client, int *muted)
-{
- *muted = cras_client_get_system_muted(client);
- return 0;
-}
-
-int get_loopback_dev_idx(struct cras_client *client, int *idx)
-{
- int rc = cras_client_get_first_dev_type_idx(
- client, CRAS_NODE_TYPE_POST_MIX_PRE_DSP, CRAS_STREAM_INPUT);
- if (rc < 0)
- return rc;
- *idx = rc;
- return 0;
-}
-
-struct libcras_client *libcras_client_create()
-{
- struct libcras_client *client = (struct libcras_client *)calloc(
- 1, sizeof(struct libcras_client));
- if (!client) {
- syslog(LOG_ERR, "cras_client: calloc failed");
- return NULL;
- }
- if (cras_client_create(&client->client_)) {
- libcras_client_destroy(client);
- return NULL;
- }
- client->api_version = CRAS_API_VERSION;
- client->connect = cras_client_connect;
- client->connect_timeout = cras_client_connect_timeout;
- client->connected_wait = cras_client_connected_wait;
- client->run_thread = cras_client_run_thread;
- client->stop = cras_client_stop;
- client->add_pinned_stream = cras_client_add_pinned_stream;
- client->rm_stream = cras_client_rm_stream;
- client->set_stream_volume = cras_client_set_stream_volume;
- client->get_nodes = get_nodes;
- client->get_default_output_buffer_size = get_default_output_buffer_size;
- client->get_aec_group_id = get_aec_group_id;
- client->get_aec_supported = get_aec_supported;
- client->get_system_muted = get_system_muted;
- client->set_system_mute = cras_client_set_system_mute;
- client->get_loopback_dev_idx = get_loopback_dev_idx;
- return client;
-}
-
-void libcras_client_destroy(struct libcras_client *client)
-{
- cras_client_destroy(client->client_);
- free(client);
-}
-
-int stream_params_set(struct cras_stream_params *params,
- enum CRAS_STREAM_DIRECTION direction,
- size_t buffer_frames, size_t cb_threshold,
- enum CRAS_STREAM_TYPE stream_type,
- enum CRAS_CLIENT_TYPE client_type, uint32_t flags,
- void *user_data, libcras_stream_cb_t stream_cb,
- cras_error_cb_t err_cb, size_t rate,
- snd_pcm_format_t format, size_t num_channels)
-{
- params->direction = direction;
- params->buffer_frames = buffer_frames;
- params->cb_threshold = cb_threshold;
- params->stream_type = stream_type;
- params->client_type = client_type;
- params->flags = flags;
- params->user_data = user_data;
- params->stream_cb = stream_cb;
- params->err_cb = err_cb;
- params->format.frame_rate = rate;
- params->format.format = format;
- params->format.num_channels = num_channels;
- return 0;
-}
-
-int stream_params_set_channel_layout(struct cras_stream_params *params,
- int length, const int8_t *layout)
-{
- if (length != CRAS_CH_MAX)
- return -EINVAL;
- return cras_audio_format_set_channel_layout(&params->format, layout);
-}
-
-struct libcras_stream_params *libcras_stream_params_create()
-{
- struct libcras_stream_params *params =
- (struct libcras_stream_params *)calloc(
- 1, sizeof(struct libcras_stream_params));
- if (!params) {
- syslog(LOG_ERR, "cras_client: calloc failed");
- return NULL;
- }
- params->params_ = (struct cras_stream_params *)calloc(
- 1, sizeof(struct cras_stream_params));
- if (params->params_ == NULL) {
- syslog(LOG_ERR, "cras_client: calloc failed");
- free(params->params_);
- return NULL;
- }
- params->api_version = CRAS_API_VERSION;
- params->set = stream_params_set;
- params->set_channel_layout = stream_params_set_channel_layout;
- params->enable_aec = cras_client_stream_params_enable_aec;
- return params;
-}
-
-void libcras_stream_params_destroy(struct libcras_stream_params *params)
-{
- free(params->params_);
- free(params);
-}
-
-struct cras_node_info {
- uint64_t id;
- uint32_t dev_idx;
- uint32_t node_idx;
- uint32_t max_supported_channels;
- bool plugged;
- bool active;
- char type[CRAS_NODE_TYPE_BUFFER_SIZE];
- char node_name[CRAS_NODE_NAME_BUFFER_SIZE];
- char dev_name[CRAS_IODEV_NAME_BUFFER_SIZE];
-};
-
-int cras_node_info_get_id(struct cras_node_info *node, uint64_t *id)
-{
- (*id) = node->id;
- return 0;
-}
-
-int cras_node_info_get_dev_idx(struct cras_node_info *node, uint32_t *dev_idx)
-{
- (*dev_idx) = node->dev_idx;
- return 0;
-}
-
-int cras_node_info_get_node_idx(struct cras_node_info *node, uint32_t *node_idx)
-{
- (*node_idx) = node->node_idx;
- return 0;
-}
-
-int cras_node_info_get_max_supported_channels(struct cras_node_info *node,
- uint32_t *max_supported_channels)
-{
- (*max_supported_channels) = node->max_supported_channels;
- return 0;
-}
-
-int cras_node_info_is_plugged(struct cras_node_info *node, bool *is_plugged)
-{
- (*is_plugged) = node->plugged;
- return 0;
-}
-
-int cras_node_info_is_active(struct cras_node_info *node, bool *is_active)
-{
- (*is_active) = node->active;
- return 0;
-}
-
-int cras_node_info_get_type(struct cras_node_info *node, char **type)
-{
- (*type) = node->type;
- return 0;
-}
-
-int cras_node_info_get_node_name(struct cras_node_info *node, char **node_name)
-{
- (*node_name) = node->node_name;
- return 0;
-}
-
-int cras_node_info_get_dev_name(struct cras_node_info *node, char **dev_name)
-{
- (*dev_name) = node->dev_name;
- return 0;
-}
-
-struct libcras_node_info *
-libcras_node_info_create(struct cras_iodev_info *iodev,
- struct cras_ionode_info *ionode)
-{
- struct libcras_node_info *node = (struct libcras_node_info *)calloc(
- 1, sizeof(struct libcras_node_info));
- if (!node) {
- syslog(LOG_ERR, "cras_client: calloc failed");
- return NULL;
- }
- node->node_ = (struct cras_node_info *)calloc(
- 1, sizeof(struct cras_node_info));
- if (node->node_ == NULL) {
- syslog(LOG_ERR, "cras_client: calloc failed");
- free(node);
- return NULL;
- }
- node->api_version = CRAS_API_VERSION;
- node->node_->id =
- cras_make_node_id(ionode->iodev_idx, ionode->ionode_idx);
- node->node_->dev_idx = ionode->iodev_idx;
- node->node_->node_idx = ionode->ionode_idx;
- node->node_->max_supported_channels = iodev->max_supported_channels;
- node->node_->plugged = ionode->plugged;
- node->node_->active = ionode->active;
- strncpy(node->node_->type, ionode->type, CRAS_NODE_TYPE_BUFFER_SIZE);
- node->node_->type[CRAS_NODE_TYPE_BUFFER_SIZE - 1] = '\0';
- strncpy(node->node_->node_name, ionode->name,
- CRAS_NODE_NAME_BUFFER_SIZE);
- node->node_->node_name[CRAS_NODE_NAME_BUFFER_SIZE - 1] = '\0';
- strncpy(node->node_->dev_name, iodev->name,
- CRAS_IODEV_NAME_BUFFER_SIZE);
- node->node_->dev_name[CRAS_IODEV_NAME_BUFFER_SIZE - 1] = '\0';
- node->get_id = cras_node_info_get_id;
- node->get_dev_idx = cras_node_info_get_dev_idx;
- node->get_node_idx = cras_node_info_get_node_idx;
- node->get_max_supported_channels =
- cras_node_info_get_max_supported_channels;
- node->is_plugged = cras_node_info_is_plugged;
- node->is_active = cras_node_info_is_active;
- node->get_type = cras_node_info_get_type;
- node->get_node_name = cras_node_info_get_node_name;
- node->get_dev_name = cras_node_info_get_dev_name;
- return node;
-}
-
-void libcras_node_info_destroy(struct libcras_node_info *node)
-{
- free(node->node_);
- free(node);
-}
-
-void libcras_node_info_array_destroy(struct libcras_node_info **nodes,
- size_t num)
-{
- int i;
- for (i = 0; i < num; i++)
- libcras_node_info_destroy(nodes[i]);
- free(nodes);
-}
diff --git a/cras/src/libcras/cras_client.h b/cras/src/libcras/cras_client.h
index f26a0814..7012e2df 100644
--- a/cras/src/libcras/cras_client.h
+++ b/cras/src/libcras/cras_client.h
@@ -477,16 +477,6 @@ int cras_client_dump_dsp_info(struct cras_client *client);
int cras_client_update_audio_debug_info(struct cras_client *client,
void (*cb)(struct cras_client *));
-/* Asks the server to dump current main thread information.
- * Args:
- * client - The client from cras_client_create.
- * cb - A function to call when the data is received.
- * Returns:
- * 0 on success, -EINVAL if the client isn't valid or isn't running.
- */
-int cras_client_update_main_thread_debug_info(struct cras_client *client,
- void (*cb)(struct cras_client *));
-
/* Asks the server to dump bluetooth debug information.
* Args:
* client - The client from cras_client_create.
@@ -535,19 +525,6 @@ int cras_client_read_atlog(struct cras_client *client, uint64_t *read_idx,
int cras_client_update_audio_thread_snapshots(struct cras_client *client,
void (*cb)(struct cras_client *));
-/* Gets the max supported channel count of the output device from node_id.
- * Args:
- * client - The client from cras_client_create.
- * node_id - ID of the node.
- * max_channels - Out parameter will be filled with the max supported channel
- * count.
- * Returns:
- * 0 on success, or negative error code on failure.
- */
-int cras_client_get_max_supported_channels(const struct cras_client *client,
- cras_node_id_t node_id,
- uint32_t *max_channels);
-
/*
* Stream handling.
*/
@@ -561,7 +538,7 @@ int cras_client_get_max_supported_channels(const struct cras_client *client,
* be called when buffer_frames have been captured).
* unused - No longer used.
* stream_type - media or talk (currently only support "default").
- * flags - Currently only used for CRAS_INPUT_STREAM_FLAG.
+ * flags - None currently used.
* user_data - Pointer that will be passed to the callback.
* aud_cb - Called when audio is needed(playback) or ready(capture). Allowed
* return EOF to indicate that the stream should terminate.
@@ -596,6 +573,16 @@ void cras_client_stream_params_disable_agc(struct cras_stream_params *params);
void cras_client_stream_params_enable_vad(struct cras_stream_params *params);
void cras_client_stream_params_disable_vad(struct cras_stream_params *params);
+/* Function to setup client-provided shm to be used as the backing shm for the
+ * samples area in the cras_audio_shm shared with cras.
+ * Args:
+ * client_shm_fd - shm fd to use for samples shm area.
+ * client_shm_size - size of shm area backed by 'client_shm_fd'.
+ */
+void cras_client_stream_params_configure_client_shm(
+ struct cras_stream_params *params, int client_shm_fd,
+ size_t client_shm_size);
+
/* Setup stream configuration parameters. DEPRECATED.
* TODO(crbug.com/972928): remove this
* Use cras_client_stream_params_create instead.
@@ -705,6 +692,20 @@ int cras_client_set_stream_volume(struct cras_client *client,
*/
int cras_client_set_system_volume(struct cras_client *client, size_t volume);
+/* Sets the capture gain of the system.
+ *
+ * Gain is specified in dBFS * 100. For example 5dB of gain would be specified
+ * with an argument of 500, while -10 would be specified with -1000.
+ *
+ * Args:
+ * client - The client from cras_client_create.
+ * gain - The gain in dBFS * 100.
+ * Returns:
+ * 0 for success, -EPIPE if there is an I/O error talking to the server, or
+ * -EINVAL if 'client' is invalid.
+ */
+int cras_client_set_system_capture_gain(struct cras_client *client, long gain);
+
/* Sets the mute state of the system.
*
* Args:
@@ -780,6 +781,17 @@ int cras_client_set_system_capture_mute_locked(struct cras_client *client,
*/
size_t cras_client_get_system_volume(const struct cras_client *client);
+/* Gets the current system capture gain.
+ *
+ * Requires that the connection to the server has been established.
+ *
+ * Args:
+ * client - The client from cras_client_create.
+ * Returns:
+ * The current system capture volume in dB * 100.
+ */
+long cras_client_get_system_capture_gain(const struct cras_client *client);
+
/* Gets the current system mute state.
*
* Requires that the connection to the server has been established.
@@ -831,13 +843,27 @@ long cras_client_get_system_min_volume(const struct cras_client *client);
*/
long cras_client_get_system_max_volume(const struct cras_client *client);
-/* Gets the default output buffer size.
+/* Gets the current minimum system capture gain.
+ *
+ * Requires that the connection to the server has been established.
+ *
+ * Args:
+ * client - The client from cras_client_create.
+ * Returns:
+ * The minimum capture gain for the current input device in dBFS * 100.
+ */
+long cras_client_get_system_min_capture_gain(const struct cras_client *client);
+
+/* Gets the current maximum system capture gain.
+ *
+ * Requires that the connection to the server has been established.
+ *
* Args:
* client - The client from cras_client_create.
* Returns:
- * Default output buffer size in frames. A negative error on failure.
+ * The maximum capture gain for the current input device in dBFS * 100.
*/
-int cras_client_get_default_output_buffer_size(struct cras_client *client);
+long cras_client_get_system_max_capture_gain(const struct cras_client *client);
/* Gets audio debug info.
*
@@ -866,16 +892,6 @@ cras_client_get_audio_debug_info(const struct cras_client *client);
const struct cras_bt_debug_info *
cras_client_get_bt_debug_info(const struct cras_client *client);
-/* Gets main thread debug info.
- * Args:
- * client - The client from cras_client_create.
- * Returns:
- * A pointer to the debug info. This info is updated and requested by
- * calling cras_client_update_main_thread_debug_info.
- */
-const struct main_thread_debug_info *
-cras_client_get_main_thread_debug_info(const struct cras_client *client);
-
/* Gets audio thread snapshot buffer.
*
* Requires that the connection to the server has been established.
@@ -971,8 +987,7 @@ int cras_client_swap_node_left_right(struct cras_client *client,
* Args:
* client - The client from cras_client_create.
* node_id - ID of the node.
- * gain - New capture gain for the node, in range (0, 100) which will
- * linearly maps to (-4000, 4000) 100*dBFS.
+ * gain - New capture gain for the node.
*/
int cras_client_set_node_capture_gain(struct cras_client *client,
cras_node_id_t node_id, long gain);
@@ -1308,699 +1323,6 @@ int cras_client_set_input_node_gain_changed_callback(
int cras_client_set_num_active_streams_changed_callback(
struct cras_client *client,
cras_client_num_active_streams_changed_callback cb);
-
-/*
- * The functions below prefixed with libcras wrap the original CRAS library
- * They provide an interface that maps the pointers to the functions above.
- * Please add a new function instead of modifying the existing function.
- * Here are some rules about how to add a new function:
- * 1. Increase the CRAS_API_VERSION by 1.
- * 2. Write a new function in cras_client.c.
- * 3. Append the corresponding pointer to the structure. Remeber DO NOT change
- * the order of functions in the structs.
- * 4. Assign the pointer to the new function in cras_client.c.
- * 5. Create the inline function in cras_client.h, which is used by clients.
- * Remember to add DISABLE_CFI_ICALL on the inline function.
- * 6. Add CHECK_VERSION in the inline function. If the api_version is smaller
- * than the supported version, this inline function will return -ENOSYS.
- */
-
-#define CRAS_API_VERSION 1
-#define CHECK_VERSION(object, version) \
- if (object->api_version < version) { \
- return -ENOSYS; \
- }
-
-/*
- * The inline functions use the indirect function call. Therefore, they are
- * incompatible with CFI-icall.
- */
-#define DISABLE_CFI_ICALL __attribute__((no_sanitize("cfi-icall")))
-
-struct libcras_node_info {
- int api_version;
- struct cras_node_info *node_;
- int (*get_id)(struct cras_node_info *node, uint64_t *id);
- int (*get_dev_idx)(struct cras_node_info *node, uint32_t *dev_idx);
- int (*get_node_idx)(struct cras_node_info *node, uint32_t *node_idx);
- int (*get_max_supported_channels)(struct cras_node_info *node,
- uint32_t *max_supported_channels);
- int (*is_plugged)(struct cras_node_info *node, bool *plugged);
- int (*is_active)(struct cras_node_info *node, bool *active);
- int (*get_type)(struct cras_node_info *node, char **name);
- int (*get_node_name)(struct cras_node_info *node, char **name);
- int (*get_dev_name)(struct cras_node_info *node, char **name);
-};
-
-struct libcras_client {
- int api_version;
- struct cras_client *client_;
- int (*connect)(struct cras_client *client);
- int (*connect_timeout)(struct cras_client *client,
- unsigned int timeout_ms);
- int (*connected_wait)(struct cras_client *client);
- int (*run_thread)(struct cras_client *client);
- int (*stop)(struct cras_client *client);
- int (*add_pinned_stream)(struct cras_client *client, uint32_t dev_idx,
- cras_stream_id_t *stream_id_out,
- struct cras_stream_params *config);
- int (*rm_stream)(struct cras_client *client,
- cras_stream_id_t stream_id);
- int (*set_stream_volume)(struct cras_client *client,
- cras_stream_id_t stream_id,
- float volume_scaler);
- int (*get_nodes)(struct cras_client *client,
- enum CRAS_STREAM_DIRECTION direction,
- struct libcras_node_info ***nodes, size_t *num);
- int (*get_default_output_buffer_size)(struct cras_client *client,
- int *size);
- int (*get_aec_group_id)(struct cras_client *client, int *id);
- int (*get_aec_supported)(struct cras_client *client, int *supported);
- int (*get_system_muted)(struct cras_client *client, int *muted);
- int (*set_system_mute)(struct cras_client *client, int mute);
- int (*get_loopback_dev_idx)(struct cras_client *client, int *idx);
-};
-
-struct cras_stream_cb_data;
-struct libcras_stream_cb_data {
- int api_version;
- struct cras_stream_cb_data *data_;
- int (*get_stream_id)(struct cras_stream_cb_data *data,
- cras_stream_id_t *id);
- int (*get_buf)(struct cras_stream_cb_data *data, uint8_t **buf);
- int (*get_frames)(struct cras_stream_cb_data *data,
- unsigned int *frames);
- int (*get_latency)(struct cras_stream_cb_data *data,
- struct timespec *latency);
- int (*get_user_arg)(struct cras_stream_cb_data *data, void **user_arg);
-};
-typedef int (*libcras_stream_cb_t)(struct libcras_stream_cb_data *data);
-
-struct libcras_stream_params {
- int api_version;
- struct cras_stream_params *params_;
- int (*set)(struct cras_stream_params *params,
- enum CRAS_STREAM_DIRECTION direction, size_t buffer_frames,
- size_t cb_threshold, enum CRAS_STREAM_TYPE stream_type,
- enum CRAS_CLIENT_TYPE client_type, uint32_t flags,
- void *user_data, libcras_stream_cb_t stream_cb,
- cras_error_cb_t err_cb, size_t rate, snd_pcm_format_t format,
- size_t num_channels);
- int (*set_channel_layout)(struct cras_stream_params *params, int length,
- const int8_t *layout);
- void (*enable_aec)(struct cras_stream_params *params);
-};
-
-/*
- * Creates a new client.
- * Returns:
- * If success, return a valid libcras_client pointer. Otherwise, return
- * NULL.
- */
-struct libcras_client *libcras_client_create();
-
-/*
- * Destroys a client.
- * Args:
- * client - pointer returned from "libcras_client_create".
- */
-void libcras_client_destroy(struct libcras_client *client);
-
-/*
- * Connects a client to the running server.
- * Waits forever (until interrupted or connected).
- * Args:
- * client - pointer returned from "libcras_client_create".
- * Returns:
- * 0 on success, or a negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_connect(struct libcras_client *client)
-{
- return client->connect(client->client_);
-}
-
-/*
- * Connects a client to the running server, retries until timeout.
- * Args:
- * client - pointer returned from "libcras_client_create".
- * timeout_ms - timeout in milliseconds or negative to wait forever.
- * Returns:
- * 0 on success, or a negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_connect_timeout(struct libcras_client *client,
- unsigned int timeout_ms)
-{
- return client->connect_timeout(client->client_, timeout_ms);
-}
-
-/*
- * Wait up to 1 second for the client thread to complete the server connection.
- *
- * After libcras_client_run_thread() is executed, this function can be
- * used to ensure that the connection has been established with the server and
- * ensure that any information about the server is up to date. If
- * libcras_client_run_thread() has not yet been executed, or
- * libcras_client_stop() was executed and thread isn't running, then this
- * function returns -EINVAL.
- *
- * Args:
- * client - pointer returned from "libcras_client_create".
- * Returns:
- * 0 on success, or a negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_connected_wait(struct libcras_client *client)
-{
- return client->connected_wait(client->client_);
-}
-
-/*
- * Begins running the client control thread.
- *
- * Required for stream operations and other operations noted below.
- *
- * Args:
- * client - pointer returned from "libcras_client_create".
- * Returns:
- * 0 on success, or a negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_run_thread(struct libcras_client *client)
-{
- return client->run_thread(client->client_);
-}
-
-/*
- * Stops running a client.
- * This function is executed automatically by cras_client_destroy().
- * Args:
- * client - pointer returned from "libcras_client_create".
- * Returns:
- * 0 on success or if the thread was already stopped, -EINVAL if the client
- * isn't valid.
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_stop(struct libcras_client *client)
-{
- return client->stop(client->client_);
-}
-
-/*
- * Creates a pinned stream and return the stream id or < 0 on error.
- *
- * Requires execution of libcras_client_run_thread(), and an active
- * connection to the audio server.
- *
- * Args:
- * client - pointer returned from "libcras_client_create".
- * dev_idx - Index of the device to attach the newly created stream.
- * stream_id_out - On success will be filled with the new stream id.
- * Guaranteed to be set before any callbacks are made.
- * params - The pointer specifying the parameters for the stream.
- * (returned from libcras_stream_params_create)
- * Returns:
- * 0 on success, negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_add_pinned_stream(
- struct libcras_client *client, uint32_t dev_idx,
- cras_stream_id_t *stream_id_out, struct libcras_stream_params *params)
-{
- return client->add_pinned_stream(client->client_, dev_idx,
- stream_id_out, params->params_);
-}
-
-/*
- * Removes a currently playing/capturing stream.
- *
- * Requires execution of libcras_client_run_thread().
- *
- * Args:
- * client - pointer returned from "libcras_client_create".
- * stream_id - ID returned from libcras_client_add_stream to identify
- * the stream to remove.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_rm_stream(struct libcras_client *client,
- cras_stream_id_t stream_id)
-{
- return client->rm_stream(client->client_, stream_id);
-}
-
-/*
- * Sets the volume scaling factor for the given stream.
- *
- * Requires execution of cras_client_run_thread().
- *
- * Args:
- * client - pointer returned from "libcras_client_create".
- * stream_id - ID returned from libcras_client_add_stream.
- * volume_scaler - 0.0-1.0 the new value to scale this stream by.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_set_stream_volume(struct libcras_client *client,
- cras_stream_id_t stream_id,
- float volume_scaler)
-{
- return client->set_stream_volume(client->client_, stream_id,
- volume_scaler);
-}
-
-/*
- * Gets the current list of audio nodes.
- *
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * direction - Input or output.
- * nodes - Array that will be filled with libcras_node_info pointers.
- * num - Pointer to store the size of the array.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- * Remember to call libcras_node_info_array_destroy to free the array.
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_get_nodes(struct libcras_client *client,
- enum CRAS_STREAM_DIRECTION direction,
- struct libcras_node_info ***nodes,
- size_t *num)
-{
- return client->get_nodes(client->client_, direction, nodes, num);
-}
-
-/*
- * Gets the default output buffer size.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * size - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_client_get_default_output_buffer_size(struct libcras_client *client,
- int *size)
-{
- return client->get_default_output_buffer_size(client->client_, size);
-}
-
-/*
- * Gets the AEC group ID.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * id - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_get_aec_group_id(struct libcras_client *client,
- int *id)
-{
- return client->get_aec_group_id(client->client_, id);
-}
-
-/*
- * Gets whether AEC is supported.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * supported - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_get_aec_supported(struct libcras_client *client,
- int *supported)
-{
- return client->get_aec_supported(client->client_, supported);
-}
-
-/*
- * Gets whether the system is muted.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * muted - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_get_system_muted(struct libcras_client *client,
- int *muted)
-{
- return client->get_aec_group_id(client->client_, muted);
-}
-
-/*
- * Mutes or unmutes the system.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * mute - 1 is to mute and 0 is to unmute.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_set_system_mute(struct libcras_client *client,
- int mute)
-{
- return client->set_system_mute(client->client_, mute);
-}
-
-/*
- * Gets the index of the loopback device.
- * Args:
- * client - Pointer returned from "libcras_client_create".
- * idx - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_client_get_loopback_dev_idx(struct libcras_client *client,
- int *idx)
-{
- return client->get_loopback_dev_idx(client->client_, idx);
-}
-
-/*
- * Creates a new struct to save stream params.
- * Returns:
- * If success, return a valid libcras_stream_params pointer. Otherwise,
- * return NULL.
- */
-struct libcras_stream_params *libcras_stream_params_create();
-
-/*
- * Destroys a stream params instance.
- * Args:
- * params - The pointer returned from libcras_stream_params_create.
- */
-void libcras_stream_params_destroy(struct libcras_stream_params *params);
-
-/*
- * Setup stream configuration parameters.
- * Args:
- * params - The pointer returned from libcras_stream_params_create.
- * direction - Playback(CRAS_STREAM_OUTPUT) or capture(CRAS_STREAM_INPUT).
- * buffer_frames - total number of audio frames to buffer (dictates latency).
- * cb_threshold - For playback, call back for more data when the buffer
- * reaches this level. For capture, this is ignored (Audio callback will
- * be called when buffer_frames have been captured).
- * stream_type - Media or talk (currently only support "default").
- * client_type - The client type, like Chrome or CrOSVM.
- * flags - Currently only used for CRAS_INPUT_STREAM_FLAG.
- * user_data - Pointer that will be passed to the callback.
- * stream_cb - The audio callback. Called when audio is needed(playback) or
- * ready(capture).
- * err_cb - Called when there is an error with the stream.
- * rate - The sample rate of the audio stream.
- * format - The format of the audio stream.
- * num_channels - The number of channels of the audio stream.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_stream_params_set(
- struct libcras_stream_params *params,
- enum CRAS_STREAM_DIRECTION direction, size_t buffer_frames,
- size_t cb_threshold, enum CRAS_STREAM_TYPE stream_type,
- enum CRAS_CLIENT_TYPE client_type, uint32_t flags, void *user_data,
- libcras_stream_cb_t stream_cb, cras_error_cb_t err_cb, size_t rate,
- snd_pcm_format_t format, size_t num_channels)
-{
- return params->set(params->params_, direction, buffer_frames,
- cb_threshold, stream_type, client_type, flags,
- user_data, stream_cb, err_cb, rate, format,
- num_channels);
-}
-
-/*
- * Sets channel layout on given stream parameter.
- * Args:
- * params - The pointer returned from libcras_stream_params_create.
- * length - The length of the array.
- * layout - An integer array representing the position of each channel in
- * enum CRAS_CHANNEL.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_params_set_channel_layout(struct libcras_stream_params *params,
- int length, const int8_t *layout)
-{
- return params->set_channel_layout(params->params_, length, layout);
-}
-
-/*
- * Enables AEC on given stream parameter.
- * Args:
- * params - The pointer returned from libcras_stream_params_create.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_params_enable_aec(struct libcras_stream_params *params)
-{
- params->enable_aec(params->params_);
- return 0;
-}
-
-/*
- * Gets stream id from the callback data.
- * Args:
- * data - The pointer passed to the callback function.
- * id - The pointer to save the stream id.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_cb_data_get_stream_id(struct libcras_stream_cb_data *data,
- cras_stream_id_t *id)
-{
- return data->get_stream_id(data->data_, id);
-}
-
-/*
- * Gets stream buf from the callback data.
- * Args:
- * data - The pointer passed to the callback function.
- * buf - The pointer to save the stream buffer.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_stream_cb_data_get_buf(struct libcras_stream_cb_data *data,
- uint8_t **buf)
-{
- return data->get_buf(data->data_, buf);
-}
-
-/*
- * Gets how many frames to read or play from the callback data.
- * Args:
- * data - The pointer passed to the callback function.
- * frames - The pointer to save the number of frames.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_cb_data_get_frames(struct libcras_stream_cb_data *data,
- unsigned int *frames)
-{
- return data->get_frames(data->data_, frames);
-}
-
-/*
- * Gets the latency from the callback data.
- * Args:
- * data - The pointer passed to the callback function.
- * frames - The timespec pointer to save the latency.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_cb_data_get_latency(struct libcras_stream_cb_data *data,
- struct timespec *latency)
-{
- return data->get_latency(data->data_, latency);
-}
-
-/*
- * Gets the user data from the callback data.
- * Args:
- * data - The pointer passed to the callback function.
- * frames - The pointer to save the user data.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_stream_cb_data_get_usr_arg(struct libcras_stream_cb_data *data,
- void **user_arg)
-{
- return data->get_user_arg(data->data_, user_arg);
-}
-
-/*
- * Destroys a node info instance.
- * Args:
- * node - The libcras_node_info pointer to destroy.
- */
-void libcras_node_info_destroy(struct libcras_node_info *node);
-
-/*
- * Destroys a node info array.
- * Args:
- * nodes - The libcras_node_info pointer array to destroy.
- * num - The size of the array.
- */
-void libcras_node_info_array_destroy(struct libcras_node_info **nodes,
- size_t num);
-
-/*
- * Gets ID from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * id - The pointer to save ID.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_id(struct libcras_node_info *node,
- uint64_t *id)
-{
- return node->get_id(node->node_, id);
-}
-
-/*
- * Gets device index from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * dev_idx - The pointer to the device index.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_dev_idx(struct libcras_node_info *node,
- uint32_t *dev_idx)
-{
- return node->get_dev_idx(node->node_, dev_idx);
-}
-
-/*
- * Gets node index from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * node_idx - The pointer to save the node index.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_node_idx(struct libcras_node_info *node,
- uint32_t *node_idx)
-{
- return node->get_node_idx(node->node_, node_idx);
-}
-
-/*
- * Gets the max supported channels from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * max_supported_channels - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int
-libcras_node_info_get_max_supported_channels(struct libcras_node_info *node,
- uint32_t *max_supported_channels)
-{
- return node->get_max_supported_channels(node->node_,
- max_supported_channels);
-}
-
-/*
- * Gets whether the node is plugged from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * plugged - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_is_plugged(struct libcras_node_info *node,
- bool *plugged)
-{
- return node->is_plugged(node->node_, plugged);
-}
-
-/*
- * Gets whether the node is active from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * active - The pointer to save the result.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_is_active(struct libcras_node_info *node,
- bool *active)
-{
- return node->is_active(node->node_, active);
-}
-
-/*
- * Gets device type from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * type - The pointer to save the device type.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_type(struct libcras_node_info *node,
- char **type)
-{
- return node->get_type(node->node_, type);
-}
-
-/*
- * Gets device name from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * name - The pointer to save the device name.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_node_name(struct libcras_node_info *node,
- char **name)
-{
- return node->get_node_name(node->node_, name);
-}
-
-/*
- * Gets node name from the node info pointer.
- * Args:
- * node - The node info pointer. (Returned from libcras_client_get_nodes)
- * name - The pointer to save the node name.
- * Returns:
- * 0 on success negative error code on failure (from errno.h).
- */
-DISABLE_CFI_ICALL
-inline int libcras_node_info_get_dev_name(struct libcras_node_info *node,
- char **name)
-{
- return node->get_dev_name(node->node_, name);
-}
-
#ifdef __cplusplus
}
#endif
diff --git a/cras/src/plc/cras_plc.c b/cras/src/plc/cras_plc.c
index 74c3568b..ed42ae97 100644
--- a/cras/src/plc/cras_plc.c
+++ b/cras/src/plc/cras_plc.c
@@ -22,9 +22,6 @@
#define PLC_SBCRL 36 /* SBC Reconvergence sample Length */
#define PLC_OLAL 16 /* OverLap-Add Length */
-#define PLC_WINDOW_SIZE 5
-#define PLC_PL_THRESHOLD 2
-
/* The pre-computed zero input bit stream of mSBC codec, per HFP 1.7 spec.
* This mSBC frame will be decoded into all-zero input PCM. */
static const uint8_t msbc_zero_frame[] = {
@@ -43,18 +40,6 @@ static const float rcos[PLC_OLAL] = { 0.99148655f, 0.96623611f, 0.92510857f,
0.13049554f, 0.07489143f, 0.03376389f,
0.00851345f };
-/* This structure tracks the packet loss information for last PLC_WINDOW_SIZE
- * of packets:
- * loss_hist - The packet loss history of receiving packets. 1 means lost.
- * ptr - The index of the to be updated packet loss status.
- * count - The count of lost packets in the window.
- */
-struct packet_window {
- uint8_t loss_hist[PLC_WINDOW_SIZE];
- unsigned int ptr;
- unsigned int count;
-};
-
/* The PLC is specifically designed for mSBC. The algorithm searches the
* history of receiving samples to find the best match samples and constructs
* substitutions for the lost samples. The selection is based on pattern
@@ -72,30 +57,23 @@ struct packet_window {
* frame.
* zero_frame - A buffer used for storing the samples from decoding the
* mSBC zero frame packet.
- * pl_window - A window monitoring how many packets are bad within the recent
- * PLC_WINDOW_SIZE of packets. This is used to determine if we
- * want to disable the PLC temporarily.
*/
struct cras_msbc_plc {
int16_t hist[PLC_HL + MSBC_FS + PLC_SBCRL + PLC_OLAL];
unsigned int best_lag;
int handled_bad_frames;
int16_t zero_frame[MSBC_FS];
- struct packet_window *pl_window;
};
struct cras_msbc_plc *cras_msbc_plc_create()
{
struct cras_msbc_plc *plc =
(struct cras_msbc_plc *)calloc(1, sizeof(*plc));
- plc->pl_window =
- (struct packet_window *)calloc(1, sizeof(*plc->pl_window));
return plc;
}
void cras_msbc_plc_destroy(struct cras_msbc_plc *plc)
{
- free(plc->pl_window);
free(plc);
}
@@ -116,33 +94,14 @@ void overlap_add(int16_t *output, float scaler_d, const int16_t *desc,
}
}
-void update_plc_state(struct packet_window *w, uint8_t is_packet_loss)
-{
- uint8_t *curr = &w->loss_hist[w->ptr];
- if (is_packet_loss != *curr) {
- w->count += (is_packet_loss - *curr);
- *curr = is_packet_loss;
- }
- w->ptr = (w->ptr + 1) % PLC_WINDOW_SIZE;
-}
-
-int possibly_pause_plc(struct packet_window *w)
-{
- /* The packet loss count comes from a time window and we use it as an
- * indicator of our confidence of the PLC algorithm. It is known to
- * generate poorer and robotic feeling sounds, when the majority of
- * samples in the PLC history buffer are from the concealment results.
- */
- return w->count >= PLC_PL_THRESHOLD;
-}
-
int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc *state,
const uint8_t *input, uint8_t *output)
{
int16_t *frame_head, *input_samples, *output_samples;
if (state->handled_bad_frames == 0) {
- /* If there was no packet concealment before this good frame,
- * we just simply copy the input to output without reconverge.
+ /* If there was no packet loss before this good frame, there
+ * is nothing we need to do to the frame so we'll just pass
+ * the input to output.
*/
memmove(output, input, MSBC_FS * MSBC_SAMPLE_SIZE);
} else {
@@ -170,7 +129,6 @@ int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc *state,
(PLC_HL - MSBC_FS) * MSBC_SAMPLE_SIZE);
memcpy(&state->hist[PLC_HL - MSBC_FS], output,
MSBC_FS * MSBC_SAMPLE_SIZE);
- update_plc_state(state->pl_window, 0);
return MSBC_CODE_SIZE;
}
@@ -183,7 +141,7 @@ float cross_correlation(int16_t *x, int16_t *y)
x2 += ((float)x[i]) * x[i];
y2 += ((float)y[i]) * y[i];
}
- return sum / sqrtf(x2 * y2);
+ return sum / sqrt(x2 * y2);
}
int pattern_match(int16_t *hist)
@@ -226,60 +184,37 @@ int cras_msbc_plc_handle_bad_frames(struct cras_msbc_plc *state,
int16_t *frame_head = &state->hist[PLC_HL];
size_t pcm_decoded = 0;
- /* mSBC codec is stateful, the history of signal would contribute to the
- * decode result state->zero_frame.
- */
codec->decode(codec, msbc_zero_frame, MSBC_PKT_LEN, state->zero_frame,
MSBC_FS, &pcm_decoded);
- /* The PLC algorithm is more likely to generate bad results that sound
- * robotic after severe packet losses happened. Only applying it when
- * we are confident.
- */
- if (!possibly_pause_plc(state->pl_window)) {
- if (state->handled_bad_frames == 0) {
- /* Finds the best matching samples and amplitude */
- state->best_lag = pattern_match(state->hist) + PLC_TL;
- best_match_hist = &state->hist[state->best_lag];
- scaler = amplitude_match(&state->hist[PLC_HL - MSBC_FS],
- best_match_hist);
-
- /* Constructs the substitution samples */
- overlap_add(frame_head, 1.0, state->zero_frame, scaler,
- best_match_hist);
- for (int i = PLC_OLAL; i < MSBC_FS; i++)
- state->hist[PLC_HL + i] =
- f_to_s16(scaler * best_match_hist[i]);
- overlap_add(&frame_head[MSBC_FS], scaler,
- &best_match_hist[MSBC_FS], 1.0,
- &best_match_hist[MSBC_FS]);
-
- memmove(&frame_head[MSBC_FS + PLC_OLAL],
- &best_match_hist[MSBC_FS + PLC_OLAL],
- PLC_SBCRL * MSBC_SAMPLE_SIZE);
- } else {
- memmove(frame_head, &state->hist[state->best_lag],
- (MSBC_FS + PLC_SBCRL + PLC_OLAL) *
- MSBC_SAMPLE_SIZE);
- }
- state->handled_bad_frames++;
+ if (state->handled_bad_frames == 0) {
+ /* Finds the best matching samples and amplitude */
+ state->best_lag = pattern_match(state->hist) + PLC_TL;
+ best_match_hist = &state->hist[state->best_lag];
+ scaler = amplitude_match(&state->hist[PLC_HL - MSBC_FS],
+ best_match_hist);
+
+ /* Constructs the substitution samples */
+ overlap_add(frame_head, 1.0, state->zero_frame, scaler,
+ best_match_hist);
+ for (int i = PLC_OLAL; i < MSBC_FS; i++)
+ state->hist[PLC_HL + i] =
+ f_to_s16(scaler * best_match_hist[i]);
+ overlap_add(&frame_head[MSBC_FS], scaler,
+ &best_match_hist[MSBC_FS], 1.0,
+ &best_match_hist[MSBC_FS]);
+
+ memmove(&frame_head[MSBC_FS + PLC_OLAL],
+ &best_match_hist[MSBC_FS + PLC_OLAL],
+ PLC_SBCRL * MSBC_SAMPLE_SIZE);
} else {
- /* This is a case similar to receiving a good frame with all
- * zeros, we set handled_bad_frames to zero to prevent the
- * following good frame from being concealed to reconverge with
- * the zero frames we fill in. The concealment result sounds
- * more artificial and weird than simply writing zeros and
- * following samples.
- */
- memmove(frame_head, state->zero_frame, MSBC_CODE_SIZE);
- memset(frame_head + MSBC_CODE_SIZE, 0,
- (PLC_SBCRL + PLC_OLAL) * MSBC_SAMPLE_SIZE);
- state->handled_bad_frames = 0;
+ memmove(frame_head, &state->hist[state->best_lag],
+ (MSBC_FS + PLC_SBCRL + PLC_OLAL) * MSBC_SAMPLE_SIZE);
}
+ state->handled_bad_frames++;
memcpy(output, frame_head, MSBC_CODE_SIZE);
memmove(state->hist, &state->hist[MSBC_FS],
(PLC_HL + PLC_SBCRL + PLC_OLAL) * MSBC_SAMPLE_SIZE);
- update_plc_state(state->pl_window, 1);
return MSBC_CODE_SIZE;
}
diff --git a/cras/src/plc/cras_plc_test.c b/cras/src/plc/cras_plc_test.c
index 4b7a6a77..458f1254 100644
--- a/cras/src/plc/cras_plc_test.c
+++ b/cras/src/plc/cras_plc_test.c
@@ -4,13 +4,11 @@
*/
#include <errno.h>
-#include <getopt.h>
#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -31,65 +29,32 @@ static const uint8_t msbc_zero_frame[] = {
0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c
};
-bool *generate_pl_seq(int input_file_size, float pl_percent)
+bool *generate_pl_seq(unsigned pk_count, unsigned loss_count)
{
- unsigned pk_count, pl_count;
- bool *seq;
-
- pk_count = input_file_size / MSBC_CODE_SIZE;
- pl_count = pk_count * (pl_percent / 100.0);
- seq = (bool *)calloc(pk_count, sizeof(*seq));
+ bool *seq = (bool *)calloc(pk_count, sizeof(*seq));
srand(RND_SEED);
- while (pl_count > 0) {
+ while (loss_count > 0) {
bool *missed = &seq[rand() % pk_count];
if (!*missed) {
*missed = true;
- pl_count--;
- }
- }
- return seq;
-}
-
-/* pl_hex is expected to be consecutive bytes(two chars) in hex format.*/
-bool *parse_pl_hex(int input_file_size, const char *pl_hex)
-{
- char tmp[3];
- uint8_t val = 0;
- int i, pl_hex_len, seq_len;
- bool *seq;
-
- pl_hex_len = strlen(pl_hex);
- seq_len = MAX(1 + input_file_size / MSBC_CODE_SIZE, pl_hex_len * 4);
- seq = (bool *)calloc(seq_len, sizeof(*seq));
-
- for (i = 0; i < seq_len; i++) {
- /* If sequence is longer then the provided pl_hex, leave the
- * rest to all zeros. */
- if (i > pl_hex_len * 4)
- break;
- if (i % 8 == 0) {
- memcpy(tmp, pl_hex + i / 4, 2);
- tmp[2] = '\0';
- val = strtol(tmp, NULL, 16);
+ loss_count--;
}
- seq[i] = val & 1U;
- val >>= 1;
}
- printf("pl_hex string maps to %ld ms, total sequence size %f ms\n",
- strlen(pl_hex) * 30, seq_len * 7.5f);
return seq;
}
-void plc_experiment(const char *input_filename, bool *pl_seq, bool with_plc)
+void plc_experiment(char *input_filename, float pl_percent, bool with_plc)
{
char output_filename[255];
int input_fd, output_fd, rc;
+ struct stat st;
+ bool *pl_seq;
struct cras_audio_codec *msbc_input = cras_msbc_codec_create();
struct cras_audio_codec *msbc_output = cras_msbc_codec_create();
struct cras_msbc_plc *plc = cras_msbc_plc_create();
uint8_t buffer[MSBC_CODE_SIZE], packet_buffer[MSBC_PKT_FRAME_LEN];
size_t encoded, decoded;
- unsigned count = 0;
+ unsigned pk_count, pl_count, count = 0;
input_fd = open(input_filename, O_RDONLY);
if (input_fd == -1) {
@@ -98,9 +63,9 @@ void plc_experiment(const char *input_filename, bool *pl_seq, bool with_plc)
}
if (with_plc)
- sprintf(output_filename, "output_with_plc.raw");
+ sprintf(output_filename, "output_%2.2f_plc.raw", pl_percent);
else
- sprintf(output_filename, "output_with_zero.raw");
+ sprintf(output_filename, "output_%2.2f_zero.raw", pl_percent);
output_fd = open(output_filename, O_CREAT | O_RDWR | O_TRUNC, 0644);
if (output_fd == -1) {
@@ -109,6 +74,11 @@ void plc_experiment(const char *input_filename, bool *pl_seq, bool with_plc)
return;
}
+ fstat(input_fd, &st);
+ pk_count = st.st_size / MSBC_CODE_SIZE;
+ pl_count = pk_count * (pl_percent / 100.0);
+ pl_seq = generate_pl_seq(pk_count, pl_count);
+
while (1) {
rc = read(input_fd, buffer, MSBC_CODE_SIZE);
if (rc < 0) {
@@ -147,77 +117,19 @@ void plc_experiment(const char *input_filename, bool *pl_seq, bool with_plc)
}
}
-static void show_usage()
-{
- printf("This test only supports reading/writing raw audio with format:\n"
- "\t16000 sample rate, mono channel, S16_LE\n");
- printf("--help - Print this usage.\n");
- printf("--input_file - path to an audio file.\n");
- printf("--pattern - Hex string representing consecutive packets'"
- "status.\n");
- printf("--random - Percentage of packet loss.\n");
-}
-
int main(int argc, char **argv)
{
- int fd;
- struct stat st;
- float pl_percent;
- int pl_percent_set = 0;
- int option_character;
- int option_index = 0;
- const char *input_file = NULL;
- const char *pl_hex = NULL;
- bool *pl_seq = NULL;
- static struct option long_options[] = {
- { "help", no_argument, NULL, 'h' },
- { "input", required_argument, NULL, 'i' },
- { "pattern", required_argument, NULL, 'p' },
- { "random", required_argument, NULL, 'r' },
- { NULL, 0, NULL, 0 },
- };
-
- while (true) {
- option_character = getopt_long(argc, argv, "i:r:p:h",
- long_options, &option_index);
- if (option_character == -1)
- break;
- switch (option_character) {
- case 'h':
- show_usage();
- break;
- case 'i':
- input_file = optarg;
- break;
- case 'p':
- pl_hex = optarg;
- break;
- case 'r':
- pl_percent = atof(optarg);
- pl_percent_set = 1;
- break;
- default:
- break;
- }
- }
-
- if ((!pl_percent_set && !pl_hex) || !input_file) {
- show_usage();
+ if (argc != 3) {
+ printf("Usage: cras_plc_test input.raw pl_percentage\n"
+ "This test only supports reading/writing files with "
+ "format:\n"
+ "- raw pcm\n"
+ "- 16000 sample rate\n"
+ "- mono channel\n"
+ "- S16_LE sample format\n");
return 1;
}
- fd = open(input_file, O_RDONLY);
- if (fd == -1) {
- fprintf(stderr, "Cannout open input file %s\n", input_file);
- return 1;
- }
- fstat(fd, &st);
- close(fd);
- if (pl_percent_set)
- pl_seq = generate_pl_seq(st.st_size, pl_percent);
- else if (pl_hex)
- pl_seq = parse_pl_hex(st.st_size, pl_hex);
-
- plc_experiment(input_file, pl_seq, true);
- plc_experiment(input_file, pl_seq, false);
+ plc_experiment(argv[1], atof(argv[2]), true);
+ plc_experiment(argv[1], atof(argv[2]), false);
}
diff --git a/cras/src/plc/parse_sco.py b/cras/src/plc/parse_sco.py
deleted file mode 100755
index c50df159..00000000
--- a/cras/src/plc/parse_sco.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-A script to extract raw SCO RX packets from btsnoop.
-Use 'btmon -S' to dump SCO traffic from btsnoop file.
-Trim the btsnoop output to just the SCO traffic period.
-Then execute 'python parse-sco.py <btsnoop-output>'
-"""
-
-import atexit
-import binascii
-import os
-import re
-import sys
-
-
-class SCOParser:
- """
- Parser for grepping SCO packets
- """
-
- def __init__(self):
- # On old releases, +CIEV: 4,1 indicates the start point of call session
- # c 31 0d 0a 9a ..+CIEV: 4,1..
- self.call_start_re = re.compile(r'.*?\+CIEV:\s4,(\d).*?')
-
- # > SCO Data RX: Handle 257 flags 0x00 dlen 60 #13826 [hci0] 650.388305
- # 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- # 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- # 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
- # 00 00 00 00 00 00 00 00 00 00 00 00
- self.sco_rx_re = re.compile(r'.*?SCO\sData\sRX.*?flags\s0x(\d+).*?')
- self.sco_f = None
- self.output_idx = 0
- self.pk_count = 0
- self.pl_count = 0
-
- atexit.register(self._cleanup)
-
- def _cleanup(self):
- if self.sco_f is not None:
- print(
- "Current file contains %d packets (%d with erroneous status flag)" %
- (self.pk_count, self.pl_count))
- self.pk_count = 0
- self.pl_count = 0
- self.sco_f.close()
-
- def _new_session(self):
- if self.sco_f is not None:
- close(self.sco_f)
-
- new_file = "sco_file_%d" % self.output_idx
- print("Record to %s" % new_file)
- self.sco_f = open(new_file, 'wb')
- self.output_idx += 1
-
- return self.sco_f
-
- def parse(self, filename):
- if not os.path.exists(filename):
- print("%s doesn't exist" % filename)
- return
-
- print("Start parsing %s" % filename)
- parse_rx_data = 0
- with open(filename, "r") as f:
- for line in f.readlines():
- if parse_rx_data > 0:
- self.sco_f.write(binascii.unhexlify(''.join(line[:56].split())))
- parse_rx_data = (parse_rx_data + 1) % 5
-
- # Start a new session and output following SCO data to a new file
- match = self.call_start_re.search(line)
- if match and (1 == int(match.group(1))):
- self._new_session()
- continue
-
- match = self.sco_rx_re.search(line)
- if match:
- if self.sco_f is None:
- self._new_session()
-
- self.pk_count += 1
-
- status_flag = int(match.group(1))
- hdr = ['01', str(status_flag) + '1', '3c']
- if status_flag != 0:
- self.pl_count += 1
-
- self.sco_f.write(binascii.unhexlify(''.join(hdr)))
- parse_rx_data = 1
-
-
-def main(argv):
- if len(argv) < 1:
- print("parse_sco.py [btsnoop.txt]")
- return
-
- p = SCOParser()
- p.parse(argv[0])
-
-
-if __name__ == "__main__":
- main(sys.argv[1:])
diff --git a/cras/src/server/audio_thread.c b/cras/src/server/audio_thread.c
index 48bb0dc2..d7ef8bd6 100644
--- a/cras/src/server/audio_thread.c
+++ b/cras/src/server/audio_thread.c
@@ -37,13 +37,6 @@
*/
#define MAX_CONTINUOUS_ZERO_SLEEP_COUNT 2
-/*
- * If the number of continuous zero sleep is equal to this limit, the value
- * will be recorded immediately. It can ensure all busyloop will be recorded
- * even if the busyloop does not stop.
- */
-#define MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT 1000
-
/* Messages that can be sent from the main context to the audio thread. */
enum AUDIO_THREAD_COMMAND {
AUDIO_THREAD_ADD_OPEN_DEV,
@@ -124,16 +117,16 @@ static struct iodev_callback_list *iodev_callbacks;
struct iodev_callback_list {
int fd;
- int events;
- enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger;
+ int is_write;
+ int enabled;
thread_callback cb;
void *cb_data;
struct pollfd *pollfd;
struct iodev_callback_list *prev, *next;
};
-void audio_thread_add_events_callback(int fd, thread_callback cb, void *data,
- int events)
+static void _audio_thread_add_callback(int fd, thread_callback cb, void *data,
+ int is_write)
{
struct iodev_callback_list *iodev_cb;
@@ -146,12 +139,22 @@ void audio_thread_add_events_callback(int fd, thread_callback cb, void *data,
iodev_cb->fd = fd;
iodev_cb->cb = cb;
iodev_cb->cb_data = data;
- iodev_cb->trigger = TRIGGER_POLL;
- iodev_cb->events = events;
+ iodev_cb->enabled = 1;
+ iodev_cb->is_write = is_write;
DL_APPEND(iodev_callbacks, iodev_cb);
}
+void audio_thread_add_callback(int fd, thread_callback cb, void *data)
+{
+ _audio_thread_add_callback(fd, cb, data, 0);
+}
+
+void audio_thread_add_write_callback(int fd, thread_callback cb, void *data)
+{
+ _audio_thread_add_callback(fd, cb, data, 1);
+}
+
void audio_thread_rm_callback(int fd)
{
struct iodev_callback_list *iodev_cb;
@@ -165,14 +168,13 @@ void audio_thread_rm_callback(int fd)
}
}
-void audio_thread_config_events_callback(
- int fd, enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger)
+void audio_thread_enable_callback(int fd, int enabled)
{
struct iodev_callback_list *iodev_cb;
DL_FOREACH (iodev_callbacks, iodev_cb) {
if (iodev_cb->fd == fd) {
- iodev_cb->trigger = trigger;
+ iodev_cb->enabled = !!enabled;
return;
}
}
@@ -443,8 +445,7 @@ static int thread_add_stream(struct audio_thread *thread,
{
int rc;
- rc = dev_io_append_stream(&thread->open_devs[CRAS_STREAM_OUTPUT],
- &thread->open_devs[CRAS_STREAM_INPUT], stream,
+ rc = dev_io_append_stream(&thread->open_devs[stream->direction], stream,
iodevs, num_iodevs);
if (rc < 0)
return rc;
@@ -556,11 +557,8 @@ static void append_stream_dump_info(struct audio_debug_info *info,
si->runtime_nsec = time_since.tv_nsec;
}
-/* Handle a message sent from main thread to the audio thread.
- * Returns:
- * Error code when reading or sending message fails.
- */
-static int handle_audio_thread_message(struct audio_thread *thread)
+/* Handle a message sent to the playback thread */
+static int handle_playback_thread_message(struct audio_thread *thread)
{
uint8_t buf[256];
struct audio_thread_msg *msg = (struct audio_thread_msg *)buf;
@@ -715,7 +713,7 @@ static int handle_audio_thread_message(struct audio_thread *thread)
err = audio_thread_send_response(thread, ret);
if (err < 0)
return err;
- return 0;
+ return ret;
}
/* Returns the number of active streams plus the number of active devices. */
@@ -734,7 +732,7 @@ static int fill_next_sleep_interval(struct audio_thread *thread,
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
add_timespecs(&min_ts, &now);
ret = dev_io_next_output_wake(&thread->open_devs[CRAS_STREAM_OUTPUT],
- &min_ts);
+ &min_ts, &now);
ret += dev_io_next_input_wake(&thread->open_devs[CRAS_STREAM_INPUT],
&min_ts);
if (timespec_after(&min_ts, &now))
@@ -744,10 +742,13 @@ static int fill_next_sleep_interval(struct audio_thread *thread,
}
static struct pollfd *add_pollfd(struct audio_thread *thread, int fd,
- int events)
+ int is_write)
{
thread->pollfds[thread->num_pollfds].fd = fd;
- thread->pollfds[thread->num_pollfds].events = events;
+ if (is_write)
+ thread->pollfds[thread->num_pollfds].events = POLLOUT;
+ else
+ thread->pollfds[thread->num_pollfds].events = POLLIN;
thread->num_pollfds++;
if (thread->num_pollfds >= thread->pollfds_size) {
thread->pollfds_size *= 2;
@@ -795,18 +796,7 @@ static void check_busyloop(struct timespec *wait_ts)
busyloop_count++;
cras_audio_thread_event_busyloop();
}
- if (continuous_zero_sleep_count ==
- MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
- cras_server_metrics_busyloop_length(
- continuous_zero_sleep_count);
-
} else {
- if (continuous_zero_sleep_count >=
- MAX_CONTINUOUS_ZERO_SLEEP_COUNT &&
- continuous_zero_sleep_count <
- MAX_CONTINUOUS_ZERO_SLEEP_METRIC_LIMIT)
- cras_server_metrics_busyloop_length(
- continuous_zero_sleep_count);
continuous_zero_sleep_count = 0;
}
}
@@ -839,7 +829,6 @@ static void *audio_io_thread(void *arg)
while (1) {
struct timespec *wait_ts;
struct iodev_callback_list *iodev_cb;
- int non_empty;
wait_ts = NULL;
thread->num_pollfds = 1;
@@ -849,9 +838,6 @@ static void *audio_io_thread(void *arg)
&thread->open_devs[CRAS_STREAM_INPUT],
thread->remix_converter);
- non_empty = dev_io_check_non_empty_state_transition(
- thread->open_devs[CRAS_STREAM_OUTPUT]);
-
if (fill_next_sleep_interval(thread, &ts))
wait_ts = &ts;
@@ -859,12 +845,10 @@ static void *audio_io_thread(void *arg)
thread->num_pollfds = 1;
DL_FOREACH (iodev_callbacks, iodev_cb) {
- if (iodev_cb->trigger != TRIGGER_POLL) {
- iodev_cb->pollfd = NULL;
+ if (!iodev_cb->enabled)
continue;
- }
iodev_cb->pollfd = add_pollfd(thread, iodev_cb->fd,
- iodev_cb->events);
+ iodev_cb->is_write);
if (!iodev_cb->pollfd)
goto restart_poll_loop;
}
@@ -875,7 +859,7 @@ static void *audio_io_thread(void *arg)
int fd = dev_stream_poll_stream_fd(curr);
if (fd < 0)
continue;
- if (!add_pollfd(thread, fd, POLLIN))
+ if (!add_pollfd(thread, fd, 0))
goto restart_poll_loop;
}
}
@@ -884,7 +868,7 @@ static void *audio_io_thread(void *arg)
int fd = dev_stream_poll_stream_fd(curr);
if (fd < 0)
continue;
- if (!add_pollfd(thread, fd, POLLIN))
+ if (!add_pollfd(thread, fd, 0))
goto restart_poll_loop;
}
}
@@ -892,7 +876,7 @@ static void *audio_io_thread(void *arg)
log_busyloop(wait_ts);
ATLOG(atlog, AUDIO_THREAD_SLEEP, wait_ts ? wait_ts->tv_sec : 0,
- wait_ts ? wait_ts->tv_nsec : 0, non_empty);
+ wait_ts ? wait_ts->tv_nsec : 0, 0);
if (wait_ts)
check_busyloop(wait_ts);
@@ -902,33 +886,21 @@ static void *audio_io_thread(void *arg)
rc = ppoll(thread->pollfds, thread->num_pollfds, wait_ts, NULL);
ATLOG(atlog, AUDIO_THREAD_WAKE, rc, 0, 0);
-
- /* Handle callbacks registered by TRIGGER_WAKEUP */
- DL_FOREACH (iodev_callbacks, iodev_cb) {
- if (iodev_cb->trigger == TRIGGER_WAKEUP) {
- ATLOG(atlog, AUDIO_THREAD_IODEV_CB, 0, 0, 0);
- iodev_cb->cb(iodev_cb->cb_data, 0);
- }
- }
-
- /* If there's no pollfd ready to handle. */
if (rc <= 0)
continue;
if (thread->pollfds[0].revents & POLLIN) {
- rc = handle_audio_thread_message(thread);
+ rc = handle_playback_thread_message(thread);
if (rc < 0)
syslog(LOG_ERR, "handle message %d", rc);
}
DL_FOREACH (iodev_callbacks, iodev_cb) {
if (iodev_cb->pollfd &&
- iodev_cb->pollfd->revents & iodev_cb->events) {
+ iodev_cb->pollfd->revents & (POLLIN | POLLOUT)) {
ATLOG(atlog, AUDIO_THREAD_IODEV_CB,
- iodev_cb->pollfd->revents,
- iodev_cb->events, 0);
- iodev_cb->cb(iodev_cb->cb_data,
- iodev_cb->pollfd->revents);
+ iodev_cb->is_write, 0, 0);
+ iodev_cb->cb(iodev_cb->cb_data);
}
}
}
diff --git a/cras/src/server/audio_thread.h b/cras/src/server/audio_thread.h
index 34b47863..5e5e9956 100644
--- a/cras/src/server/audio_thread.h
+++ b/cras/src/server/audio_thread.h
@@ -45,24 +45,11 @@ struct audio_thread {
struct cras_fmt_conv *remix_converter;
};
-/*
- * Enum to specify how a registered event callback be triggered.
- * TRIGGER_NONE - Callback will not be triggered.
- * TRIGGER_POLL - Triggered by poll given fd and revent.
- * TRIGGER_WAKEUP - Triggered everytime when audio thread wakes up.
- */
-enum AUDIO_THREAD_EVENTS_CB_TRIGGER {
- TRIGGER_NONE,
- TRIGGER_POLL,
- TRIGGER_WAKEUP,
-};
-
/* Callback function to be handled in main loop in audio thread.
* Args:
* data - The data for callback function.
- * revent - The returned event from ppoll().
*/
-typedef int (*thread_callback)(void *data, int revent);
+typedef int (*thread_callback)(void *data);
/* Creates an audio thread.
* Returns:
@@ -96,17 +83,23 @@ int audio_thread_rm_open_dev(struct audio_thread *thread,
int audio_thread_is_dev_open(struct audio_thread *thread,
struct cras_iodev *dev);
-/* Adds a thread_callback to audio thread for requested events. By default
- * the callback trigger is set to TRIGGER_POLL.
+/* Adds an thread_callback to audio thread.
+ * Args:
+ * fd - The file descriptor to be polled for the callback.
+ * The callback will be called when fd is readable.
+ * cb - The callback function.
+ * data - The data for the callback function.
+ */
+void audio_thread_add_callback(int fd, thread_callback cb, void *data);
+
+/* Adds an thread_callback to audio thread.
* Args:
* fd - The file descriptor to be polled for the callback.
- * The callback will be called when any of requested events matched.
+ * The callback will be called when fd is writeable.
* cb - The callback function.
* data - The data for the callback function.
- * events - The requested events to ppoll().
*/
-void audio_thread_add_events_callback(int fd, thread_callback cb, void *data,
- int events);
+void audio_thread_add_write_callback(int fd, thread_callback cb, void *data);
/* Removes an thread_callback from audio thread.
* Args:
@@ -121,13 +114,8 @@ void audio_thread_rm_callback(int fd);
*/
int audio_thread_rm_callback_sync(struct audio_thread *thread, int fd);
-/* Configures the callback associated with fd when it should be triggerred.
- * Args:
- * fd - The file descriptor associate to the callback.
- * trigger - Specifies how the callback should be triggered.
- */
-void audio_thread_config_events_callback(
- int fd, enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger);
+/* Enables or Disabled the callback associated with fd. */
+void audio_thread_enable_callback(int fd, int enabled);
/* Starts a thread created with audio_thread_create.
* Args:
diff --git a/cras/src/server/config/cras_board_config.c b/cras/src/server/config/cras_board_config.c
index e36ea3cf..9acdf82c 100644
--- a/cras/src/server/config/cras_board_config.c
+++ b/cras/src/server/config/cras_board_config.c
@@ -3,95 +3,59 @@
* found in the LICENSE file.
*/
-#include <errno.h>
#include <syslog.h>
#include "cras_board_config.h"
#include "iniparser_wrapper.h"
+/* Allocate 63 chars + 1 for null where declared. */
+static const unsigned int MAX_INI_NAME_LEN = 63;
+static const unsigned int MAX_KEY_LEN = 63;
static const int32_t DEFAULT_OUTPUT_BUFFER_SIZE = 512;
static const int32_t AEC_SUPPORTED_DEFAULT = 0;
static const int32_t AEC_GROUP_ID_DEFAULT = -1;
-static const int32_t BLUETOOTH_WBS_ENABLED_INI_DEFAULT = 1;
-static const int32_t BLUETOOTH_DEPRIORITIZE_WBS_MIC_INI_DEFAULT = 0;
-static const int32_t HOTWORD_PAUSE_AT_SUSPEND_DEFAULT = 0;
#define CONFIG_NAME "board.ini"
#define DEFAULT_OUTPUT_BUF_SIZE_INI_KEY "output:default_output_buffer_size"
#define AEC_SUPPORTED_INI_KEY "processing:aec_supported"
#define AEC_GROUP_ID_INI_KEY "processing:group_id"
-#define BLUETOOTH_WBS_ENABLED_INI_KEY "bluetooth:wbs_enabled"
-#define BLUETOOTH_DEPRIORITIZE_WBS_MIC_INI_KEY "bluetooth:deprioritize_wbs_mic"
-#define UCM_IGNORE_SUFFIX_KEY "ucm:ignore_suffix"
-#define HOTWORD_PAUSE_AT_SUSPEND "hotword:pause_at_suspend"
void cras_board_config_get(const char *config_path,
struct cras_board_config *board_config)
{
- char ini_name[MAX_INI_NAME_LENGTH + 1];
- char ini_key[MAX_INI_KEY_LENGTH + 1];
- const char *ptr;
+ char ini_name[MAX_INI_NAME_LEN + 1];
+ char ini_key[MAX_KEY_LEN + 1];
dictionary *ini;
board_config->default_output_buffer_size = DEFAULT_OUTPUT_BUFFER_SIZE;
board_config->aec_supported = AEC_SUPPORTED_DEFAULT;
board_config->aec_group_id = AEC_GROUP_ID_DEFAULT;
- board_config->ucm_ignore_suffix = NULL;
- board_config->bt_wbs_enabled = BLUETOOTH_WBS_ENABLED_INI_DEFAULT;
- board_config->deprioritize_bt_wbs_mic =
- BLUETOOTH_DEPRIORITIZE_WBS_MIC_INI_DEFAULT;
if (config_path == NULL)
return;
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", config_path,
- CONFIG_NAME);
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
+ snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_path, CONFIG_NAME);
+ ini_name[MAX_INI_NAME_LEN] = '\0';
ini = iniparser_load_wrapper(ini_name);
if (ini == NULL) {
syslog(LOG_DEBUG, "No ini file %s", ini_name);
return;
}
- snprintf(ini_key, MAX_INI_KEY_LENGTH, DEFAULT_OUTPUT_BUF_SIZE_INI_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, DEFAULT_OUTPUT_BUF_SIZE_INI_KEY);
+ ini_key[MAX_KEY_LEN] = 0;
board_config->default_output_buffer_size =
iniparser_getint(ini, ini_key, DEFAULT_OUTPUT_BUFFER_SIZE);
- snprintf(ini_key, MAX_INI_KEY_LENGTH, AEC_SUPPORTED_INI_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, AEC_SUPPORTED_INI_KEY);
+ ini_key[MAX_KEY_LEN] = 0;
board_config->aec_supported =
iniparser_getint(ini, ini_key, AEC_SUPPORTED_DEFAULT);
- snprintf(ini_key, MAX_INI_KEY_LENGTH, AEC_GROUP_ID_INI_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, AEC_GROUP_ID_INI_KEY);
+ ini_key[MAX_KEY_LEN] = 0;
board_config->aec_group_id =
iniparser_getint(ini, ini_key, AEC_GROUP_ID_DEFAULT);
- snprintf(ini_key, MAX_INI_KEY_LENGTH, BLUETOOTH_WBS_ENABLED_INI_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
- board_config->bt_wbs_enabled = iniparser_getint(
- ini, ini_key, BLUETOOTH_WBS_ENABLED_INI_DEFAULT);
-
- snprintf(ini_key, MAX_INI_KEY_LENGTH,
- BLUETOOTH_DEPRIORITIZE_WBS_MIC_INI_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
- board_config->deprioritize_bt_wbs_mic = iniparser_getint(
- ini, ini_key, BLUETOOTH_DEPRIORITIZE_WBS_MIC_INI_DEFAULT);
-
- snprintf(ini_key, MAX_INI_KEY_LENGTH, UCM_IGNORE_SUFFIX_KEY);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
- ptr = iniparser_getstring(ini, ini_key, "");
- if (ptr) {
- board_config->ucm_ignore_suffix = strdup(ptr);
- if (!board_config->ucm_ignore_suffix)
- syslog(LOG_ERR, "Failed to call strdup: %d", errno);
- }
-
- snprintf(ini_key, MAX_INI_KEY_LENGTH, HOTWORD_PAUSE_AT_SUSPEND);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
- board_config->hotword_pause_at_suspend = iniparser_getint(
- ini, ini_key, HOTWORD_PAUSE_AT_SUSPEND_DEFAULT);
-
iniparser_freedict(ini);
syslog(LOG_DEBUG, "Loaded ini file %s", ini_name);
}
diff --git a/cras/src/server/config/cras_board_config.h b/cras/src/server/config/cras_board_config.h
index d4bd8496..92ef971c 100644
--- a/cras/src/server/config/cras_board_config.h
+++ b/cras/src/server/config/cras_board_config.h
@@ -12,10 +12,6 @@ struct cras_board_config {
int32_t default_output_buffer_size;
int32_t aec_supported;
int32_t aec_group_id;
- int32_t bt_wbs_enabled;
- int32_t deprioritize_bt_wbs_mic;
- char *ucm_ignore_suffix;
- int32_t hotword_pause_at_suspend;
};
/* Gets a configuration based on the config file specified.
diff --git a/cras/src/server/config/cras_card_config.c b/cras/src/server/config/cras_card_config.c
index ae36565d..f19d0855 100644
--- a/cras/src/server/config/cras_card_config.c
+++ b/cras/src/server/config/cras_card_config.c
@@ -10,6 +10,10 @@
#include "iniparser_wrapper.h"
#include "utlist.h"
+/* Allocate 63 chars + 1 for null where declared. */
+static const unsigned int MAX_INI_NAME_LEN = 63;
+static const unsigned int MAX_KEY_LEN = 63;
+
struct cras_card_config {
dictionary *ini;
};
@@ -18,15 +22,15 @@ static struct cras_volume_curve *
create_simple_step_curve(const struct cras_card_config *card_config,
const char *control_name)
{
- char ini_key[MAX_INI_KEY_LENGTH + 1];
+ char ini_key[MAX_KEY_LEN + 1];
int max_volume;
int volume_step;
- snprintf(ini_key, MAX_INI_KEY_LENGTH, "%s:max_volume", control_name);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, "%s:max_volume", control_name);
+ ini_key[MAX_KEY_LEN] = 0;
max_volume = iniparser_getint(card_config->ini, ini_key, 0);
- snprintf(ini_key, MAX_INI_KEY_LENGTH, "%s:volume_step", control_name);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, "%s:volume_step", control_name);
+ ini_key[MAX_KEY_LEN] = 0;
volume_step = iniparser_getint(card_config->ini, ini_key, 300);
syslog(LOG_INFO, "Configure curve found for %s.", control_name);
return cras_volume_curve_create_simple_step(max_volume, volume_step);
@@ -37,13 +41,12 @@ create_explicit_curve(const struct cras_card_config *card_config,
const char *control_name)
{
unsigned int i;
- char ini_key[MAX_INI_KEY_LENGTH + 1];
+ char ini_key[MAX_KEY_LEN + 1];
long dB_values[101];
for (i = 0; i < 101; i++) {
- snprintf(ini_key, MAX_INI_KEY_LENGTH, "%s:dB_at_%u",
- control_name, i);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, "%s:dB_at_%u", control_name, i);
+ ini_key[MAX_KEY_LEN] = 0;
dB_values[i] = iniparser_getint(card_config->ini, ini_key, 0);
}
syslog(LOG_INFO, "Explicit volume curve found for %s.", control_name);
@@ -58,12 +61,11 @@ struct cras_card_config *cras_card_config_create(const char *config_path,
const char *card_name)
{
struct cras_card_config *card_config = NULL;
- char ini_name[MAX_INI_NAME_LENGTH + 1];
+ char ini_name[MAX_INI_NAME_LEN + 1];
dictionary *ini;
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", config_path,
- card_name);
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
+ snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_path, card_name);
+ ini_name[MAX_INI_NAME_LEN] = '\0';
ini = iniparser_load_wrapper(ini_name);
if (ini == NULL) {
syslog(LOG_DEBUG, "No ini file %s", ini_name);
@@ -91,14 +93,14 @@ void cras_card_config_destroy(struct cras_card_config *card_config)
struct cras_volume_curve *cras_card_config_get_volume_curve_for_control(
const struct cras_card_config *card_config, const char *control_name)
{
- char ini_key[MAX_INI_KEY_LENGTH + 1];
+ char ini_key[MAX_KEY_LEN + 1];
const char *curve_type;
if (card_config == NULL || control_name == NULL)
return NULL;
- snprintf(ini_key, MAX_INI_KEY_LENGTH, "%s:volume_curve", control_name);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
+ snprintf(ini_key, MAX_KEY_LEN, "%s:volume_curve", control_name);
+ ini_key[MAX_KEY_LEN] = 0;
curve_type = iniparser_getstring(card_config->ini, ini_key, NULL);
if (curve_type && strcmp(curve_type, "simple_step") == 0)
diff --git a/cras/src/server/config/cras_device_blacklist.c b/cras/src/server/config/cras_device_blacklist.c
new file mode 100644
index 00000000..1d18eb0e
--- /dev/null
+++ b/cras/src/server/config/cras_device_blacklist.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "cras_device_blacklist.h"
+#include "iniparser_wrapper.h"
+#include "utlist.h"
+
+/* Allocate 63 chars + 1 for null where declared. */
+static const unsigned int MAX_INI_NAME_LEN = 63;
+static const unsigned int MAX_KEY_LEN = 63;
+
+struct cras_device_blacklist {
+ dictionary *ini;
+};
+
+/*
+ * Exported Interface
+ */
+
+struct cras_device_blacklist *
+cras_device_blacklist_create(const char *config_path)
+{
+ struct cras_device_blacklist *blacklist;
+ char ini_name[MAX_INI_NAME_LEN + 1];
+
+ blacklist = calloc(1, sizeof(*blacklist));
+ if (!blacklist)
+ return NULL;
+
+ snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_path,
+ "device_blacklist");
+ ini_name[MAX_INI_NAME_LEN] = '\0';
+ blacklist->ini = iniparser_load_wrapper(ini_name);
+
+ return blacklist;
+}
+
+void cras_device_blacklist_destroy(struct cras_device_blacklist *blacklist)
+{
+ if (blacklist && blacklist->ini)
+ iniparser_freedict(blacklist->ini);
+ free(blacklist);
+}
+
+int cras_device_blacklist_check(struct cras_device_blacklist *blacklist,
+ unsigned vendor_id, unsigned product_id,
+ unsigned desc_checksum, unsigned device_index)
+{
+ char ini_key[MAX_KEY_LEN + 1];
+
+ if (!blacklist)
+ return 0;
+
+ snprintf(ini_key, MAX_KEY_LEN, "USB_Outputs:%04x_%04x_%08x_%u",
+ vendor_id, product_id, desc_checksum, device_index);
+ ini_key[MAX_KEY_LEN] = 0;
+ return iniparser_getboolean(blacklist->ini, ini_key, 0);
+}
diff --git a/cras/src/server/config/cras_device_blocklist.h b/cras/src/server/config/cras_device_blacklist.h
index d0f750bd..ac7cfe23 100644
--- a/cras/src/server/config/cras_device_blocklist.h
+++ b/cras/src/server/config/cras_device_blacklist.h
@@ -8,41 +8,41 @@
* useful for devices that present non-functional alsa devices. For instance
* some mics show a phantom playback device.
*/
-#ifndef CRAS_DEVICE_BLOCKLIST_H_
-#define CRAS_DEVICE_BLOCKLIST_H_
+#ifndef CRAS_DEVICE_BLACKLIST_H_
+#define CRAS_DEVICE_BLACKLIST_H_
#include <stdint.h>
#include "cras_types.h"
-struct cras_device_blocklist;
+struct cras_device_blacklist;
-/* Creates a blocklist of devices that should never be added to the system.
+/* Creates a blacklist of devices that should never be added to the system.
* Args:
* config_path - Path containing the config files.
* Returns:
- * A pointer to the created blocklist on success, NULL on failure.
+ * A pointer to the created blacklist on success, NULL on failure.
*/
-struct cras_device_blocklist *
-cras_device_blocklist_create(const char *config_path);
+struct cras_device_blacklist *
+cras_device_blacklist_create(const char *config_path);
-/* Destroys a blocklist returned by cras_device_blocklist_create().
+/* Destroys a blacklist returned by cras_device_blacklist_create().
* Args:
- * blocklist - Blocklist returned by cras_device_blocklist_create()
+ * blacklist - Blacklist returned by cras_device_blacklist_create()
*/
-void cras_device_blocklist_destroy(struct cras_device_blocklist *blocklist);
+void cras_device_blacklist_destroy(struct cras_device_blacklist *blacklist);
-/* Checks if a playback device on a USB card is blocklisted.
+/* Checks if a playback device on a USB card is blacklisted.
* Args:
- * blocklist - Blocklist returned by cras_device_blocklist_create()
+ * blacklist - Blacklist returned by cras_device_blacklist_create()
* vendor_id - USB vendor ID.
* product_id - USB product ID.
* device_index - Index of the alsa device in the card.
* Returns:
- * 1 if the device is blocklisted, 0 otherwise.
+ * 1 if the device is blacklisted, 0 otherwise.
*/
-int cras_device_blocklist_check(struct cras_device_blocklist *blocklist,
+int cras_device_blacklist_check(struct cras_device_blacklist *blacklist,
unsigned vendor_id, unsigned product_id,
unsigned desc_checksum, unsigned device_index);
-#endif /* CRAS_CARD_DEVICE_BLOCKLIST_H_ */
+#endif /* CRAS_CARD_DEVICE_BLACKLIST_H_ */
diff --git a/cras/src/server/config/cras_device_blocklist.c b/cras/src/server/config/cras_device_blocklist.c
deleted file mode 100644
index d418fb80..00000000
--- a/cras/src/server/config/cras_device_blocklist.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "cras_device_blocklist.h"
-#include "iniparser_wrapper.h"
-#include "utlist.h"
-
-struct cras_device_blocklist {
- dictionary *ini;
-};
-
-/*
- * Exported Interface
- */
-
-struct cras_device_blocklist *
-cras_device_blocklist_create(const char *config_path)
-{
- struct cras_device_blocklist *blocklist;
- char ini_name[MAX_INI_NAME_LENGTH + 1];
-
- blocklist = calloc(1, sizeof(*blocklist));
- if (!blocklist)
- return NULL;
-
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", config_path,
- "device_blocklist");
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
- blocklist->ini = iniparser_load_wrapper(ini_name);
-
- return blocklist;
-}
-
-void cras_device_blocklist_destroy(struct cras_device_blocklist *blocklist)
-{
- if (blocklist && blocklist->ini)
- iniparser_freedict(blocklist->ini);
- free(blocklist);
-}
-
-int cras_device_blocklist_check(struct cras_device_blocklist *blocklist,
- unsigned vendor_id, unsigned product_id,
- unsigned desc_checksum, unsigned device_index)
-{
- char ini_key[MAX_INI_KEY_LENGTH + 1];
-
- if (!blocklist)
- return 0;
-
- snprintf(ini_key, MAX_INI_KEY_LENGTH, "USB_Outputs:%04x_%04x_%08x_%u",
- vendor_id, product_id, desc_checksum, device_index);
- ini_key[MAX_INI_KEY_LENGTH] = 0;
- return iniparser_getboolean(blocklist->ini, ini_key, 0);
-}
diff --git a/cras/src/server/cras.c b/cras/src/server/cras.c
index 8d23907a..32953ef3 100644
--- a/cras/src/server/cras.c
+++ b/cras/src/server/cras.c
@@ -9,7 +9,6 @@
#include <stdio.h>
#include <syslog.h>
-#include "cras_alsa_plugin_io.h"
#include "cras_apm_list.h"
#include "cras_config.h"
#include "cras_iodev_list.h"
@@ -38,7 +37,7 @@ static void set_signals()
int main(int argc, char **argv)
{
int c, option_index;
- int log_mask = LOG_WARNING;
+ int log_mask = LOG_ERR;
const char default_dsp_config[] = CRAS_CONFIG_FILE_DIR "/dsp.ini";
const char *dsp_config = default_dsp_config;
const char *device_config_dir = CRAS_CONFIG_FILE_DIR;
@@ -139,7 +138,6 @@ int main(int argc, char **argv)
cras_dsp_init(dsp_config);
cras_apm_list_init(device_config_dir);
cras_iodev_list_init();
- cras_alsa_plugin_io_init(device_config_dir);
/* Start the server. */
return cras_server_run(profile_disable_mask);
diff --git a/cras/src/server/cras_a2dp_info.c b/cras/src/server/cras_a2dp_info.c
index b2db3848..ffddb252 100644
--- a/cras/src/server/cras_a2dp_info.c
+++ b/cras/src/server/cras_a2dp_info.c
@@ -104,7 +104,7 @@ int a2dp_queued_frames(const struct a2dp_info *a2dp)
return a2dp->samples;
}
-void a2dp_reset(struct a2dp_info *a2dp)
+void a2dp_drain(struct a2dp_info *a2dp)
{
a2dp->a2dp_buf_used =
sizeof(struct rtp_header) + sizeof(struct rtp_payload);
@@ -180,7 +180,8 @@ int a2dp_encode(struct a2dp_info *a2dp, const void *pcm_buf, int pcm_buf_size,
int a2dp_write(struct a2dp_info *a2dp, int stream_fd, size_t link_mtu)
{
/* Do avdtp write when the max number of SBC frames is reached. */
- if (a2dp->a2dp_buf_used + a2dp->frame_length > link_mtu)
+ if (a2dp->a2dp_buf_used + a2dp->frame_length >
+ link_mtu - sizeof(struct rtp_header) - sizeof(struct rtp_payload))
return avdtp_write(stream_fd, a2dp);
return 0;
diff --git a/cras/src/server/cras_a2dp_info.h b/cras/src/server/cras_a2dp_info.h
index b33911e8..eaf00d5b 100644
--- a/cras/src/server/cras_a2dp_info.h
+++ b/cras/src/server/cras_a2dp_info.h
@@ -8,7 +8,7 @@
#include "a2dp-codecs.h"
-#define A2DP_BUF_SIZE_BYTES 2048
+#define A2DP_BUF_SIZE_BYTES 1024
/* Represents the codec and encoded state of a2dp iodev.
* Members:
@@ -60,9 +60,9 @@ int a2dp_block_size(struct a2dp_info *a2dp, int encoded_bytes);
int a2dp_queued_frames(const struct a2dp_info *a2dp);
/*
- * Empty all queued samples in a2dp_info.
+ * Drains queued samples in a2dp_info.
*/
-void a2dp_reset(struct a2dp_info *a2dp);
+void a2dp_drain(struct a2dp_info *a2dp);
/*
* Encodes samples using the codec for this a2dp instance, returns the number of
diff --git a/cras/src/server/cras_a2dp_iodev.c b/cras/src/server/cras_a2dp_iodev.c
index b8a606e4..f6351aba 100644
--- a/cras/src/server/cras_a2dp_iodev.c
+++ b/cras/src/server/cras_a2dp_iodev.c
@@ -20,24 +20,19 @@
#include "cras_a2dp_info.h"
#include "cras_a2dp_iodev.h"
#include "cras_audio_area.h"
-#include "cras_audio_thread_monitor.h"
#include "cras_bt_device.h"
#include "cras_iodev.h"
#include "cras_util.h"
+#include "sfh.h"
#include "rtp.h"
#include "utlist.h"
#define PCM_BUF_MAX_SIZE_FRAMES (4096 * 4)
#define PCM_BUF_MAX_SIZE_BYTES (PCM_BUF_MAX_SIZE_FRAMES * 4)
-/* Threshold for reasonable a2dp throttle log in audio dump. */
-static const struct timespec throttle_log_threshold = {
- 0, 20000000 /* 20ms */
-};
-
-/* Threshold for severe a2dp throttle event. */
-static const struct timespec throttle_event_threshold = {
- 2, 0 /* 2s */
+/* no_stream target_frames in timespec. */
+static const struct timespec no_stream_target_frames_ts = {
+ 0, 10 * 1000 * 1000 /* 10 msec. */
};
/* Child of cras_iodev to handle bluetooth A2DP streaming.
@@ -48,10 +43,14 @@ static const struct timespec throttle_event_threshold = {
* sock_depth_frames - Socket depth in frames of the a2dp socket.
* pcm_buf - Buffer to hold pcm samples before encode.
* destroyed - Flag to note if this a2dp_io is about to destroy.
- * next_flush_time - The time when it is okay for next flush call.
- * flush_period - The time period between two a2dp packet writes.
- * write_block - How many frames of audio samples are transferred in one
- * a2dp packet write.
+ * bt_written_frames - Accumulated frames written to a2dp socket. Used
+ * together with the device open timestamp to estimate how many virtual
+ * buffer is queued there.
+ * dev_open_time - The last time a2dp_ios is opened.
+ * drain_complete - Flag to indicate if valid frames have all been drained
+ * in no stream state.
+ * filled_zeros_bytes - Number of zero data in bytes that have been filled
+ * in no stream state.
*/
struct a2dp_io {
struct cras_iodev base;
@@ -60,12 +59,13 @@ struct a2dp_io {
unsigned sock_depth_frames;
struct byte_buffer *pcm_buf;
int destroyed;
- struct timespec next_flush_time;
- struct timespec flush_period;
- unsigned int write_block;
+ uint64_t bt_written_frames;
+ struct timespec dev_open_time;
+ bool drain_complete;
+ int filled_zeros_bytes;
};
-static int encode_and_flush(const struct cras_iodev *iodev);
+static int flush_data(void *arg);
static int update_supported_formats(struct cras_iodev *iodev)
{
@@ -76,6 +76,7 @@ static int update_supported_formats(struct cras_iodev *iodev)
cras_bt_transport_configuration(a2dpio->transport, &a2dp, sizeof(a2dp));
+ iodev->format->format = SND_PCM_FORMAT_S16_LE;
channel = (a2dp.channel_mode == SBC_CHANNEL_MODE_MONO) ? 1 : 2;
if (a2dp.frequency & SBC_SAMPLING_FREQ_48000)
@@ -101,167 +102,97 @@ static int update_supported_formats(struct cras_iodev *iodev)
iodev->supported_formats =
(snd_pcm_format_t *)malloc(2 * sizeof(snd_pcm_format_t));
iodev->supported_formats[0] = SND_PCM_FORMAT_S16_LE;
- iodev->supported_formats[1] = (snd_pcm_format_t)0;
+ iodev->supported_formats[1] = 0;
return 0;
}
-static unsigned int bt_local_queued_frames(const struct cras_iodev *iodev)
+/* Calculates the number of virtual buffer in frames. Assuming all written
+ * buffer is consumed in a constant frame rate at bluetooth device side.
+ * Args:
+ * iodev: The a2dp iodev to estimate the queued frames for.
+ * fr: The amount of frames just transmitted.
+ */
+static int bt_queued_frames(const struct cras_iodev *iodev, int fr)
{
+ uint64_t consumed;
struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
- return a2dp_queued_frames(&a2dpio->a2dp) +
- buf_queued(a2dpio->pcm_buf) /
- cras_get_format_bytes(iodev->format);
+
+ /* Calculate consumed frames since device has opened */
+ a2dpio->bt_written_frames += fr;
+ consumed = cras_frames_since_time(&a2dpio->dev_open_time,
+ iodev->format->frame_rate);
+
+ if (a2dpio->bt_written_frames > consumed)
+ return a2dpio->bt_written_frames - consumed;
+ else
+ return 0;
}
static int frames_queued(const struct cras_iodev *iodev,
struct timespec *tstamp)
{
- int local_queued_frames = bt_local_queued_frames(iodev);
+ struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
+ int estimate_queued_frames = bt_queued_frames(iodev, 0);
+ int local_queued_frames = a2dp_queued_frames(&a2dpio->a2dp) +
+ buf_queued(a2dpio->pcm_buf) /
+ cras_get_format_bytes(iodev->format);
clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
- return MIN(iodev->buffer_size, local_queued_frames);
+ return MIN(iodev->buffer_size,
+ MAX(estimate_queued_frames, local_queued_frames));
}
-/*
- * Utility function to fill zero frames until buffer level reaches
- * target_level. This is useful to allocate just enough data to write
- * to controller, while not introducing extra latency.
- */
-static int fill_zeros_to_target_level(struct cras_iodev *iodev,
- unsigned int target_level)
+static int no_stream(struct cras_iodev *iodev, int enable)
{
- unsigned int local_queued_frames = bt_local_queued_frames(iodev);
+ struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
+ unsigned int buf_avail;
+ unsigned int format_bytes;
+ unsigned int target_bytes;
+ unsigned int target_total_bytes;
+ unsigned int bt_queued_bytes;
+ uint8_t *buf;
+ struct timespec tstamp;
+ int i;
- if (local_queued_frames < target_level)
- return cras_iodev_fill_odev_zeros(
- iodev, target_level - local_queued_frames);
- return 0;
-}
+ format_bytes = cras_get_format_bytes(iodev->format);
-/*
- * dev_io_playback_write() has the logic to detect underrun scenario
- * and calls into this underrun ops, by comparing buffer level with
- * number of frames just written. Note that it's not correct 100% of
- * the time in a2dp case, because we lose track of samples once they're
- * flushed to socket.
- */
-static int output_underrun(struct cras_iodev *iodev)
-{
- unsigned int local_queued_frames = bt_local_queued_frames(iodev);
-
- /*
- * Examples to help understand the check:
- *
- * [False-positive underrun]
- * Assume min_buffer_level = 1000, written 900, and flushes
- * 800 of data. Audio thread sees 1000 + 900 - 800 = 1100 of
- * data left. This is merely 100(< 900) above min_buffer_level
- * so audio_thread thinks it underruns, but actually not.
- *
- * [True underrun]
- * min_buffer_level = 1000, written 200, and flushes 800 of
- * data. Now that buffer runs lower than min_buffer_level so
- * it's indeed an underrun.
- */
- if (local_queued_frames > iodev->min_buffer_level)
+ if (enable) {
+ /* Target to have let hw_level = 2 * (frames in 10ms) */
+ bt_queued_bytes =
+ cras_iodev_frames_queued(iodev, &tstamp) * format_bytes;
+ target_total_bytes =
+ 2 *
+ cras_time_to_frames(&no_stream_target_frames_ts,
+ iodev->format->frame_rate) *
+ format_bytes;
+ if (target_total_bytes <= bt_queued_bytes)
+ return 0;
+ target_total_bytes -= bt_queued_bytes;
+
+ /* Loop twice to make sure target_total_bytes are filled. */
+ for (i = 0; i < 2; i++) {
+ buf = buf_write_pointer_size(a2dpio->pcm_buf,
+ &buf_avail);
+ if (buf_avail == 0 || target_total_bytes == 0)
+ break;
+ target_bytes = MIN(buf_avail, target_total_bytes);
+ memset(buf, 0, target_bytes);
+ buf_increment_write(a2dpio->pcm_buf, target_bytes);
+ bt_queued_frames(iodev, target_bytes / format_bytes);
+ target_total_bytes -= target_bytes;
+ }
+ flush_data(iodev);
return 0;
-
- return cras_iodev_fill_odev_zeros(iodev, iodev->min_cb_level);
-}
-
-/*
- * This will be called multiple times when a2dpio is in no_stream state
- * frames_to_play_in_sleep ops determins how regular this will be called.
- */
-static int enter_no_stream(struct a2dp_io *a2dpio)
-{
- struct cras_iodev *odev = &a2dpio->base;
- int rc;
- /*
- * Setting target level to 3 times of min_buffer_level.
- * We want hw_level to stay bewteen 1-2 times of min_buffer_level on
- * top of the underrun threshold(i.e one min_cb_level).
- */
- rc = fill_zeros_to_target_level(odev, 3 * odev->min_buffer_level);
- if (rc)
- syslog(LOG_ERR, "Error in A2DP enter_no_stream");
- return encode_and_flush(odev);
-}
-
-/*
- * This is called when stream data is available to write. Prepare audio
- * data to one min_buffer_level. Don't flush it now because stream data is
- * coming right up which will trigger next flush at appropriate time.
- */
-static int leave_no_stream(struct a2dp_io *a2dpio)
-{
- struct cras_iodev *odev = &a2dpio->base;
-
- /*
- * Since stream data is ready, just make sure hw_level doesn't underrun
- * after one flush. Hence setting the target level to 2 times of
- * min_buffer_level.
- */
- return fill_zeros_to_target_level(odev, 2 * odev->min_buffer_level);
-}
-
-/*
- * Makes sure there's enough data(zero frames) to flush when no stream presents.
- * Note that the underrun condition is when real buffer level goes below
- * min_buffer_level, so we want to keep data at a reasonable higher level on top
- * of that.
- */
-static int no_stream(struct cras_iodev *odev, int enable)
-{
- struct a2dp_io *a2dpio = (struct a2dp_io *)odev;
-
- if (enable)
- return enter_no_stream(a2dpio);
- else
- return leave_no_stream(a2dpio);
-}
-
-/* Encode as much PCM data as we can until the buffer level of a2dp_info
- * reaches MTU.
- * Returns:
- * 0 for success, otherwise negative error code.
- */
-static int encode_a2dp_packet(struct a2dp_io *a2dpio)
-{
- int processed;
- size_t format_bytes = cras_get_format_bytes(a2dpio->base.format);
-
- while (buf_queued(a2dpio->pcm_buf)) {
- processed = a2dp_encode(
- &a2dpio->a2dp, buf_read_pointer(a2dpio->pcm_buf),
- buf_readable(a2dpio->pcm_buf), format_bytes,
- cras_bt_transport_write_mtu(a2dpio->transport));
- if (processed == -ENOSPC || processed == 0)
- break;
- if (processed < 0)
- return processed;
-
- buf_increment_read(a2dpio->pcm_buf, processed);
}
return 0;
}
-/*
- * To be called when a2dp socket becomes writable.
- */
-static int a2dp_socket_write_cb(void *arg, int revent)
-{
- struct cras_iodev *iodev = (struct cras_iodev *)arg;
- return encode_and_flush(iodev);
-}
-
static int configure_dev(struct cras_iodev *iodev)
{
struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
int sock_depth;
int err;
socklen_t optlen;
- int a2dp_payload_length;
err = cras_bt_transport_acquire(a2dpio->transport);
if (err < 0) {
@@ -284,60 +215,34 @@ static int configure_dev(struct cras_iodev *iodev)
if (!a2dpio->pcm_buf)
return -ENOMEM;
+ iodev->buffer_size = PCM_BUF_MAX_SIZE_FRAMES;
+
/* Set up the socket to hold two MTUs full of data before returning
* EAGAIN. This will allow the write to be throttled when a reasonable
* amount of data is queued. */
sock_depth = 2 * cras_bt_transport_write_mtu(a2dpio->transport);
setsockopt(cras_bt_transport_fd(a2dpio->transport), SOL_SOCKET,
SO_SNDBUF, &sock_depth, sizeof(sock_depth));
+
optlen = sizeof(sock_depth);
getsockopt(cras_bt_transport_fd(a2dpio->transport), SOL_SOCKET,
SO_SNDBUF, &sock_depth, &optlen);
a2dpio->sock_depth_frames = a2dp_block_size(&a2dpio->a2dp, sock_depth) /
cras_get_format_bytes(iodev->format);
- /*
- * Per avdtp_write, subtract the room for packet header first.
- * Calculate how many frames are encapsulated in one a2dp packet, and
- * the corresponding time period between two packets.
- */
- a2dp_payload_length = cras_bt_transport_write_mtu(a2dpio->transport) -
- sizeof(struct rtp_header) -
- sizeof(struct rtp_payload);
- a2dpio->write_block =
- a2dp_block_size(&a2dpio->a2dp, a2dp_payload_length) /
- cras_get_format_bytes(iodev->format);
- cras_frames_to_time(a2dpio->write_block, iodev->format->frame_rate,
- &a2dpio->flush_period);
-
- /* PCM buffer size plus one encoded a2dp packet. */
- iodev->buffer_size = PCM_BUF_MAX_SIZE_FRAMES + a2dpio->write_block;
-
- /*
- * Buffer level less than one write_block can't be send over a2dp
- * packet. Configure min_buffer_level to this value so when stream
- * underruns, audio thread can take action to fill some zeros.
- */
- iodev->min_buffer_level = a2dpio->write_block;
- audio_thread_add_events_callback(
- cras_bt_transport_fd(a2dpio->transport), a2dp_socket_write_cb,
- iodev, POLLOUT | POLLERR | POLLHUP);
- audio_thread_config_events_callback(
- cras_bt_transport_fd(a2dpio->transport), TRIGGER_NONE);
- return 0;
-}
+ iodev->min_buffer_level = a2dpio->sock_depth_frames;
-static int start(const struct cras_iodev *iodev)
-{
- struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
+ a2dpio->drain_complete = 0;
+ a2dpio->filled_zeros_bytes = 0;
- /*
- * This is called when iodev in open state, at the moment when
- * output sample is ready. Initialize the next_flush_time for
- * following flush calls.
- */
- clock_gettime(CLOCK_MONOTONIC_RAW, &a2dpio->next_flush_time);
+ /* Initialize variables for bt_queued_frames() */
+ a2dpio->bt_written_frames = 0;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &a2dpio->dev_open_time);
+ audio_thread_add_write_callback(cras_bt_transport_fd(a2dpio->transport),
+ flush_data, iodev);
+ audio_thread_enable_callback(cras_bt_transport_fd(a2dpio->transport),
+ 0);
return 0;
}
@@ -362,53 +267,26 @@ static int close_dev(struct cras_iodev *iodev)
device = cras_bt_transport_device(a2dpio->transport);
if (device)
cras_bt_device_cancel_suspend(device);
- a2dp_reset(&a2dpio->a2dp);
+ a2dp_drain(&a2dpio->a2dp);
byte_buffer_destroy(&a2dpio->pcm_buf);
cras_iodev_free_format(iodev);
cras_iodev_free_audio_area(iodev);
return 0;
}
-static unsigned int frames_to_play_in_sleep(struct cras_iodev *iodev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp)
-{
- struct a2dp_io *a2dpio = (struct a2dp_io *)iodev;
- int frames_until;
-
- *hw_level = frames_queued(iodev, hw_tstamp);
- if (*hw_level < a2dpio->write_block)
- *hw_level = 0;
- else
- *hw_level -= a2dpio->write_block;
-
- frames_until = cras_frames_until_time(&a2dpio->next_flush_time,
- iodev->format->frame_rate);
- if (frames_until > 0)
- return frames_until;
-
- /* If time has passed next_flush_time, for example when socket write
- * throttles, sleep a moderate of time so that audio thread doesn't
- * busy wake up. */
- return a2dpio->write_block;
-}
-
-/* Encodes PCM data to a2dp frames and try to flush it to the socket.
+/* Flushes queued buffer, including pcm and a2dp buffer.
* Returns:
* 0 when the flush succeeded, -1 when error occurred.
*/
-static int encode_and_flush(const struct cras_iodev *iodev)
+static int flush_data(void *arg)
{
- int err;
+ struct cras_iodev *iodev = (struct cras_iodev *)arg;
+ int processed;
size_t format_bytes;
int written = 0;
- unsigned int queued_frames;
+ int queued_frames;
struct a2dp_io *a2dpio;
struct cras_bt_device *device;
- struct timespec now, ts;
- static const struct timespec flush_wake_fuzz_ts = {
- 0, 1000000 /* 1ms */
- };
a2dpio = (struct a2dp_io *)iodev;
format_bytes = cras_get_format_bytes(iodev->format);
@@ -419,51 +297,23 @@ static int encode_and_flush(const struct cras_iodev *iodev)
if (device == NULL)
return -EINVAL;
- ATLOG(atlog, AUDIO_THREAD_A2DP_FLUSH, iodev->state,
- a2dpio->next_flush_time.tv_sec, a2dpio->next_flush_time.tv_nsec);
-
- /* Only allow data to be flushed after start() ops is called. */
- if ((iodev->state != CRAS_IODEV_STATE_NORMAL_RUN) &&
- (iodev->state != CRAS_IODEV_STATE_NO_STREAM_RUN))
- return 0;
-
- err = encode_a2dp_packet(a2dpio);
- if (err < 0)
- return err;
+encode_more:
+ while (buf_queued(a2dpio->pcm_buf)) {
+ processed = a2dp_encode(
+ &a2dpio->a2dp, buf_read_pointer(a2dpio->pcm_buf),
+ buf_readable(a2dpio->pcm_buf), format_bytes,
+ cras_bt_transport_write_mtu(a2dpio->transport));
+ ATLOG(atlog, AUDIO_THREAD_A2DP_ENCODE, processed,
+ buf_queued(a2dpio->pcm_buf),
+ buf_readable(a2dpio->pcm_buf));
+ if (processed == -ENOSPC || processed == 0)
+ break;
+ if (processed < 0)
+ return 0;
-do_flush:
- /* If flush gets called before targeted next flush time, do nothing. */
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- add_timespecs(&now, &flush_wake_fuzz_ts);
- if (!timespec_after(&now, &a2dpio->next_flush_time)) {
- if (iodev->buffer_size == bt_local_queued_frames(iodev)) {
- /*
- * If buffer is full, audio thread will no longer call
- * into get/put buffer in subsequent wake-ups. In that
- * case set the registered callback to be triggered at
- * next audio thread wake up.
- */
- audio_thread_config_events_callback(
- cras_bt_transport_fd(a2dpio->transport),
- TRIGGER_WAKEUP);
- cras_audio_thread_event_a2dp_overrun();
- syslog(LOG_WARNING, "Buffer overrun in A2DP iodev");
- }
- return 0;
+ buf_increment_read(a2dpio->pcm_buf, processed);
}
- /* If the A2DP write schedule miss exceeds a small threshold, log it for
- * debug purpose. */
- subtract_timespecs(&now, &a2dpio->next_flush_time, &ts);
- if (timespec_after(&ts, &throttle_log_threshold))
- ATLOG(atlog, AUDIO_THREAD_A2DP_THROTTLE_TIME, ts.tv_sec,
- ts.tv_nsec, bt_local_queued_frames(iodev));
-
- /* Log an event if the A2DP write schedule miss exceeds a large threshold
- * that we consider it as something severe. */
- if (timespec_after(&ts, &throttle_event_threshold))
- cras_audio_thread_event_a2dp_throttle();
-
written = a2dp_write(&a2dpio->a2dp,
cras_bt_transport_fd(a2dpio->transport),
cras_bt_transport_write_mtu(a2dpio->transport));
@@ -472,32 +322,18 @@ do_flush:
if (written == -EAGAIN) {
/* If EAGAIN error lasts longer than 5 seconds, suspend the
* a2dp connection. */
- cras_bt_device_schedule_suspend(device, 5000,
- A2DP_LONG_TX_FAILURE);
- audio_thread_config_events_callback(
- cras_bt_transport_fd(a2dpio->transport), TRIGGER_POLL);
+ cras_bt_device_schedule_suspend(device, 5000);
+ audio_thread_enable_callback(
+ cras_bt_transport_fd(a2dpio->transport), 1);
return 0;
} else if (written < 0) {
/* Suspend a2dp immediately when receives error other than
* EAGAIN. */
cras_bt_device_cancel_suspend(device);
- cras_bt_device_schedule_suspend(device, 0, A2DP_TX_FATAL_ERROR);
- /* Stop polling the socket in audio thread. Main thread will
- * close this iodev soon. */
- audio_thread_config_events_callback(
- cras_bt_transport_fd(a2dpio->transport), TRIGGER_NONE);
+ cras_bt_device_schedule_suspend(device, 0);
return written;
}
- /* Update the next flush time if one block successfully been written. */
- if (written)
- add_timespecs(&a2dpio->next_flush_time, &a2dpio->flush_period);
-
- /* a2dp_write no longer return -EAGAIN when reaches here, disable
- * the polling write callback. */
- audio_thread_config_events_callback(
- cras_bt_transport_fd(a2dpio->transport), TRIGGER_NONE);
-
/* Data succcessfully written to a2dp socket, cancel any scheduled
* suspend timer. */
cras_bt_device_cancel_suspend(device);
@@ -507,13 +343,12 @@ do_flush:
* to min_buffer_level so that another A2DP write could causes underrun.
*/
queued_frames = buf_queued(a2dpio->pcm_buf) / format_bytes;
- if (written &&
- (iodev->min_buffer_level + a2dpio->write_block < queued_frames)) {
- err = encode_a2dp_packet(a2dpio);
- if (err < 0)
- return err;
- goto do_flush;
- }
+ if (written && (iodev->min_buffer_level + written < queued_frames))
+ goto encode_more;
+
+ /* everything written. */
+ audio_thread_enable_callback(cras_bt_transport_fd(a2dpio->transport),
+ 0);
return 0;
}
@@ -562,7 +397,13 @@ static int put_buffer(struct cras_iodev *iodev, unsigned nwritten)
buf_increment_write(a2dpio->pcm_buf, written_bytes);
- return encode_and_flush(iodev);
+ /* Set dev open time at when the first data arrives. */
+ if (nwritten && !a2dpio->bt_written_frames)
+ clock_gettime(CLOCK_MONOTONIC_RAW, &a2dpio->dev_open_time);
+
+ bt_queued_frames(iodev, nwritten);
+
+ return flush_data(iodev);
}
static int flush_buffer(struct cras_iodev *iodev)
@@ -643,7 +484,10 @@ struct cras_iodev *a2dp_iodev_create(struct cras_bt_transport *transport)
snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = '\0';
- iodev->info.stable_id = cras_bt_device_get_stable_id(device);
+ iodev->info.stable_id =
+ SuperFastHash(cras_bt_device_object_path(device),
+ strlen(cras_bt_device_object_path(device)),
+ strlen(cras_bt_device_object_path(device)));
iodev->configure_dev = configure_dev;
iodev->frames_queued = frames_queued;
@@ -652,15 +496,12 @@ struct cras_iodev *a2dp_iodev_create(struct cras_bt_transport *transport)
iodev->put_buffer = put_buffer;
iodev->flush_buffer = flush_buffer;
iodev->no_stream = no_stream;
- iodev->output_underrun = output_underrun;
iodev->close_dev = close_dev;
iodev->update_supported_formats = update_supported_formats;
iodev->update_active_node = update_active_node;
iodev->set_volume = set_volume;
- iodev->start = start;
- iodev->frames_to_play_in_sleep = frames_to_play_in_sleep;
- /* Create an empty ionode */
+ /* Create a dummy ionode */
node = (struct cras_ionode *)calloc(1, sizeof(*node));
node->dev = iodev;
strcpy(node->name, iodev->info.name);
@@ -669,18 +510,11 @@ struct cras_iodev *a2dp_iodev_create(struct cras_bt_transport *transport)
node->volume = 100;
gettimeofday(&node->plugged_time, NULL);
- /* Prepare active node before append, so bt_io can extract correct
- * info from A2DP iodev and node. */
- cras_iodev_add_node(iodev, node);
- cras_iodev_set_active_node(iodev, node);
+ /* A2DP does output only */
cras_bt_device_append_iodev(
device, iodev, cras_bt_transport_profile(a2dpio->transport));
-
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels =
- (a2dp.channel_mode == SBC_CHANNEL_MODE_MONO) ? 1 : 2;
-
- ewma_power_disable(&iodev->ewma);
+ cras_iodev_add_node(iodev, node);
+ cras_iodev_set_active_node(iodev, node);
return iodev;
error:
diff --git a/cras/src/server/cras_alsa_card.c b/cras/src/server/cras_alsa_card.c
index 362e6a68..709cc1d5 100644
--- a/cras/src/server/cras_alsa_card.c
+++ b/cras/src/server/cras_alsa_card.c
@@ -14,7 +14,7 @@
#include "cras_alsa_io.h"
#include "cras_alsa_mixer.h"
#include "cras_alsa_ucm.h"
-#include "cras_device_blocklist.h"
+#include "cras_device_blacklist.h"
#include "cras_card_config.h"
#include "cras_config.h"
#include "cras_iodev.h"
@@ -25,8 +25,8 @@
#include "utlist.h"
#define MAX_ALSA_CARDS 32 /* Alsa limit on number of cards. */
-#define MAX_ALSA_CARD_NAME_LENGTH 6 /* Alsa card name "hw:XX" + 1 for null. */
-#define MAX_ALSA_PCM_NAME_LENGTH 9 /* Alsa pcm name "hw:XX,YY" + 1 for null. */
+#define MAX_ALSA_PCM_NAME_LENGTH 6 /* Alsa names "hw:XX" + 1 for null. */
+#define MAX_INI_NAME_LENGTH 63 /* 63 chars + 1 for null where declared. */
#define MAX_COUPLED_OUTPUT_SIZE 4
struct iodev_list_node {
@@ -43,7 +43,7 @@ struct hctl_poll_fd {
};
/* Holds information about each sound card on the system.
- * name - of the form hw:XX.
+ * name - of the form hw:XX,YY.
* card_index - 0 based index, value of "XX" in the name.
* iodevs - Input and output devices for this card.
* mixer - Controls the mixer controls for this card.
@@ -53,7 +53,7 @@ struct hctl_poll_fd {
* config - Config info for this card, can be NULL if none found.
*/
struct cras_alsa_card {
- char name[MAX_ALSA_CARD_NAME_LENGTH];
+ char name[MAX_ALSA_PCM_NAME_LENGTH];
size_t card_index;
struct iodev_list_node *iodevs;
struct cras_alsa_mixer *mixer;
@@ -84,7 +84,6 @@ struct cras_iodev *create_iodev_for_device(
struct iodev_list_node *new_dev;
struct iodev_list_node *node;
int first = 1;
- char pcm_name[MAX_ALSA_PCM_NAME_LENGTH];
/* Find whether this is the first device in this direction, and
* avoid duplicate device indexes. */
@@ -104,28 +103,22 @@ struct cras_iodev *create_iodev_for_device(
if (new_dev == NULL)
return NULL;
- /* Append device index to card namem, ex: 'hw:0', for the PCM name of
- * target iodev. */
- snprintf(pcm_name, MAX_ALSA_PCM_NAME_LENGTH, "%s,%u", alsa_card->name,
- device_index);
-
new_dev->direction = direction;
- new_dev->iodev =
- alsa_iodev_create(info->card_index, card_name, device_index,
- pcm_name, dev_name, dev_id, info->card_type,
- first, alsa_card->mixer, alsa_card->config,
- alsa_card->ucm, alsa_card->hctl, direction,
- info->usb_vendor_id, info->usb_product_id,
- info->usb_serial_number);
+ new_dev->iodev = alsa_iodev_create(
+ info->card_index, card_name, device_index, dev_name, dev_id,
+ info->card_type, first, alsa_card->mixer, alsa_card->config,
+ alsa_card->ucm, alsa_card->hctl, direction, info->usb_vendor_id,
+ info->usb_product_id, info->usb_serial_number);
if (new_dev->iodev == NULL) {
- syslog(LOG_ERR, "Couldn't create alsa_iodev for %s", pcm_name);
+ syslog(LOG_ERR, "Couldn't create alsa_iodev for %u:%u\n",
+ info->card_index, device_index);
free(new_dev);
return NULL;
}
- syslog(LOG_DEBUG, "New %s device %s",
+ syslog(LOG_DEBUG, "New %s device %u:%d",
direction == CRAS_STREAM_OUTPUT ? "playback" : "capture",
- pcm_name);
+ info->card_index, device_index);
DL_APPEND(alsa_card->iodevs, new_dev);
return new_dev->iodev;
@@ -146,15 +139,15 @@ static int card_has_hctl_jack(struct cras_alsa_card *alsa_card)
}
/* Check if a device should be ignored for this card. Returns non-zero if the
- * device is in the blocklist and should be ignored.
+ * device is in the blacklist and should be ignored.
*/
static int should_ignore_dev(struct cras_alsa_card_info *info,
- struct cras_device_blocklist *blocklist,
+ struct cras_device_blacklist *blacklist,
size_t device_index)
{
if (info->card_type == ALSA_CARD_TYPE_USB)
- return cras_device_blocklist_check(
- blocklist, info->usb_vendor_id, info->usb_product_id,
+ return cras_device_blacklist_check(
+ blacklist, info->usb_vendor_id, info->usb_product_id,
info->usb_desc_checksum, device_index);
return 0;
}
@@ -178,7 +171,7 @@ static struct mixer_name *filter_controls(struct cras_use_case_mgr *ucm,
/* Handles notifications from alsa controls. Called by main thread when a poll
* fd provided by alsa signals there is an event available. */
-static void alsa_control_event_pending(void *arg, int revent)
+static void alsa_control_event_pending(void *arg)
{
struct cras_alsa_card *card;
@@ -195,7 +188,7 @@ static void alsa_control_event_pending(void *arg, int revent)
static int
add_controls_and_iodevs_by_matching(struct cras_alsa_card_info *info,
- struct cras_device_blocklist *blocklist,
+ struct cras_device_blacklist *blacklist,
struct cras_alsa_card *alsa_card,
const char *card_name, snd_ctl_t *handle)
{
@@ -258,7 +251,7 @@ add_controls_and_iodevs_by_matching(struct cras_alsa_card_info *info,
/* Check for playback devices. */
snd_pcm_info_set_stream(dev_info, SND_PCM_STREAM_PLAYBACK);
if (snd_ctl_pcm_info(handle, dev_info) == 0 &&
- !should_ignore_dev(info, blocklist, dev_idx)) {
+ !should_ignore_dev(info, blacklist, dev_idx)) {
struct cras_iodev *iodev = create_iodev_for_device(
alsa_card, info, card_name,
snd_pcm_info_get_name(dev_info),
@@ -345,11 +338,6 @@ static int add_controls_and_iodevs_with_ucm(struct cras_alsa_card_info *info,
/* Create all of the devices. */
DL_FOREACH (ucm_sections, section) {
- /* If a UCM section specifies certain device as dependency
- * then don't create an alsa iodev for it, just append it
- * as node later. */
- if (section->dependent_dev_idx != -1)
- continue;
snd_pcm_info_set_device(dev_info, section->dev_idx);
snd_pcm_info_set_subdevice(dev_info, 0);
if (section->dir == CRAS_STREAM_OUTPUT)
@@ -377,17 +365,11 @@ static int add_controls_and_iodevs_with_ucm(struct cras_alsa_card_info *info,
section->dev_idx, section->dir);
}
- /* Setup jacks and controls for the devices. If a SectionDevice is
- * dependent on another SectionDevice, it'll be added as a node to
- * a existing ALSA iodev. */
+ /* Setup jacks and controls for the devices. */
DL_FOREACH (ucm_sections, section) {
DL_FOREACH (alsa_card->iodevs, node) {
- if (node->direction != section->dir)
- continue;
- if (alsa_iodev_index(node->iodev) == section->dev_idx)
- break;
- if (alsa_iodev_index(node->iodev) ==
- section->dependent_dev_idx)
+ if (node->direction == section->dir &&
+ alsa_iodev_index(node->iodev) == section->dev_idx)
break;
}
if (node) {
@@ -449,7 +431,7 @@ static void configure_echo_reference_dev(struct cras_alsa_card *alsa_card)
struct cras_alsa_card *cras_alsa_card_create(
struct cras_alsa_card_info *info, const char *device_config_dir,
- struct cras_device_blocklist *blocklist, const char *ucm_suffix)
+ struct cras_device_blacklist *blacklist, const char *ucm_suffix)
{
snd_ctl_t *handle = NULL;
int rc, n;
@@ -469,7 +451,7 @@ struct cras_alsa_card *cras_alsa_card_create(
return NULL;
alsa_card->card_index = info->card_index;
- snprintf(alsa_card->name, MAX_ALSA_CARD_NAME_LENGTH, "hw:%u",
+ snprintf(alsa_card->name, MAX_ALSA_PCM_NAME_LENGTH, "hw:%u",
info->card_index);
rc = snd_ctl_open(&handle, alsa_card->name, 0);
@@ -490,10 +472,6 @@ struct cras_alsa_card *cras_alsa_card_create(
goto error_bail;
}
- if (info->card_type != ALSA_CARD_TYPE_INTERNAL ||
- cras_system_check_ignore_ucm_suffix(card_name))
- ucm_suffix = NULL;
-
/* Read config file for this card if it exists. */
alsa_card->config =
cras_card_config_create(device_config_dir, card_name);
@@ -517,9 +495,6 @@ struct cras_alsa_card *cras_alsa_card_create(
card_name, alsa_card->ucm ? "yes" : "no");
}
- if (info->card_type == ALSA_CARD_TYPE_INTERNAL && !alsa_card->ucm)
- syslog(LOG_ERR, "No ucm config on internal card %s", card_name);
-
rc = snd_hctl_open(&alsa_card->hctl, alsa_card->name, SND_CTL_NONBLOCK);
if (rc < 0) {
syslog(LOG_DEBUG, "failed to get hctl for %s", alsa_card->name);
@@ -553,7 +528,7 @@ struct cras_alsa_card *cras_alsa_card_create(
card_name, handle);
else
rc = add_controls_and_iodevs_by_matching(
- info, blocklist, alsa_card, card_name, handle);
+ info, blacklist, alsa_card, card_name, handle);
if (rc)
goto error_bail;
@@ -584,7 +559,7 @@ struct cras_alsa_card *cras_alsa_card_create(
DL_APPEND(alsa_card->hctl_poll_fds, registered_fd);
rc = cras_system_add_select_fd(
registered_fd->fd, alsa_control_event_pending,
- alsa_card, POLLIN);
+ alsa_card);
if (rc < 0) {
DL_DELETE(alsa_card->hctl_poll_fds,
registered_fd);
diff --git a/cras/src/server/cras_alsa_card.h b/cras/src/server/cras_alsa_card.h
index a63bf90a..749a17fb 100644
--- a/cras/src/server/cras_alsa_card.h
+++ b/cras/src/server/cras_alsa_card.h
@@ -15,7 +15,7 @@
*/
struct cras_alsa_card;
-struct cras_device_blocklist;
+struct cras_device_blacklist;
/* Creates a cras_alsa_card instance for the given alsa device. Enumerates the
* devices for the card and adds them to the system as possible playback or
@@ -24,7 +24,7 @@ struct cras_device_blocklist;
* card_info - Contains the card index, type, and priority.
* device_config_dir - The directory of device configs which contains the
* volume curves.
- * blocklist - List of devices that should be ignored.
+ * blacklist - List of devices that should be ignored.
* ucm_suffix - The ucm config name is formed as <card-name>.<suffix>
* Returns:
* A pointer to the newly created cras_alsa_card which must later be freed
@@ -32,7 +32,7 @@ struct cras_device_blocklist;
*/
struct cras_alsa_card *cras_alsa_card_create(
struct cras_alsa_card_info *info, const char *device_config_dir,
- struct cras_device_blocklist *blocklist, const char *ucm_suffix);
+ struct cras_device_blacklist *blacklist, const char *ucm_suffix);
/* Destroys a cras_alsa_card that was returned from cras_alsa_card_create.
* Args:
diff --git a/cras/src/server/cras_alsa_helpers.c b/cras/src/server/cras_alsa_helpers.c
index 6cdc165a..b0729fd0 100644
--- a/cras/src/server/cras_alsa_helpers.c
+++ b/cras/src/server/cras_alsa_helpers.c
@@ -25,9 +25,6 @@
/* Time difference between two consecutive underrun logs. */
#define UNDERRUN_LOG_TIME_SECS 30
-/* Limit the number of channels supported for devices: b/158509536 */
-#define TEMP_CHANNEL_LIMIT 20
-
/* Chances to give mmap_begin to work. */
static const size_t MAX_MMAP_BEGIN_ATTEMPTS = 3;
/* Time to sleep between resume attempts. */
@@ -413,19 +410,8 @@ int cras_alsa_fill_properties(snd_pcm_t *handle, size_t **rates,
}
(*channel_counts)[num_found] = 0;
if (num_found == 0) {
- // Pull the max channel count and use that.
- unsigned int max_channels = 0;
- rc = snd_pcm_hw_params_get_channels_max(params, &max_channels);
- if (rc < 0) {
- syslog(LOG_WARNING, "No valid channel counts found.");
- return -EINVAL;
- } else if (max_channels > TEMP_CHANNEL_LIMIT) {
- syslog(LOG_WARNING, "Can't support so many channels.");
- return -EINVAL;
- } else {
- (*channel_counts)[0] = (size_t)max_channels;
- (*channel_counts)[1] = 0;
- }
+ syslog(LOG_WARNING, "No valid channel counts found.");
+ return -EINVAL;
}
num_found = 0;
@@ -556,7 +542,7 @@ int cras_alsa_set_hwparams(snd_pcm_t *handle, struct cras_audio_format *format,
return 0;
}
-int cras_alsa_set_swparams(snd_pcm_t *handle)
+int cras_alsa_set_swparams(snd_pcm_t *handle, int *enable_htimestamp)
{
int err;
snd_pcm_sw_params_t *swparams;
@@ -593,7 +579,50 @@ int cras_alsa_set_swparams(snd_pcm_t *handle)
return err;
}
+ if (*enable_htimestamp) {
+ /* Use MONOTONIC_RAW time-stamps. */
+ err = snd_pcm_sw_params_set_tstamp_type(
+ handle, swparams, SND_PCM_TSTAMP_TYPE_MONOTONIC_RAW);
+ if (err < 0) {
+ syslog(LOG_ERR, "set_tstamp_type: %s\n",
+ snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_sw_params_set_tstamp_mode(handle, swparams,
+ SND_PCM_TSTAMP_ENABLE);
+ if (err < 0) {
+ syslog(LOG_ERR, "set_tstamp_mode: %s\n",
+ snd_strerror(err));
+ return err;
+ }
+ }
+
+ /* This hack is required because ALSA-LIB does not provide any way to
+ * detect whether MONOTONIC_RAW timestamps are supported by the kernel.
+ * In ALSA-LIB, the code checks the hardware protocol version. */
err = snd_pcm_sw_params(handle, swparams);
+ if (err == -EINVAL && *enable_htimestamp) {
+ *enable_htimestamp = 0;
+ syslog(LOG_WARNING,
+ "MONOTONIC_RAW timestamps are not supported.");
+
+ err = snd_pcm_sw_params_set_tstamp_type(
+ handle, swparams, SND_PCM_TSTAMP_TYPE_GETTIMEOFDAY);
+ if (err < 0) {
+ syslog(LOG_ERR, "set_tstamp_type: %s\n",
+ snd_strerror(err));
+ return err;
+ }
+ err = snd_pcm_sw_params_set_tstamp_mode(handle, swparams,
+ SND_PCM_TSTAMP_NONE);
+ if (err < 0) {
+ syslog(LOG_ERR, "set_tstamp_mode: %s\n",
+ snd_strerror(err));
+ return err;
+ }
+
+ err = snd_pcm_sw_params(handle, swparams);
+ }
if (err < 0) {
syslog(LOG_ERR, "sw_params: %s\n", snd_strerror(err));
diff --git a/cras/src/server/cras_alsa_helpers.h b/cras/src/server/cras_alsa_helpers.h
index 01a42aea..38976749 100644
--- a/cras/src/server/cras_alsa_helpers.h
+++ b/cras/src/server/cras_alsa_helpers.h
@@ -135,10 +135,13 @@ int cras_alsa_set_hwparams(snd_pcm_t *handle, struct cras_audio_format *format,
/* Sets up the swparams to alsa.
* Args:
* handle - The open PCM to configure.
+ * enable_htimestamp - If non-zero, enable and configure hardware timestamps,
+ * updated to reflect whether MONOTONIC RAW htimestamps
+ * are supported by the kernel implementation.
* Returns:
* 0 on success, negative error on failure.
*/
-int cras_alsa_set_swparams(snd_pcm_t *handle);
+int cras_alsa_set_swparams(snd_pcm_t *handle, int *enable_htimestamp);
/* Get the number of used frames in the alsa buffer.
*
diff --git a/cras/src/server/cras_alsa_io.c b/cras/src/server/cras_alsa_io.c
index 275a6810..4aec9d68 100644
--- a/cras/src/server/cras_alsa_io.c
+++ b/cras/src/server/cras_alsa_io.c
@@ -38,6 +38,7 @@
#include "softvol_curve.h"
#include "utlist.h"
+#define MAX_ALSA_DEV_NAME_LENGTH 9 /* Alsa names "hw:XX,YY" + 1 for null. */
#define HOTWORD_DEV "Wake on Voice"
#define DEFAULT "(default)"
#define HDMI "HDMI"
@@ -47,8 +48,6 @@
#define HEADPHONE "Headphone"
#define MIC "Mic"
#define USB "USB"
-#define LOOPBACK_CAPTURE "Loopback Capture"
-#define LOOPBACK_PLAYBACK "Loopback Playback"
/*
* For USB, pad the output buffer. This avoids a situation where there isn't a
@@ -80,14 +79,12 @@ static const struct timespec no_stream_fill_zeros_duration = {
* This extends cras_ionode to include alsa-specific information.
* Members:
* mixer_output - From cras_alsa_mixer.
- * pcm_name - PCM name for snd_pcm_open.
* volume_curve - Volume curve for this node.
* jack - The jack associated with the node.
*/
struct alsa_output_node {
struct cras_ionode base;
struct mixer_control *mixer_output;
- const char *pcm_name;
struct cras_volume_curve *volume_curve;
const struct cras_alsa_jack *jack;
};
@@ -95,7 +92,6 @@ struct alsa_output_node {
struct alsa_input_node {
struct cras_ionode base;
struct mixer_control *mixer_input;
- const char *pcm_name;
const struct cras_alsa_jack *jack;
int8_t *channel_layout;
};
@@ -103,7 +99,7 @@ struct alsa_input_node {
/*
* Child of cras_iodev, alsa_io handles ALSA interaction for sound devices.
* base - The cras_iodev structure "base class".
- * pcm_name - The PCM name passed to snd_pcm_open() (e.g. "hw:0,0").
+ * dev - String that names this device (e.g. "hw:0,0").
* dev_name - value from snd_pcm_info_get_name
* dev_id - value from snd_pcm_info_get_id
* device_index - ALSA index of device, Y in "hw:X:Y".
@@ -113,7 +109,10 @@ struct alsa_input_node {
* is_first - true if this is the first iodev on the card.
* fully_specified - true if this device and it's nodes were fully specified.
* That is, don't automatically create nodes for it.
+ * jack_always_plugged - true if this node is always plugged even without jack.
+ * enable_htimestamp - True when the device's htimestamp is used.
* handle - Handle to the opened ALSA device.
+ * num_underruns - Number of times we have run out of data (playback only).
* num_severe_underruns - Number of times we have run out of data badly.
Unlike num_underruns which records for the duration
where device is opened, num_severe_underruns records
@@ -125,6 +124,8 @@ struct alsa_input_node {
* jack_list - List of alsa jack controls for this device.
* ucm - CRAS use case manager, if configuration is found.
* mmap_offset - offset returned from mmap_begin.
+ * dsp_name_default - the default dsp name for the device. It can be overridden
+ * by the jack specific dsp name.
* poll_fd - Descriptor used to block until data is ready.
* dma_period_set_microsecs - If non-zero, the value to apply to the dma_period.
* free_running - true if device is playing zeros in the buffer without
@@ -135,11 +136,10 @@ struct alsa_input_node {
* severe_underrun_frames - The threshold for severe underrun.
* default_volume_curve - Default volume curve that converts from an index
* to dBFS.
- * has_dependent_dev - true if this iodev has dependent device.
*/
struct alsa_io {
struct cras_iodev base;
- char *pcm_name;
+ char *dev;
char *dev_name;
char *dev_id;
uint32_t device_index;
@@ -147,7 +147,10 @@ struct alsa_io {
enum CRAS_ALSA_CARD_TYPE card_type;
int is_first;
int fully_specified;
+ int jack_always_plugged;
+ int enable_htimestamp;
snd_pcm_t *handle;
+ unsigned int num_underruns;
unsigned int num_severe_underruns;
snd_pcm_stream_t alsa_stream;
struct cras_alsa_mixer *mixer;
@@ -155,6 +158,7 @@ struct alsa_io {
struct cras_alsa_jack_list *jack_list;
struct cras_use_case_mgr *ucm;
snd_pcm_uframes_t mmap_offset;
+ const char *dsp_name_default;
int poll_fd;
unsigned int dma_period_set_microsecs;
int free_running;
@@ -162,7 +166,6 @@ struct alsa_io {
snd_pcm_uframes_t severe_underrun_frames;
struct cras_volume_curve *default_volume_curve;
int hwparams_set;
- int has_dependent_dev;
};
static void init_device_settings(struct alsa_io *aio);
@@ -171,10 +174,6 @@ static int alsa_iodev_set_active_node(struct cras_iodev *iodev,
struct cras_ionode *ionode,
unsigned dev_enabled);
-static int get_fixed_rate(struct alsa_io *aio);
-
-static int update_supported_formats(struct cras_iodev *iodev);
-
/*
* Defines the default values of nodes.
*/
@@ -268,21 +267,6 @@ static const struct {
.type = CRAS_NODE_TYPE_BLUETOOTH,
.position = NODE_POSITION_EXTERNAL,
},
- {
- .name = "Echo Reference",
- .type = CRAS_NODE_TYPE_ECHO_REFERENCE,
- .position = NODE_POSITION_INTERNAL,
- },
- {
- .name = LOOPBACK_CAPTURE,
- .type = CRAS_NODE_TYPE_ALSA_LOOPBACK,
- .position = NODE_POSITION_INTERNAL,
- },
- {
- .name = LOOPBACK_PLAYBACK,
- .type = CRAS_NODE_TYPE_ALSA_LOOPBACK,
- .position = NODE_POSITION_INTERNAL,
- },
};
static int set_hwparams(struct cras_iodev *iodev)
@@ -329,7 +313,8 @@ static int frames_queued(const struct cras_iodev *iodev,
aio->num_severe_underruns++;
return rc;
}
- clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
+ if (!aio->enable_htimestamp)
+ clock_gettime(CLOCK_MONOTONIC_RAW, tstamp);
if (iodev->direction == CRAS_STREAM_INPUT)
return (int)frames;
@@ -371,7 +356,7 @@ static int close_dev(struct cras_iodev *iodev)
return 0;
}
-static int empty_hotword_cb(void *arg, int revents)
+static int dummy_hotword_cb(void *arg)
{
/* Only need this once. */
struct alsa_io *aio = (struct alsa_io *)arg;
@@ -390,42 +375,13 @@ static int open_dev(struct cras_iodev *iodev)
struct alsa_io *aio = (struct alsa_io *)iodev;
snd_pcm_t *handle;
int rc;
- const char *pcm_name = NULL;
- int enable_noise_cancellation;
- if (aio->base.direction == CRAS_STREAM_OUTPUT) {
- struct alsa_output_node *aout =
- (struct alsa_output_node *)aio->base.active_node;
- pcm_name = aout->pcm_name;
- } else {
- struct alsa_input_node *ain =
- (struct alsa_input_node *)aio->base.active_node;
- pcm_name = ain->pcm_name;
- }
-
- /* For legacy UCM path which doesn't have PlaybackPCM or CapturePCM. */
- if (pcm_name == NULL)
- pcm_name = aio->pcm_name;
-
- rc = cras_alsa_pcm_open(&handle, pcm_name, aio->alsa_stream);
+ rc = cras_alsa_pcm_open(&handle, aio->dev, aio->alsa_stream);
if (rc < 0)
return rc;
aio->handle = handle;
- /* Enable or disable noise cancellation if it supports. */
- if (aio->ucm && iodev->direction == CRAS_STREAM_INPUT &&
- ucm_node_noise_cancellation_exists(aio->ucm,
- iodev->active_node->name)) {
- enable_noise_cancellation =
- cras_system_get_noise_cancellation_enabled();
- rc = ucm_enable_node_noise_cancellation(
- aio->ucm, iodev->active_node->name,
- enable_noise_cancellation);
- if (rc < 0)
- return rc;
- }
-
return 0;
}
@@ -439,6 +395,7 @@ static int configure_dev(struct cras_iodev *iodev)
*/
if (iodev->format == NULL)
return -EINVAL;
+ aio->num_underruns = 0;
aio->free_running = 0;
aio->filled_zeros_for_draining = 0;
aio->severe_underrun_frames =
@@ -447,7 +404,7 @@ static int configure_dev(struct cras_iodev *iodev)
cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
syslog(LOG_DEBUG, "Configure alsa device %s rate %zuHz, %zu channels",
- aio->pcm_name, iodev->format->frame_rate,
+ aio->dev, iodev->format->frame_rate,
iodev->format->num_channels);
rc = set_hwparams(iodev);
@@ -460,7 +417,7 @@ static int configure_dev(struct cras_iodev *iodev)
return rc;
/* Configure software params. */
- rc = cras_alsa_set_swparams(aio->handle);
+ rc = cras_alsa_set_swparams(aio->handle, &aio->enable_htimestamp);
if (rc < 0)
return rc;
@@ -500,8 +457,8 @@ static int configure_dev(struct cras_iodev *iodev)
free(ufds);
if (aio->poll_fd >= 0)
- audio_thread_add_events_callback(
- aio->poll_fd, empty_hotword_cb, aio, POLLIN);
+ audio_thread_add_callback(aio->poll_fd,
+ dummy_hotword_cb, aio);
}
/* Capture starts right away, playback will wait for samples. */
@@ -791,7 +748,8 @@ static void set_alsa_capture_gain(struct cras_iodev *iodev)
{
const struct alsa_io *aio = (const struct alsa_io *)iodev;
struct alsa_input_node *ain;
- long min_capture_gain, max_capture_gain, gain;
+ long gain;
+
assert(aio);
if (aio->mixer == NULL)
return;
@@ -799,31 +757,20 @@ static void set_alsa_capture_gain(struct cras_iodev *iodev)
/* Only set the volume if the dev is active. */
if (!has_handle(aio))
return;
-
- ain = get_active_input(aio);
-
- cras_alsa_mixer_set_capture_mute(aio->mixer,
- cras_system_get_capture_mute(),
- ain ? ain->mixer_input : NULL);
-
- /* For USB device without UCM config, not change a gain control. */
- if (ain && ain->base.type == CRAS_NODE_TYPE_USB && !aio->ucm)
- return;
+ gain = cras_iodev_adjust_active_node_gain(
+ iodev, cras_system_get_capture_gain());
/* Set hardware gain to 0dB if software gain is needed. */
if (cras_iodev_software_volume_needed(iodev))
gain = 0;
- else {
- min_capture_gain = cras_alsa_mixer_get_minimum_capture_gain(
- aio->mixer, ain ? ain->mixer_input : NULL);
- max_capture_gain = cras_alsa_mixer_get_maximum_capture_gain(
- aio->mixer, ain ? ain->mixer_input : NULL);
- gain = MAX(iodev->active_node->capture_gain, min_capture_gain);
- gain = MIN(gain, max_capture_gain);
- }
+
+ ain = get_active_input(aio);
cras_alsa_mixer_set_capture_dBFS(aio->mixer, gain,
ain ? ain->mixer_input : NULL);
+ cras_alsa_mixer_set_capture_mute(aio->mixer,
+ cras_system_get_capture_mute(),
+ ain ? ain->mixer_input : NULL);
}
/*
@@ -851,6 +798,28 @@ static void init_device_settings(struct alsa_io *aio)
set_alsa_volume(&aio->base);
set_alsa_mute(&aio->base);
} else {
+ struct mixer_control *mixer_input = NULL;
+ struct alsa_input_node *ain = get_active_input(aio);
+ long min_capture_gain, max_capture_gain;
+
+ if (ain)
+ mixer_input = ain->mixer_input;
+
+ if (cras_iodev_software_volume_needed(&aio->base)) {
+ min_capture_gain =
+ cras_iodev_minimum_software_gain(&aio->base);
+ max_capture_gain =
+ cras_iodev_maximum_software_gain(&aio->base);
+ } else {
+ min_capture_gain =
+ cras_alsa_mixer_get_minimum_capture_gain(
+ aio->mixer, mixer_input);
+ max_capture_gain =
+ cras_alsa_mixer_get_maximum_capture_gain(
+ aio->mixer, mixer_input);
+ }
+ cras_system_set_capture_gain_limits(min_capture_gain,
+ max_capture_gain);
set_alsa_capture_gain(&aio->base);
}
}
@@ -868,7 +837,6 @@ static void free_alsa_iodev_resources(struct alsa_io *aio)
{
struct cras_ionode *node;
struct alsa_output_node *aout;
- struct alsa_input_node *ain;
free(aio->base.supported_rates);
free(aio->base.supported_channel_counts);
@@ -878,10 +846,6 @@ static void free_alsa_iodev_resources(struct alsa_io *aio)
if (aio->base.direction == CRAS_STREAM_OUTPUT) {
aout = (struct alsa_output_node *)node;
cras_volume_curve_destroy(aout->volume_curve);
- free((void *)aout->pcm_name);
- } else {
- ain = (struct alsa_input_node *)node;
- free((void *)ain->pcm_name);
}
cras_iodev_rm_node(&aio->base, node);
free(node->softvol_scalers);
@@ -889,8 +853,9 @@ static void free_alsa_iodev_resources(struct alsa_io *aio)
free(node);
}
+ free((void *)aio->dsp_name_default);
cras_iodev_free_resources(&aio->base);
- free(aio->pcm_name);
+ free(aio->dev);
if (aio->dev_id)
free(aio->dev_id);
if (aio->dev_name)
@@ -1102,50 +1067,71 @@ set_output_node_software_volume_needed(struct alsa_output_node *output,
output->base.name);
}
-static void set_input_default_node_gain(struct alsa_input_node *input,
- struct alsa_io *aio)
+static void set_input_node_software_volume_needed(struct alsa_input_node *input,
+ struct alsa_io *aio)
{
- long gain;
+ long min_software_gain;
+ long max_software_gain;
+ int rc;
- input->base.capture_gain = DEFAULT_CAPTURE_GAIN;
- input->base.ui_gain_scaler = 1.0f;
+ input->base.software_volume_needed = 0;
+ input->base.min_software_gain = DEFAULT_MIN_CAPTURE_GAIN;
+ input->base.max_software_gain = 0;
+ /* Enable software gain only if max software gain is specified in UCM. */
if (!aio->ucm)
return;
- if (ucm_get_default_node_gain(aio->ucm, input->base.name, &gain) == 0)
- input->base.capture_gain = gain;
+ rc = ucm_get_max_software_gain(aio->ucm, input->base.name,
+ &max_software_gain);
+
+ /* If max software gain doesn't exist, skip min software gain setting. */
+ if (rc)
+ return;
+
+ input->base.software_volume_needed = 1;
+ input->base.max_software_gain = max_software_gain;
+ syslog(LOG_INFO,
+ "Use software gain for %s with max %ld because it is specified"
+ " in UCM",
+ input->base.name, max_software_gain);
+
+ /* Enable min software gain if it is specified in UCM. */
+ rc = ucm_get_min_software_gain(aio->ucm, input->base.name,
+ &min_software_gain);
+ if (rc)
+ return;
+
+ if (min_software_gain > max_software_gain) {
+ syslog(LOG_ERR,
+ "Ignore MinSoftwareGain %ld because it is larger than "
+ "MaxSoftwareGain %ld",
+ min_software_gain, max_software_gain);
+ return;
+ }
+
+ syslog(LOG_INFO,
+ "Use software gain for %s with min %ld because it is specified"
+ " in UCM",
+ input->base.name, min_software_gain);
+ input->base.min_software_gain = min_software_gain;
}
-static void set_input_node_intrinsic_sensitivity(struct alsa_input_node *input,
- struct alsa_io *aio)
+static void set_input_default_node_gain(struct alsa_input_node *input,
+ struct alsa_io *aio)
{
- long sensitivity;
+ long default_node_gain;
int rc;
- input->base.intrinsic_sensitivity = 0;
+ if (!aio->ucm)
+ return;
- if (aio->ucm) {
- rc = ucm_get_intrinsic_sensitivity(aio->ucm, input->base.name,
- &sensitivity);
- if (rc)
- return;
- } else if (input->base.type == CRAS_NODE_TYPE_USB) {
- /*
- * For USB devices without UCM config, trust the default capture gain.
- * Set sensitivity to the default dbfs so the capture gain is 0.
- */
- sensitivity = DEFAULT_CAPTURE_VOLUME_DBFS;
- } else {
+ rc = ucm_get_default_node_gain(aio->ucm, input->base.name,
+ &default_node_gain);
+ if (rc)
return;
- }
- input->base.intrinsic_sensitivity = sensitivity;
- input->base.capture_gain = DEFAULT_CAPTURE_VOLUME_DBFS - sensitivity;
- syslog(LOG_INFO,
- "Use software gain %ld for %s because IntrinsicSensitivity %ld is"
- " specified in UCM",
- input->base.capture_gain, input->base.name, sensitivity);
+ input->base.capture_gain = default_node_gain;
}
static void check_auto_unplug_output_node(struct alsa_io *aio,
@@ -1263,6 +1249,7 @@ static struct alsa_input_node *new_input(struct alsa_io *aio,
{
struct cras_iodev *iodev = &aio->base;
struct alsa_input_node *input;
+ char *mic_positions;
int err;
input = (struct alsa_input_node *)calloc(1, sizeof(*input));
@@ -1279,10 +1266,22 @@ static struct alsa_input_node *new_input(struct alsa_io *aio,
input->mixer_input = cras_input;
strncpy(input->base.name, name, sizeof(input->base.name) - 1);
set_node_initial_state(&input->base, aio->card_type);
+ set_input_node_software_volume_needed(input, aio);
set_input_default_node_gain(input, aio);
- set_input_node_intrinsic_sensitivity(input, aio);
if (aio->ucm) {
+ /* Check mic positions only for internal mic. */
+ if ((input->base.type == CRAS_NODE_TYPE_MIC) &&
+ (input->base.position == NODE_POSITION_INTERNAL)) {
+ mic_positions = ucm_get_mic_positions(aio->ucm);
+ if (mic_positions) {
+ strncpy(input->base.mic_positions,
+ mic_positions,
+ sizeof(input->base.mic_positions) - 1);
+ free(mic_positions);
+ }
+ }
+
/* Check if channel map is specified in UCM. */
input->channel_layout = (int8_t *)malloc(
CRAS_CH_MAX * sizeof(*input->channel_layout));
@@ -1388,7 +1387,8 @@ static const struct cras_alsa_jack *get_jack_from_node(struct cras_ionode *node)
/*
* Returns the dsp name specified in the ucm config. If there is a dsp name
- * specified for the active node, use that. Otherwise NULL should be returned.
+ * specified for the active node, use that. Otherwise use the default dsp name
+ * for the alsa_io device.
*/
static const char *get_active_dsp_name(struct alsa_io *aio)
{
@@ -1397,7 +1397,7 @@ static const char *get_active_dsp_name(struct alsa_io *aio)
if (node == NULL)
return NULL;
- return node->dsp_name;
+ return node->dsp_name ?: aio->dsp_name_default;
}
/*
@@ -1426,73 +1426,6 @@ create_volume_curve_for_jack(const struct cras_card_config *config,
}
/*
- * Updates max_supported_channels value into cras_iodev_info.
- * Note that supported_rates, supported_channel_counts, and supported_formats of
- * iodev will be updated to the latest values after calling.
- */
-static void update_max_supported_channels(struct cras_iodev *iodev)
-{
- struct alsa_io *aio = (struct alsa_io *)iodev;
- unsigned int max_channels = 0;
- size_t i;
- bool active_node_predicted = false;
- int rc;
-
- /*
- * max_supported_channels might be wrong in dependent PCM cases. Always
- * return 2 for such cases.
- */
- if (aio->has_dependent_dev) {
- max_channels = 2;
- goto update_info;
- }
-
- if (aio->handle) {
- syslog(LOG_ERR,
- "update_max_supported_channels should not be called "
- "while device is opened.");
- return;
- }
-
- /*
- * In the case of updating max_supported_channels on changing jack
- * plugging status of devices, the active node may not be determined
- * yet. Use the first node as the active node for obtaining the value of
- * max_supported_channels.
- */
- if (!iodev->active_node) {
- if (!iodev->nodes)
- goto update_info;
- iodev->active_node = iodev->nodes;
- syslog(LOG_DEBUG,
- "Predict ionode %s as active node temporarily.",
- iodev->active_node->name);
- active_node_predicted = true;
- }
-
- rc = open_dev(iodev);
- if (active_node_predicted)
- iodev->active_node = NULL; // Reset the predicted active_node.
- if (rc)
- goto update_info;
-
- rc = update_supported_formats(iodev);
- if (rc)
- goto close_iodev;
-
- for (i = 0; iodev->supported_channel_counts[i] != 0; i++) {
- if (iodev->supported_channel_counts[i] > max_channels)
- max_channels = iodev->supported_channel_counts[i];
- }
-
-close_iodev:
- close_dev(iodev);
-
-update_info:
- iodev->info.max_supported_channels = max_channels;
-}
-
-/*
* Callback that is called when an output jack is plugged or unplugged.
*/
static void jack_output_plug_event(const struct cras_alsa_jack *jack,
@@ -1555,13 +1488,6 @@ static void jack_output_plug_event(const struct cras_alsa_jack *jack,
cras_iodev_set_node_plugged(&node->base, plugged);
check_auto_unplug_output_node(aio, &node->base, plugged);
-
- /*
- * For HDMI plug event cases, update max supported channels according
- * to the current active node.
- */
- if (node->base.type == CRAS_NODE_TYPE_HDMI && plugged)
- update_max_supported_channels(&aio->base);
}
/*
@@ -1675,29 +1601,6 @@ static int get_fixed_rate(struct alsa_io *aio)
return ucm_get_sample_rate_for_dev(aio->ucm, name, aio->base.direction);
}
-static size_t get_fixed_channels(struct alsa_io *aio)
-{
- const char *name;
- int rc;
- size_t channels;
-
- if (aio->base.direction == CRAS_STREAM_OUTPUT) {
- struct alsa_output_node *active = get_active_output(aio);
- if (!active)
- return -ENOENT;
- name = active->base.name;
- } else {
- struct alsa_input_node *active = get_active_input(aio);
- if (!active)
- return -ENOENT;
- name = active->base.name;
- }
-
- rc = ucm_get_channels_for_dev(aio->ucm, name, aio->base.direction,
- &channels);
- return (rc) ? 0 : channels;
-}
-
/*
* Updates the supported sample rates and channel counts.
*/
@@ -1706,7 +1609,6 @@ static int update_supported_formats(struct cras_iodev *iodev)
struct alsa_io *aio = (struct alsa_io *)iodev;
int err;
int fixed_rate;
- size_t fixed_channels;
free(iodev->supported_rates);
iodev->supported_rates = NULL;
@@ -1731,16 +1633,6 @@ static int update_supported_formats(struct cras_iodev *iodev)
iodev->supported_rates[0] = fixed_rate;
iodev->supported_rates[1] = 0;
}
-
- /* Allow UCM to override supported channel counts. */
- fixed_channels = get_fixed_channels(aio);
- if (fixed_channels > 0) {
- free(iodev->supported_channel_counts);
- iodev->supported_channel_counts = (size_t *)malloc(
- 2 * sizeof(iodev->supported_channel_counts[0]));
- iodev->supported_channel_counts[0] = fixed_channels;
- iodev->supported_channel_counts[1] = 0;
- }
}
return 0;
}
@@ -1861,8 +1753,8 @@ static int adjust_appl_ptr_samples_remaining(struct cras_iodev *odev)
* If underrun happened, handle it. Because alsa_output_underrun function
* has already called adjust_appl_ptr, we don't need to call it again.
*/
- if (real_hw_level <= odev->min_buffer_level)
- return cras_iodev_output_underrun(odev, real_hw_level, 0);
+ if (real_hw_level < odev->min_buffer_level)
+ return odev->output_underrun(odev);
if (real_hw_level > aio->filled_zeros_for_draining)
valid_sample = real_hw_level - aio->filled_zeros_for_draining;
@@ -1880,8 +1772,12 @@ static int adjust_appl_ptr_samples_remaining(struct cras_iodev *odev)
static int alsa_output_underrun(struct cras_iodev *odev)
{
+ struct alsa_io *aio = (struct alsa_io *)odev;
int rc;
+ /* Update number of underruns we got. */
+ aio->num_underruns++;
+
/* Fill whole buffer with zeros. This avoids samples left in buffer causing
* noise when device plays them. */
rc = fill_whole_buffer_with_zeros(odev);
@@ -1910,8 +1806,8 @@ static int possibly_enter_free_run(struct cras_iodev *odev)
real_hw_level = rc;
/* If underrun happened, handle it and enter free run state. */
- if (real_hw_level <= odev->min_buffer_level) {
- rc = cras_iodev_output_underrun(odev, real_hw_level, 0);
+ if (real_hw_level < odev->min_buffer_level) {
+ rc = odev->output_underrun(odev);
if (rc < 0)
return rc;
aio->free_running = 1;
@@ -1944,10 +1840,6 @@ static int leave_free_run(struct cras_iodev *odev)
struct alsa_io *aio = (struct alsa_io *)odev;
int rc;
- /* Restart rate estimation because free run internval should not
- * be included. */
- cras_iodev_reset_rate_estimator(odev);
-
if (aio->free_running)
rc = adjust_appl_ptr_for_leaving_free_run(odev);
else
@@ -1984,6 +1876,12 @@ static int is_free_running(const struct cras_iodev *odev)
return aio->free_running;
}
+static unsigned int get_num_underruns(const struct cras_iodev *iodev)
+{
+ const struct alsa_io *aio = (const struct alsa_io *)iodev;
+ return aio->num_underruns;
+}
+
static unsigned int get_num_severe_underruns(const struct cras_iodev *iodev)
{
const struct alsa_io *aio = (const struct alsa_io *)iodev;
@@ -2008,7 +1906,8 @@ static void set_default_hotword_model(struct cras_iodev *iodev)
return;
}
-static int get_valid_frames(struct cras_iodev *odev, struct timespec *tstamp)
+static int get_valid_frames(const struct cras_iodev *odev,
+ struct timespec *tstamp)
{
struct alsa_io *aio = (struct alsa_io *)odev;
int rc;
@@ -2035,26 +1934,15 @@ static int get_valid_frames(struct cras_iodev *odev, struct timespec *tstamp)
return 0;
}
-static int support_noise_cancellation(const struct cras_iodev *iodev)
-{
- struct alsa_io *aio = (struct alsa_io *)iodev;
-
- if (!aio->ucm || !iodev->active_node)
- return 0;
-
- return ucm_node_noise_cancellation_exists(aio->ucm,
- iodev->active_node->name);
-}
-
/*
* Exported Interface.
*/
struct cras_iodev *
alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
- const char *pcm_name, const char *dev_name,
- const char *dev_id, enum CRAS_ALSA_CARD_TYPE card_type,
- int is_first, struct cras_alsa_mixer *mixer,
+ const char *dev_name, const char *dev_id,
+ enum CRAS_ALSA_CARD_TYPE card_type, int is_first,
+ struct cras_alsa_mixer *mixer,
const struct cras_card_config *config,
struct cras_use_case_mgr *ucm, snd_hctl_t *hctl,
enum CRAS_STREAM_DIRECTION direction, size_t usb_vid,
@@ -2077,6 +1965,7 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
aio->is_first = is_first;
aio->handle = NULL;
aio->num_severe_underruns = 0;
+ aio->jack_always_plugged = 0;
if (dev_name) {
aio->dev_name = strdup(dev_name);
if (!aio->dev_name)
@@ -2089,10 +1978,11 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
}
aio->free_running = 0;
aio->filled_zeros_for_draining = 0;
- aio->has_dependent_dev = 0;
- aio->pcm_name = strdup(pcm_name);
- if (aio->pcm_name == NULL)
+ aio->dev = (char *)malloc(MAX_ALSA_DEV_NAME_LENGTH);
+ if (aio->dev == NULL)
goto cleanup_iodev;
+ snprintf(aio->dev, MAX_ALSA_DEV_NAME_LENGTH, "hw:%zu,%zu", card_index,
+ device_index);
if (direction == CRAS_STREAM_INPUT) {
aio->alsa_stream = SND_PCM_STREAM_CAPTURE;
@@ -2120,10 +2010,10 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
iodev->get_hotword_models = get_hotword_models;
iodev->no_stream = no_stream;
iodev->is_free_running = is_free_running;
+ iodev->get_num_underruns = get_num_underruns;
iodev->get_num_severe_underruns = get_num_severe_underruns;
iodev->get_valid_frames = get_valid_frames;
iodev->set_swap_mode_for_node = cras_iodev_dsp_set_swap_mode_for_node;
- iodev->support_noise_cancellation = support_noise_cancellation;
if (card_type == ALSA_CARD_TYPE_USB)
iodev->min_buffer_level = USB_EXTRA_BUFFER_FRAMES;
@@ -2131,7 +2021,6 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
iodev->ramp = cras_ramp_create();
if (iodev->ramp == NULL)
goto cleanup_iodev;
- iodev->initial_ramp_request = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
aio->mixer = mixer;
aio->config = config;
@@ -2148,6 +2037,8 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
unsigned int level;
int rc;
+ aio->dsp_name_default =
+ ucm_get_dsp_name_default(ucm, direction);
/* Set callback for swap mode if it is supported
* in ucm modifier. */
if (ucm_swap_mode_exists(ucm))
@@ -2157,6 +2048,8 @@ alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
rc = ucm_get_min_buffer_level(ucm, &level);
if (!rc && direction == CRAS_STREAM_OUTPUT)
iodev->min_buffer_level = level;
+
+ aio->enable_htimestamp = ucm_get_enable_htimestamp_flag(ucm);
}
set_iodev_name(iodev, card_name, dev_name, card_index, device_index,
@@ -2270,9 +2163,6 @@ int alsa_iodev_legacy_complete_init(struct cras_iodev *iodev)
set_default_hotword_model(iodev);
- /* Record max supported channels into cras_iodev_info. */
- update_max_supported_channels(iodev);
-
return 0;
}
@@ -2288,17 +2178,9 @@ int alsa_iodev_ucm_add_nodes_and_jacks(struct cras_iodev *iodev,
if (!aio || !section)
return -EINVAL;
-
- /* Allow this section to add as a new node only if the device id
- * or dependent device id matches this iodev. */
- if (((uint32_t)section->dev_idx != aio->device_index) &&
- ((uint32_t)section->dependent_dev_idx != aio->device_index))
+ if ((uint32_t)section->dev_idx != aio->device_index)
return -EINVAL;
- /* Set flag has_dependent_dev for the case of dependent device. */
- if (section->dependent_dev_idx != -1)
- aio->has_dependent_dev = 1;
-
/* This iodev is fully specified. Avoid automatic node creation. */
aio->fully_specified = 1;
@@ -2315,14 +2197,15 @@ int alsa_iodev_ucm_add_nodes_and_jacks(struct cras_iodev *iodev,
output_node = new_output(aio, control, section->name);
if (!output_node)
return -ENOMEM;
- output_node->pcm_name = strdup(section->pcm_name);
} else if (iodev->direction == CRAS_STREAM_INPUT) {
input_node = new_input(aio, control, section->name);
if (!input_node)
return -ENOMEM;
- input_node->pcm_name = strdup(section->pcm_name);
}
+ if (section->jack_type && !strcmp(section->jack_type, "always"))
+ aio->jack_always_plugged = 1;
+
/* Find any jack controls for this device. */
rc = cras_alsa_jack_list_add_jack_for_section(aio->jack_list, section,
&jack);
@@ -2347,7 +2230,6 @@ int alsa_iodev_ucm_add_nodes_and_jacks(struct cras_iodev *iodev,
void alsa_iodev_ucm_complete_init(struct cras_iodev *iodev)
{
struct alsa_io *aio = (struct alsa_io *)iodev;
- struct cras_ionode *node;
if (!iodev)
return;
@@ -2365,22 +2247,15 @@ void alsa_iodev_ucm_complete_init(struct cras_iodev *iodev)
/*
* Set plugged for the USB device per card when it appears if
- * there is no jack reporting plug status
+ * there is no jack reporting plug status and the jack is set
+ * to be always plugged.
*/
- if (aio->card_type == ALSA_CARD_TYPE_USB) {
- DL_FOREACH (iodev->nodes, node) {
- if (!get_jack_from_node(node))
- cras_iodev_set_node_plugged(node, 1);
- }
+ if (aio->card_type == ALSA_CARD_TYPE_USB && aio->jack_always_plugged &&
+ !get_jack_from_node(iodev->active_node)) {
+ cras_iodev_set_node_plugged(iodev->active_node, 1);
}
set_default_hotword_model(iodev);
-
- node = iodev->active_node;
-
- /* Record max supported channels into cras_iodev_info. */
- if (node && node->plugged)
- update_max_supported_channels(iodev);
}
void alsa_iodev_destroy(struct cras_iodev *iodev)
@@ -2444,10 +2319,12 @@ static int alsa_iodev_set_active_node(struct cras_iodev *iodev,
unsigned dev_enabled)
{
struct alsa_io *aio = (struct alsa_io *)iodev;
- int rc = 0;
- if (iodev->active_node == ionode)
- goto skip;
+ if (iodev->active_node == ionode) {
+ enable_active_ucm(aio, dev_enabled);
+ init_device_settings(aio);
+ return 0;
+ }
/* Disable jack ucm before switching node. */
enable_active_ucm(aio, 0);
@@ -2457,16 +2334,7 @@ static int alsa_iodev_set_active_node(struct cras_iodev *iodev,
cras_iodev_set_active_node(iodev, ionode);
aio->base.dsp_name = get_active_dsp_name(aio);
cras_iodev_update_dsp(iodev);
-skip:
enable_active_ucm(aio, dev_enabled);
- if (ionode->type == CRAS_NODE_TYPE_HOTWORD) {
- if (dev_enabled) {
- rc = ucm_enable_hotword_model(aio->ucm);
- if (rc < 0)
- return rc;
- } else
- ucm_disable_all_hotword_models(aio->ucm);
- }
/* Setting the volume will also unmute if the system isn't muted. */
init_device_settings(aio);
return 0;
diff --git a/cras/src/server/cras_alsa_io.h b/cras/src/server/cras_alsa_io.h
index f8e613d0..9bc0c1f9 100644
--- a/cras/src/server/cras_alsa_io.h
+++ b/cras/src/server/cras_alsa_io.h
@@ -21,7 +21,6 @@ struct ucm_section;
* card_index - 0 based index, value of "XX" in "hw:XX,YY".
* card_name - The name of the card.
* device_index - 0 based index, value of "YY" in "hw:XX,YY".
- * pcm_name - The pcm name passing to snd_pcm_open(), e.g hw:0,0
* dev_name - The name of the device.
* dev_id - The id string of the device.
* card_type - the type of the card this iodev belongs.
@@ -39,9 +38,9 @@ struct ucm_section;
*/
struct cras_iodev *
alsa_iodev_create(size_t card_index, const char *card_name, size_t device_index,
- const char *pcm_name, const char *dev_name,
- const char *dev_id, enum CRAS_ALSA_CARD_TYPE card_type,
- int is_first, struct cras_alsa_mixer *mixer,
+ const char *dev_name, const char *dev_id,
+ enum CRAS_ALSA_CARD_TYPE card_type, int is_first,
+ struct cras_alsa_mixer *mixer,
const struct cras_card_config *config,
struct cras_use_case_mgr *ucm, snd_hctl_t *hctl,
enum CRAS_STREAM_DIRECTION direction, size_t usb_vid,
diff --git a/cras/src/server/cras_alsa_jack.c b/cras/src/server/cras_alsa_jack.c
index 6d4d7bf5..a16e94e4 100644
--- a/cras/src/server/cras_alsa_jack.c
+++ b/cras/src/server/cras_alsa_jack.c
@@ -380,7 +380,7 @@ static void display_info_delay_cb(struct cras_timer *timer, void *arg)
* file has data to read. Perform autoswitching to / from the
* associated device when data is available.
*/
-static void gpio_switch_callback(void *arg, int events)
+static void gpio_switch_callback(void *arg)
{
struct cras_alsa_jack *jack = arg;
int i;
@@ -408,30 +408,38 @@ static void gpio_switch_callback(void *arg, int events)
static unsigned int
gpio_jack_match_device(const struct cras_alsa_jack *jack,
struct cras_alsa_jack_list *jack_list,
+ const char *card_name,
enum CRAS_STREAM_DIRECTION direction)
{
- int target_dev_idx;
+ const char *target_device_name = NULL;
+ char current_device_name[CRAS_IODEV_NAME_BUFFER_SIZE];
+ unsigned int rc;
/* If the device name is not specified in UCM, assume it should be
* associated with device 0. */
if (!jack_list->ucm || !jack->ucm_device)
return jack_list->is_first_device;
- /* If jack has valid ucm_device, that means this jack has already been
- * associated to this card. Next step to match device index on this
- * card. */
- target_dev_idx = ucm_get_alsa_dev_idx_for_dev(
+ /* Look for device name specified in a device section of UCM. */
+ target_device_name = ucm_get_device_name_for_dev(
jack_list->ucm, jack->ucm_device, direction);
- if (target_dev_idx < 0)
+ if (!target_device_name)
return jack_list->is_first_device;
syslog(LOG_DEBUG,
- "Matching GPIO jack, target device idx: %d, "
+ "Matching GPIO jack, target device name: %s, "
"current card name: %s, device index: %zu\n",
- target_dev_idx, jack_list->card_name, jack_list->device_index);
+ target_device_name, card_name, jack_list->device_index);
- return (target_dev_idx == jack_list->device_index);
+ /* Device name of format "hw:<card_name>,<device_index>", should fit
+ * in the string of size CRAS_IODEV_NAME_BUFFER_SIZE.*/
+ snprintf(current_device_name, sizeof(current_device_name), "hw:%s,%zu",
+ card_name, jack_list->device_index);
+
+ rc = !strcmp(current_device_name, target_device_name);
+ free((void *)target_device_name);
+ return rc;
}
static int create_jack_for_gpio(struct cras_alsa_jack_list *jack_list,
@@ -503,8 +511,8 @@ static int cras_complete_gpio_jack(struct gpio_switch_list_data *data,
cras_free_jack(jack, 0);
return -EIO;
}
- r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback, jack,
- POLLIN);
+ r = cras_system_add_select_fd(jack->gpio.fd, gpio_switch_callback,
+ jack);
if (r < 0) {
/* Not yet registered with system select. */
cras_free_jack(jack, 0);
@@ -532,6 +540,7 @@ static int open_and_monitor_gpio(struct gpio_switch_list_data *data,
{
struct cras_alsa_jack *jack;
struct cras_alsa_jack_list *jack_list = data->jack_list;
+ const char *card_name = jack_list->card_name;
enum CRAS_STREAM_DIRECTION direction = jack_list->direction;
int r;
@@ -544,7 +553,7 @@ static int open_and_monitor_gpio(struct gpio_switch_list_data *data,
jack->ucm_device = ucm_get_dev_for_jack(
jack_list->ucm, jack->gpio.device_name, direction);
- if (!gpio_jack_match_device(jack, jack_list, direction)) {
+ if (!gpio_jack_match_device(jack, jack_list, card_name, direction)) {
cras_free_jack(jack, 0);
return -EIO;
}
@@ -719,31 +728,6 @@ static int gpio_switch_list_by_matching(const char *dev_path,
return data->rc;
}
-/* Find ELD control for HDMI/DP gpio jack. */
-static snd_hctl_elem_t *find_eld_control_by_dev_index(snd_hctl_t *hctl,
- unsigned int dev_idx)
-{
- static const char eld_control_name[] = "ELD";
- snd_ctl_elem_id_t *elem_id;
-
- snd_ctl_elem_id_alloca(&elem_id);
- snd_ctl_elem_id_clear(elem_id);
- snd_ctl_elem_id_set_interface(elem_id, SND_CTL_ELEM_IFACE_PCM);
- snd_ctl_elem_id_set_device(elem_id, dev_idx);
- snd_ctl_elem_id_set_name(elem_id, eld_control_name);
- return snd_hctl_find_elem(hctl, elem_id);
-}
-
-/* For non-gpio jack, check if it's of type hdmi/dp by
- * matching jack name. */
-static int is_jack_hdmi_dp(const char *jack_name)
-{
- // TODO(hychao): Use the information provided in UCM instead of
- // name matching.
- static const char *hdmi_dp = "HDMI";
- return !!strstr(jack_name, hdmi_dp);
-}
-
/* Find GPIO jacks for this jack_list.
* Args:
* jack_list - Jack list to add to.
@@ -779,17 +763,8 @@ static int find_gpio_jacks(struct cras_alsa_jack_list *jack_list,
gpio_switch_list_for_each(gpio_switch_list_with_section, &data);
else
gpio_switch_list_for_each(gpio_switch_list_by_matching, &data);
- if (result_jack) {
+ if (result_jack)
*result_jack = data.result_jack;
-
- /* Find ELD control only for HDMI/DP gpio jack. */
- if (*result_jack &&
- is_jack_hdmi_dp((*result_jack)->gpio.device_name))
- (*result_jack)->eld_control =
- find_eld_control_by_dev_index(
- jack_list->hctl,
- jack_list->device_index);
- }
return data.rc;
}
@@ -844,6 +819,14 @@ static unsigned int hctl_jack_device_index(const char *name)
return (unsigned int)device_index;
}
+/* For non-gpio jack, check if it's of type hdmi/dp by
+ * matching jack name. */
+static int is_jack_hdmi_dp(const char *jack_name)
+{
+ static const char *hdmi_dp = "HDMI/DP";
+ return strncmp(jack_name, hdmi_dp, strlen(hdmi_dp)) == 0;
+}
+
/* Checks if the given control name is in the supplied list of possible jack
* control base names. */
static int is_jack_control_in_list(const char *const *list,
@@ -884,6 +867,7 @@ static int find_jack_controls(struct cras_alsa_jack_list *jack_list)
static const char *const input_jack_base_names[] = {
"Mic Jack",
};
+ static const char eld_control_name[] = "ELD";
const char *const *jack_names;
unsigned int num_jack_names;
@@ -957,9 +941,17 @@ static int find_jack_controls(struct cras_alsa_jack_list *jack_list)
name = snd_hctl_elem_get_name(jack->elem);
if (!is_jack_hdmi_dp(name))
continue;
-
- jack->eld_control = find_eld_control_by_dev_index(
- jack_list->hctl, jack_list->device_index);
+ for (elem = snd_hctl_first_elem(jack_list->hctl); elem != NULL;
+ elem = snd_hctl_elem_next(elem)) {
+ if (strcmp(snd_hctl_elem_get_name(elem),
+ eld_control_name))
+ continue;
+ if (snd_hctl_elem_get_device(elem) !=
+ jack_list->device_index)
+ continue;
+ jack->eld_control = elem;
+ break;
+ }
}
return 0;
@@ -985,6 +977,7 @@ static int find_hctl_jack_for_section(struct cras_alsa_jack_list *jack_list,
struct ucm_section *section,
struct cras_alsa_jack **result_jack)
{
+ static const char eld_control_name[] = "ELD";
snd_hctl_elem_t *elem;
snd_ctl_elem_id_t *elem_id;
struct cras_alsa_jack *jack;
@@ -1035,8 +1028,10 @@ static int find_hctl_jack_for_section(struct cras_alsa_jack_list *jack_list,
return 0;
/* Look up ELD control. */
- jack->eld_control = find_eld_control_by_dev_index(
- jack_list->hctl, jack_list->device_index);
+ snd_ctl_elem_id_set_name(elem_id, eld_control_name);
+ elem = snd_hctl_find_elem(jack_list->hctl, elem_id);
+ if (elem)
+ jack->eld_control = elem;
return 0;
}
diff --git a/cras/src/server/cras_alsa_mixer.c b/cras/src/server/cras_alsa_mixer.c
index 3379d959..99f4d61f 100644
--- a/cras/src/server/cras_alsa_mixer.c
+++ b/cras/src/server/cras_alsa_mixer.c
@@ -417,7 +417,7 @@ static int mixer_control_set_mute(const struct mixer_control *control,
int muted)
{
const struct mixer_control_element *elem = NULL;
- int rc = -EINVAL;
+ int rc;
if (!control)
return -EINVAL;
DL_FOREACH (control->elements, elem) {
@@ -943,7 +943,7 @@ void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer *cras_mixer, long dBFS,
assert(cras_mixer);
/* dBFS is normally < 0 to specify the attenuation from max. max is the
- * combined max of the main controls and the current output.
+ * combined max of the master controls and the current output.
*/
to_set = dBFS + cras_mixer->max_volume_dB;
if (cras_alsa_mixer_has_volume(mixer_output))
@@ -959,9 +959,9 @@ void cras_alsa_mixer_set_dBFS(struct cras_alsa_mixer *cras_mixer, long dBFS,
if (!c->has_volume)
continue;
- if (mixer_control_set_dBFS(c, to_set) == 0 &&
- mixer_control_get_dBFS(c, &actual_dB) == 0)
- to_set -= actual_dB;
+ mixer_control_set_dBFS(c, to_set);
+ mixer_control_get_dBFS(c, &actual_dB);
+ to_set -= actual_dB;
}
/* Apply the rest to the output-specific control. */
if (cras_alsa_mixer_has_volume(mixer_output))
@@ -1002,9 +1002,9 @@ void cras_alsa_mixer_set_capture_dBFS(struct cras_alsa_mixer *cras_mixer,
if (!c->has_volume)
continue;
- if (mixer_control_set_dBFS(c, to_set) == 0 &&
- mixer_control_get_dBFS(c, &actual_dB) == 0)
- to_set -= actual_dB;
+ mixer_control_set_dBFS(c, to_set);
+ mixer_control_get_dBFS(c, &actual_dB);
+ to_set -= actual_dB;
}
/* Apply the reset to input specific control */
diff --git a/cras/src/server/cras_alsa_mixer.h b/cras/src/server/cras_alsa_mixer.h
index 878fbe54..6b306035 100644
--- a/cras/src/server/cras_alsa_mixer.h
+++ b/cras/src/server/cras_alsa_mixer.h
@@ -6,6 +6,9 @@
#ifndef _CRAS_ALSA_MIXER_H
#define _CRAS_ALSA_MIXER_H
+#include <alsa/asoundlib.h>
+#include <iniparser.h>
+
#include "cras_types.h"
/* cras_alsa_mixer represents the alsa mixer interface for an alsa card. It
@@ -147,7 +150,7 @@ void cras_alsa_mixer_set_mute(struct cras_alsa_mixer *cras_mixer, int muted,
* Args:
* cras_mixer - Mixer to set the volume in.
* muted - 1 if muted, 0 if not.
- * mixer_input - The mixer input to mute if no card mute.
+ * mixer_input - The mixer input to mute if no master mute.
*/
void cras_alsa_mixer_set_capture_mute(struct cras_alsa_mixer *cras_mixer,
int muted,
diff --git a/cras/src/server/cras_alsa_plugin_io.c b/cras/src/server/cras_alsa_plugin_io.c
deleted file mode 100644
index 32c1ae11..00000000
--- a/cras/src/server/cras_alsa_plugin_io.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <alsa/asoundlib.h>
-#include <alsa/use-case.h>
-#include <stdio.h>
-#include <sys/select.h>
-#include <syslog.h>
-
-#include "cras_alsa_io.h"
-#include "cras_alsa_jack.h"
-#include "cras_alsa_mixer.h"
-#include "cras_alsa_ucm.h"
-#include "cras_iodev.h"
-#include "cras_system_state.h"
-#include "iniparser_wrapper.h"
-#include "utlist.h"
-
-#define PLUGINS_INI "plugins.ini"
-#define PLUGIN_KEY_CTL "ctl"
-#define PLUGIN_KEY_DIR "dir"
-#define PLUGIN_KEY_PCM "pcm"
-#define PLUGIN_KEY_CARD "card"
-
-#define NULL_USB_VID 0x00
-#define NULL_USB_PID 0x00
-#define NULL_USB_SERIAL_NUMBER "serial-number-not-used"
-
-struct hctl_poll_fd {
- int fd;
- struct hctl_poll_fd *prev, *next;
-};
-
-struct alsa_plugin {
- snd_hctl_t *hctl;
- struct cras_alsa_mixer *mixer;
- struct hctl_poll_fd *hctl_poll_fds;
- struct cras_use_case_mgr *ucm;
- struct cras_iodev *iodev;
- struct alsa_plugin *next, *prev;
-};
-
-static struct alsa_plugin *plugins;
-
-static char ini_name[MAX_INI_NAME_LENGTH + 1];
-static char key_name[MAX_INI_NAME_LENGTH + 1];
-static dictionary *plugins_ini = NULL;
-
-static void hctl_event_pending(void *arg, int revents)
-{
- struct alsa_plugin *plugin;
-
- plugin = (struct alsa_plugin *)arg;
- if (plugin->hctl == NULL)
- return;
-
- /* handle_events will trigger the callback registered with each control
- * that has changed. */
- snd_hctl_handle_events(plugin->hctl);
-}
-
-/* hctl poll descritpor */
-static void collect_poll_descriptors(struct alsa_plugin *plugin)
-{
- struct hctl_poll_fd *registered_fd;
- struct pollfd *pollfds;
- int i, n, rc;
-
- n = snd_hctl_poll_descriptors_count(plugin->hctl);
- if (n == 0) {
- syslog(LOG_DEBUG, "No hctl descritpor to poll");
- return;
- }
-
- pollfds = malloc(n * sizeof(*pollfds));
- if (pollfds == NULL)
- return;
-
- n = snd_hctl_poll_descriptors(plugin->hctl, pollfds, n);
- for (i = 0; i < n; i++) {
- registered_fd = calloc(1, sizeof(*registered_fd));
- if (registered_fd == NULL) {
- free(pollfds);
- return;
- }
- registered_fd->fd = pollfds[i].fd;
- DL_APPEND(plugin->hctl_poll_fds, registered_fd);
- rc = cras_system_add_select_fd(
- registered_fd->fd, hctl_event_pending, plugin, POLLIN);
- if (rc < 0) {
- DL_DELETE(plugin->hctl_poll_fds, registered_fd);
- free(pollfds);
- return;
- }
- }
- free(pollfds);
-}
-
-static void cleanup_poll_descriptors(struct alsa_plugin *plugin)
-{
- struct hctl_poll_fd *poll_fd;
- DL_FOREACH (plugin->hctl_poll_fds, poll_fd) {
- cras_system_rm_select_fd(poll_fd->fd);
- DL_DELETE(plugin->hctl_poll_fds, poll_fd);
- free(poll_fd);
- }
-}
-
-static void destroy_plugin(struct alsa_plugin *plugin);
-
-void alsa_plugin_io_create(enum CRAS_STREAM_DIRECTION direction,
- const char *pcm_name, const char *ctl_name,
- const char *card_name)
-{
- struct alsa_plugin *plugin;
- struct ucm_section *section;
- struct ucm_section *ucm_sections;
- int rc;
-
- plugin = (struct alsa_plugin *)calloc(1, sizeof(*plugin));
- if (!plugin) {
- syslog(LOG_ERR, "No memory to create alsa plugin");
- return;
- }
-
- rc = snd_hctl_open(&plugin->hctl, ctl_name, SND_CTL_NONBLOCK);
- if (rc < 0) {
- syslog(LOG_ERR, "open hctl fail for plugin %s", ctl_name);
- goto cleanup;
- }
-
- rc = snd_hctl_nonblock(plugin->hctl, 1);
- if (rc < 0) {
- syslog(LOG_ERR, "Failed to nonblock hctl for %s", ctl_name);
- goto cleanup;
- }
- rc = snd_hctl_load(plugin->hctl);
- if (rc < 0) {
- syslog(LOG_ERR, "Failed to load hctl for %s", ctl_name);
- goto cleanup;
- }
- collect_poll_descriptors(plugin);
-
- plugin->mixer = cras_alsa_mixer_create(ctl_name);
-
- plugin->ucm = ucm_create(card_name);
-
- DL_APPEND(plugins, plugin);
-
- ucm_sections = ucm_get_sections(plugin->ucm);
- DL_FOREACH (ucm_sections, section) {
- rc = cras_alsa_mixer_add_controls_in_section(plugin->mixer,
- section);
- if (rc)
- syslog(LOG_ERR,
- "Failed adding control to plugin,"
- "section %s mixer_name %s",
- section->name, section->mixer_name);
- }
- plugin->iodev = alsa_iodev_create(0, card_name, 0, pcm_name, "", "",
- ALSA_CARD_TYPE_USB, 1, /* is first */
- plugin->mixer, NULL, plugin->ucm,
- plugin->hctl, direction, NULL_USB_VID,
- NULL_USB_PID, NULL_USB_SERIAL_NUMBER);
-
- DL_FOREACH (ucm_sections, section) {
- if (section->dir != plugin->iodev->direction)
- continue;
- section->dev_idx = 0;
- alsa_iodev_ucm_add_nodes_and_jacks(plugin->iodev, section);
- }
-
- alsa_iodev_ucm_complete_init(plugin->iodev);
-
- return;
-cleanup:
- if (plugin)
- destroy_plugin(plugin);
-}
-
-static void destroy_plugin(struct alsa_plugin *plugin)
-{
- cleanup_poll_descriptors(plugin);
- if (plugin->hctl)
- snd_hctl_close(plugin->hctl);
- if (plugin->iodev)
- alsa_iodev_destroy(plugin->iodev);
- if (plugin->mixer)
- cras_alsa_mixer_destroy(plugin->mixer);
-
- free(plugin);
-}
-
-void alsa_pluigin_io_destroy_all()
-{
- struct alsa_plugin *plugin;
-
- DL_FOREACH (plugins, plugin)
- destroy_plugin(plugin);
-}
-
-void cras_alsa_plugin_io_init(const char *device_config_dir)
-{
- int nsec, i;
- enum CRAS_STREAM_DIRECTION direction;
- const char *sec_name;
- const char *tmp, *pcm_name, *ctl_name, *card_name;
-
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", device_config_dir,
- PLUGINS_INI);
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
-
- plugins_ini = iniparser_load_wrapper(ini_name);
- if (!plugins_ini)
- return;
-
- nsec = iniparser_getnsec(plugins_ini);
- for (i = 0; i < nsec; i++) {
- sec_name = iniparser_getsecname(plugins_ini, i);
-
- /* Parse dir=output or dir=input */
- snprintf(key_name, MAX_INI_NAME_LENGTH, "%s:%s", sec_name,
- PLUGIN_KEY_DIR);
- tmp = iniparser_getstring(plugins_ini, key_name, NULL);
- if (strcmp(tmp, "output") == 0)
- direction = CRAS_STREAM_OUTPUT;
- else if (strcmp(tmp, "input") == 0)
- direction = CRAS_STREAM_INPUT;
- else
- continue;
-
- /* pcm=<plugin-pcm-name> this name will be used with
- * snd_pcm_open. */
- snprintf(key_name, MAX_INI_NAME_LENGTH, "%s:%s", sec_name,
- PLUGIN_KEY_PCM);
- pcm_name = iniparser_getstring(plugins_ini, key_name, NULL);
- if (!pcm_name)
- continue;
-
- /* ctl=<plugin-ctl-name> this name will be used with
- * snd_hctl_open. */
- snprintf(key_name, MAX_INI_NAME_LENGTH, "%s:%s", sec_name,
- PLUGIN_KEY_CTL);
- ctl_name = iniparser_getstring(plugins_ini, key_name, NULL);
- if (!ctl_name)
- continue;
-
- /* card=<card-name> this name will be used with
- * snd_use_case_mgr_open. */
- snprintf(key_name, MAX_INI_NAME_LENGTH, "%s:%s", sec_name,
- PLUGIN_KEY_CARD);
- card_name = iniparser_getstring(plugins_ini, key_name, NULL);
- if (!card_name)
- continue;
-
- syslog(LOG_DEBUG,
- "Creating plugin for direction %s, pcm %s, ctl %s, card %s",
- direction == CRAS_STREAM_OUTPUT ? "output" : "input",
- pcm_name, ctl_name, card_name);
-
- alsa_plugin_io_create(direction, pcm_name, ctl_name, card_name);
- }
-}
diff --git a/cras/src/server/cras_alsa_plugin_io.h b/cras/src/server/cras_alsa_plugin_io.h
deleted file mode 100644
index 995f463e..00000000
--- a/cras/src/server/cras_alsa_plugin_io.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef CRAS_ALSA_PLUGIN_IO_H_
-#define CRAS_ALSA_PLUGIN_IO_H_
-
-/*
- * Disclaimer:
- * The ALSA plugin path in CRAS is intended to be used for development or
- * testing. CrOS audio team is not responsible for nor provides hot-fix to
- * any breakage if it’s used in production code.
- */
-
-void alsa_pluigin_io_destroy_all();
-
-void cras_alsa_plugin_io_init(const char *device_config_dir);
-
-#endif /* CRAS_ALSA_PLUGIN_IO_H_ */
diff --git a/cras/src/server/cras_alsa_ucm.c b/cras/src/server/cras_alsa_ucm.c
index 3e46f6a9..12ee81e6 100644
--- a/cras/src/server/cras_alsa_ucm.c
+++ b/cras/src/server/cras_alsa_ucm.c
@@ -13,53 +13,49 @@
#include "cras_util.h"
#include "utlist.h"
-static const char jack_control_var[] = "JackControl";
-static const char jack_dev_var[] = "JackDev";
+static const char jack_var[] = "JackName";
+static const char jack_type_var[] = "JackType";
static const char jack_switch_var[] = "JackSwitch";
static const char edid_var[] = "EDIDFile";
static const char cap_var[] = "CaptureControl";
+static const char mic_positions[] = "MicPositions";
static const char override_type_name_var[] = "OverrideNodeType";
+static const char output_dsp_name_var[] = "OutputDspName";
+static const char input_dsp_name_var[] = "InputDspName";
static const char dsp_name_var[] = "DspName";
-static const char playback_mixer_elem_var[] = "PlaybackMixerElem";
-static const char capture_mixer_elem_var[] = "CaptureMixerElem";
+static const char mixer_var[] = "MixerName";
+static const char swap_mode_suffix[] = "Swap Mode";
static const char min_buffer_level_var[] = "MinBufferLevel";
static const char dma_period_var[] = "DmaPeriodMicrosecs";
static const char disable_software_volume[] = "DisableSoftwareVolume";
static const char playback_device_name_var[] = "PlaybackPCM";
static const char playback_device_rate_var[] = "PlaybackRate";
-static const char playback_channels_var[] = "PlaybackChannels";
static const char capture_device_name_var[] = "CapturePCM";
static const char capture_device_rate_var[] = "CaptureRate";
static const char capture_channel_map_var[] = "CaptureChannelMap";
-static const char capture_channels_var[] = "CaptureChannels";
static const char coupled_mixers[] = "CoupledMixers";
-static const char dependent_device_name_var[] = "DependentPCM";
static const char preempt_hotword_var[] = "PreemptHotword";
static const char echo_reference_dev_name_var[] = "EchoReferenceDev";
-
-/* SectionModifier prefixes and suffixes. */
-static const char hotword_model_prefix[] = "Hotword Model";
-static const char swap_mode_suffix[] = "Swap Mode";
-static const char noise_cancellation_suffix[] = "Noise Cancellation";
-
/*
- * Set this value in a SectionDevice to specify the intrinsic sensitivity in
- * 0.01 dBFS/Pa. It currently only supports input devices. You should get the
- * value by recording samples without either hardware or software gain. We are
- * still working on building a standard process for measuring it. The value you
- * see now in our UCM is just estimated value. If it is set, CRAS will enable
- * software gain and use the value as a reference for calculating the
- * appropriate software gain to apply to the device to meet our target volume.
+ * Set this value in a SectionDevice to specify the minimum software gain in
+ * 0.01 dB and enable software gain on this node. It must be used with
+ * MaxSoftwareGain. If not, the value will be ignored.
*/
-static const char intrinsic_sensitivity_var[] = "IntrinsicSensitivity";
-
+static const char min_software_gain[] = "MinSoftwareGain";
+/*
+ * Set this value in a SectionDevice to specify the maximum software gain in
+ * 0.01 dB and enable software gain on this node.
+ */
+static const char max_software_gain[] = "MaxSoftwareGain";
/*
* Set this value in a SectionDevice to specify the default node gain in
* 0.01 dB.
*/
static const char default_node_gain[] = "DefaultNodeGain";
+static const char hotword_model_prefix[] = "Hotword Model";
static const char fully_specified_ucm_var[] = "FullySpecifiedUCM";
static const char main_volume_names[] = "MainVolumeNames";
+static const char enable_htimestamp_var[] = "EnableHtimestamp";
/* Use case verbs corresponding to CRAS_STREAM_TYPE. */
static const char *use_case_verbs[] = {
@@ -67,8 +63,6 @@ static const char *use_case_verbs[] = {
"Speech", "Pro Audio", "Accessibility",
};
-static const size_t max_section_name_len = 100;
-
/* Represents a list of section names found in UCM. */
struct section_name {
const char *name;
@@ -77,10 +71,9 @@ struct section_name {
struct cras_use_case_mgr {
snd_use_case_mgr_t *mgr;
- char *name;
+ const char *name;
unsigned int avail_use_cases;
enum CRAS_STREAM_TYPE use_case;
- char *hotword_modifier;
};
static inline const char *uc_verb(struct cras_use_case_mgr *mgr)
@@ -315,42 +308,32 @@ ucm_get_devices_for_var(struct cras_use_case_mgr *mgr, const char *var,
return section_names;
}
-static const char *ucm_get_value_for_dev(struct cras_use_case_mgr *mgr,
- const char *value_var, const char *dev)
+static const char *
+ucm_get_playback_device_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
{
const char *name = NULL;
int rc;
- rc = get_var(mgr, value_var, dev, uc_verb(mgr), &name);
+ rc = get_var(mgr, playback_device_name_var, dev, uc_verb(mgr), &name);
if (rc)
return NULL;
return name;
}
-static inline const char *
-ucm_get_playback_device_name_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
-{
- return ucm_get_value_for_dev(mgr, playback_device_name_var, dev);
-}
-
-static inline const char *
+static const char *
ucm_get_capture_device_name_for_dev(struct cras_use_case_mgr *mgr,
const char *dev)
{
- return ucm_get_value_for_dev(mgr, capture_device_name_var, dev);
-}
+ const char *name = NULL;
+ int rc;
-/* Gets the value of DependentPCM property. This is used to structure two
- * SectionDevices under one cras iodev to avoid two PCMs be open at the
- * same time because of restriction in lower layer driver or hardware.
- */
-static inline const char *
-ucm_get_dependent_device_name_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
-{
- return ucm_get_value_for_dev(mgr, dependent_device_name_var, dev);
+ rc = get_var(mgr, capture_device_name_var, dev, uc_verb(mgr), &name);
+ if (rc)
+ return NULL;
+
+ return name;
}
/* Get a list of mixer names specified in a UCM variable separated by ",".
@@ -382,21 +365,6 @@ static struct mixer_name *ucm_get_mixer_names(struct cras_use_case_mgr *mgr,
return names;
}
-/* Gets the modifier name of Noise Cancellation for the given node_name. */
-static void ucm_get_node_noise_cancellation_name(const char *node_name,
- char *mod_name)
-{
- size_t len =
- strlen(node_name) + 1 + strlen(noise_cancellation_suffix) + 1;
- if (len > max_section_name_len) {
- syslog(LOG_ERR,
- "Length of the given section name is %zu > %zu(max)",
- len, max_section_name_len);
- len = max_section_name_len;
- }
- snprintf(mod_name, len, "%s %s", node_name, noise_cancellation_suffix);
-}
-
/* Exported Interface */
struct cras_use_case_mgr *ucm_create(const char *name)
@@ -415,10 +383,6 @@ struct cras_use_case_mgr *ucm_create(const char *name)
if (!mgr)
return NULL;
- mgr->name = strdup(name);
- if (!mgr->name)
- goto cleanup;
-
rc = snd_use_case_mgr_open(&mgr->mgr, name);
if (rc) {
syslog(LOG_WARNING, "Can not open ucm for card %s, rc = %d",
@@ -426,8 +390,8 @@ struct cras_use_case_mgr *ucm_create(const char *name)
goto cleanup;
}
+ mgr->name = name;
mgr->avail_use_cases = 0;
- mgr->hotword_modifier = NULL;
num_verbs = snd_use_case_get_list(mgr->mgr, "_verbs", &list);
for (i = 0; i < num_verbs; i += 2) {
for (j = 0; j < CRAS_STREAM_NUM_TYPES; ++j) {
@@ -449,7 +413,6 @@ struct cras_use_case_mgr *ucm_create(const char *name)
cleanup_mgr:
snd_use_case_mgr_close(mgr->mgr);
cleanup:
- free(mgr->name);
free(mgr);
return NULL;
}
@@ -457,8 +420,6 @@ cleanup:
void ucm_destroy(struct cras_use_case_mgr *mgr)
{
snd_use_case_mgr_close(mgr->mgr);
- free(mgr->hotword_modifier);
- free(mgr->name);
free(mgr);
}
@@ -515,63 +476,12 @@ int ucm_enable_swap_mode(struct cras_use_case_mgr *mgr, const char *node_name,
return rc;
}
-int ucm_node_noise_cancellation_exists(struct cras_use_case_mgr *mgr,
- const char *node_name)
-{
- char *node_modifier_name = NULL;
- int exists;
-
- node_modifier_name = (char *)malloc(max_section_name_len);
- if (!node_modifier_name)
- return 0;
- ucm_get_node_noise_cancellation_name(node_name, node_modifier_name);
- exists = ucm_mod_exists_with_name(mgr, node_modifier_name);
- free((void *)node_modifier_name);
- return exists;
-}
-
-int ucm_enable_node_noise_cancellation(struct cras_use_case_mgr *mgr,
- const char *node_name, int enable)
-{
- char *node_modifier_name = NULL;
- int rc;
-
- node_modifier_name = (char *)malloc(max_section_name_len);
- if (!node_modifier_name)
- return -ENOMEM;
- ucm_get_node_noise_cancellation_name(node_name, node_modifier_name);
- if (!ucm_mod_exists_with_name(mgr, node_modifier_name)) {
- syslog(LOG_ERR, "Can not find modifier %s.",
- node_modifier_name);
- free((void *)node_modifier_name);
- return -EPERM;
- }
- if (modifier_enabled(mgr, node_modifier_name) == !!enable) {
- syslog(LOG_DEBUG, "Modifier %s is already %s.",
- node_modifier_name, enable ? "enabled" : "disabled");
- free((void *)node_modifier_name);
- return 0;
- }
-
- syslog(LOG_DEBUG, "UCM %s Modifier %s", enable ? "enable" : "disable",
- node_modifier_name);
- rc = ucm_set_modifier_enabled(mgr, node_modifier_name, enable);
- free((void *)node_modifier_name);
- return rc;
-}
-
int ucm_set_enabled(struct cras_use_case_mgr *mgr, const char *dev, int enable)
{
- int rc;
if (device_enabled(mgr, dev) == !!enable)
return 0;
syslog(LOG_DEBUG, "UCM %s %s", enable ? "enable" : "disable", dev);
- rc = snd_use_case_set(mgr->mgr, enable ? "_enadev" : "_disdev", dev);
- if (rc && (rc != -ENOENT || ucm_has_fully_specified_ucm_flag(mgr))) {
- syslog(LOG_ERR, "Can not %s UCM for device %s, rc = %d",
- enable ? "enable" : "disable", dev, rc);
- }
- return rc;
+ return snd_use_case_set(mgr->mgr, enable ? "_enadev" : "_disdev", dev);
}
char *ucm_get_flag(struct cras_use_case_mgr *mgr, const char *flag_name)
@@ -605,10 +515,33 @@ char *ucm_get_cap_control(struct cras_use_case_mgr *mgr, const char *ucm_dev)
return control_name;
}
-inline const char *ucm_get_override_type_name(struct cras_use_case_mgr *mgr,
- const char *dev)
+char *ucm_get_mic_positions(struct cras_use_case_mgr *mgr)
{
- return ucm_get_value_for_dev(mgr, override_type_name_var, dev);
+ char *control_name = NULL;
+ const char *value;
+ int rc;
+
+ rc = get_var(mgr, mic_positions, "", uc_verb(mgr), &value);
+ if (!rc) {
+ control_name = strdup(value);
+ free((void *)value);
+ }
+
+ return control_name;
+}
+
+const char *ucm_get_override_type_name(struct cras_use_case_mgr *mgr,
+ const char *dev)
+{
+ const char *override_type_name;
+ int rc;
+
+ rc = get_var(mgr, override_type_name_var, dev, uc_verb(mgr),
+ &override_type_name);
+ if (rc)
+ return NULL;
+
+ return override_type_name;
}
char *ucm_get_dev_for_jack(struct cras_use_case_mgr *mgr, const char *jack,
@@ -617,8 +550,7 @@ char *ucm_get_dev_for_jack(struct cras_use_case_mgr *mgr, const char *jack,
struct section_name *section_names, *c;
char *ret = NULL;
- section_names =
- ucm_get_devices_for_var(mgr, jack_dev_var, jack, direction);
+ section_names = ucm_get_devices_for_var(mgr, jack_var, jack, direction);
DL_FOREACH (section_names, c) {
if (!strcmp(c->name, "Mic")) {
@@ -646,16 +578,10 @@ char *ucm_get_dev_for_jack(struct cras_use_case_mgr *mgr, const char *jack,
char *ucm_get_dev_for_mixer(struct cras_use_case_mgr *mgr, const char *mixer,
enum CRAS_STREAM_DIRECTION dir)
{
- struct section_name *section_names = NULL, *c;
+ struct section_name *section_names, *c;
char *ret = NULL;
- if (dir == CRAS_STREAM_OUTPUT) {
- section_names = ucm_get_devices_for_var(
- mgr, playback_mixer_elem_var, mixer, dir);
- } else if (dir == CRAS_STREAM_INPUT) {
- section_names = ucm_get_devices_for_var(
- mgr, capture_mixer_elem_var, mixer, dir);
- }
+ section_names = ucm_get_devices_for_var(mgr, mixer_var, mixer, dir);
if (section_names)
ret = strdup(section_names->name);
@@ -669,16 +595,46 @@ char *ucm_get_dev_for_mixer(struct cras_use_case_mgr *mgr, const char *mixer,
return ret;
}
-inline const char *ucm_get_edid_file_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
+const char *ucm_get_edid_file_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
+{
+ const char *file_name;
+ int rc;
+
+ rc = get_var(mgr, edid_var, dev, uc_verb(mgr), &file_name);
+ if (rc)
+ return NULL;
+
+ return file_name;
+}
+
+const char *ucm_get_dsp_name_default(struct cras_use_case_mgr *mgr,
+ int direction)
{
- return ucm_get_value_for_dev(mgr, edid_var, dev);
+ const char *var = (direction == CRAS_STREAM_OUTPUT) ?
+ output_dsp_name_var :
+ input_dsp_name_var;
+ const char *dsp_name = NULL;
+ int rc;
+
+ rc = get_var(mgr, var, "", uc_verb(mgr), &dsp_name);
+ if (rc)
+ return NULL;
+
+ return dsp_name;
}
-inline const char *ucm_get_dsp_name_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
+const char *ucm_get_dsp_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
{
- return ucm_get_value_for_dev(mgr, dsp_name_var, dev);
+ const char *dsp_name = NULL;
+ int rc;
+
+ rc = get_var(mgr, dsp_name_var, dev, uc_verb(mgr), &dsp_name);
+ if (rc)
+ return NULL;
+
+ return dsp_name;
}
int ucm_get_min_buffer_level(struct cras_use_case_mgr *mgr, unsigned int *level)
@@ -706,29 +662,42 @@ unsigned int ucm_get_disable_software_volume(struct cras_use_case_mgr *mgr)
return value;
}
-int ucm_get_default_node_gain(struct cras_use_case_mgr *mgr, const char *dev,
+int ucm_get_min_software_gain(struct cras_use_case_mgr *mgr, const char *dev,
long *gain)
{
int value;
int rc;
- rc = get_int(mgr, default_node_gain, dev, uc_verb(mgr), &value);
+ rc = get_int(mgr, min_software_gain, dev, uc_verb(mgr), &value);
+ if (rc)
+ return rc;
+ *gain = value;
+ return 0;
+}
+
+int ucm_get_max_software_gain(struct cras_use_case_mgr *mgr, const char *dev,
+ long *gain)
+{
+ int value;
+ int rc;
+
+ rc = get_int(mgr, max_software_gain, dev, uc_verb(mgr), &value);
if (rc)
return rc;
*gain = value;
return 0;
}
-int ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr *mgr,
- const char *dev, long *sensitivity)
+int ucm_get_default_node_gain(struct cras_use_case_mgr *mgr, const char *dev,
+ long *gain)
{
int value;
int rc;
- rc = get_int(mgr, intrinsic_sensitivity_var, dev, uc_verb(mgr), &value);
+ rc = get_int(mgr, default_node_gain, dev, uc_verb(mgr), &value);
if (rc)
return rc;
- *sensitivity = value;
+ *gain = value;
return 0;
}
@@ -743,31 +712,29 @@ int ucm_get_preempt_hotword(struct cras_use_case_mgr *mgr, const char *dev)
return value;
}
-static int get_device_index_from_target(const char *target_device_name);
-
-int ucm_get_alsa_dev_idx_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
- enum CRAS_STREAM_DIRECTION direction)
+const char *ucm_get_device_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev,
+ enum CRAS_STREAM_DIRECTION direction)
{
- const char *pcm_name = NULL;
- int dev_idx = -1;
-
if (direction == CRAS_STREAM_OUTPUT)
- pcm_name = ucm_get_playback_device_name_for_dev(mgr, dev);
+ return ucm_get_playback_device_name_for_dev(mgr, dev);
else if (direction == CRAS_STREAM_INPUT)
- pcm_name = ucm_get_capture_device_name_for_dev(mgr, dev);
-
- if (pcm_name) {
- dev_idx = get_device_index_from_target(pcm_name);
- free((void *)pcm_name);
- }
- return dev_idx;
+ return ucm_get_capture_device_name_for_dev(mgr, dev);
+ return NULL;
}
-inline const char *
+const char *
ucm_get_echo_reference_dev_name_for_dev(struct cras_use_case_mgr *mgr,
const char *dev)
{
- return ucm_get_value_for_dev(mgr, echo_reference_dev_name_var, dev);
+ const char *name = NULL;
+ int rc;
+
+ rc = get_var(mgr, echo_reference_dev_name_var, dev, uc_verb(mgr),
+ &name);
+ if (rc)
+ return NULL;
+ return name;
}
int ucm_get_sample_rate_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
@@ -791,31 +758,6 @@ int ucm_get_sample_rate_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
return value;
}
-int ucm_get_channels_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
- enum CRAS_STREAM_DIRECTION direction,
- size_t *channels)
-{
- int value;
- int rc;
- const char *var_name;
-
- if (direction == CRAS_STREAM_OUTPUT)
- var_name = playback_channels_var;
- else if (direction == CRAS_STREAM_INPUT)
- var_name = capture_channels_var;
- else
- return -EINVAL;
-
- rc = get_int(mgr, var_name, dev, uc_verb(mgr), &value);
- if (rc)
- return rc;
- if (value < 0)
- return -1;
-
- *channels = (size_t)value;
- return 0;
-}
-
int ucm_get_capture_chmap_for_dev(struct cras_use_case_mgr *mgr,
const char *dev, int8_t *channel_layout)
{
@@ -861,125 +803,10 @@ static int get_device_index_from_target(const char *target_device_name)
return -1;
}
-static const char *ucm_get_dir_for_device(struct cras_use_case_mgr *mgr,
- const char *dev_name,
- enum CRAS_STREAM_DIRECTION *dir)
-{
- const char *pcm_name;
-
- pcm_name = ucm_get_playback_device_name_for_dev(mgr, dev_name);
-
- if (pcm_name) {
- *dir = CRAS_STREAM_OUTPUT;
- return pcm_name;
- }
-
- pcm_name = ucm_get_capture_device_name_for_dev(mgr, dev_name);
- if (pcm_name) {
- *dir = CRAS_STREAM_INPUT;
- return pcm_name;
- }
-
- *dir = CRAS_STREAM_UNDEFINED;
- return NULL;
-}
-
-static int ucm_parse_device_section(struct cras_use_case_mgr *mgr,
- const char *dev,
- struct ucm_section **sections)
-{
- enum CRAS_STREAM_DIRECTION dir;
- int dev_idx = -1;
- int dependent_dev_idx = -1;
- const char *jack_name = NULL;
- const char *jack_type = NULL;
- const char *jack_dev = NULL;
- const char *jack_control = NULL;
- const char *mixer_name = NULL;
- struct mixer_name *m_name;
- int rc = 0;
- const char *pcm_name;
- const char *dependent_dev_name = NULL;
- struct ucm_section *dev_sec;
- const char *dev_name;
-
- dev_name = strdup(dev);
- if (!dev_name)
- return 0;
-
- pcm_name = ucm_get_dir_for_device(mgr, dev_name, &dir);
-
- if (pcm_name)
- dev_idx = get_device_index_from_target(pcm_name);
-
- if (dir == CRAS_STREAM_UNDEFINED) {
- syslog(LOG_ERR,
- "UCM configuration for device '%s' missing"
- " PlaybackPCM or CapturePCM definition.",
- dev_name);
- rc = -EINVAL;
- goto error_cleanup;
- }
-
- dependent_dev_name =
- ucm_get_dependent_device_name_for_dev(mgr, dev_name);
- if (dependent_dev_name) {
- dependent_dev_idx =
- get_device_index_from_target(dependent_dev_name);
- }
-
- jack_dev = ucm_get_jack_dev_for_dev(mgr, dev_name);
- jack_control = ucm_get_jack_control_for_dev(mgr, dev_name);
- if (dir == CRAS_STREAM_OUTPUT)
- mixer_name = ucm_get_playback_mixer_elem_for_dev(mgr, dev_name);
- else if (dir == CRAS_STREAM_INPUT)
- mixer_name = ucm_get_capture_mixer_elem_for_dev(mgr, dev_name);
-
- if (jack_dev) {
- jack_name = jack_dev;
- jack_type = "gpio";
- } else if (jack_control) {
- jack_name = jack_control;
- jack_type = "hctl";
- }
-
- dev_sec = ucm_section_create(dev_name, pcm_name, dev_idx,
- dependent_dev_idx, dir, jack_name,
- jack_type);
-
- if (!dev_sec) {
- syslog(LOG_ERR, "Failed to allocate memory.");
- rc = -ENOMEM;
- goto error_cleanup;
- }
-
- dev_sec->jack_switch = ucm_get_jack_switch_for_dev(mgr, dev_name);
-
- if (mixer_name) {
- rc = ucm_section_set_mixer_name(dev_sec, mixer_name);
- if (rc)
- goto error_cleanup;
- }
-
- m_name = ucm_get_mixer_names(mgr, dev_name, coupled_mixers, dir,
- MIXER_NAME_VOLUME);
- ucm_section_concat_coupled(dev_sec, m_name);
-
- DL_APPEND(*sections, dev_sec);
- ucm_section_dump(dev_sec);
-error_cleanup:
- free((void *)dev_name);
- free((void *)dependent_dev_name);
- free((void *)jack_dev);
- free((void *)jack_control);
- free((void *)mixer_name);
- free((void *)pcm_name);
- return rc;
-}
-
struct ucm_section *ucm_get_sections(struct cras_use_case_mgr *mgr)
{
struct ucm_section *sections = NULL;
+ struct ucm_section *dev_sec;
const char **list;
int num_devs;
int i;
@@ -993,17 +820,101 @@ struct ucm_section *ucm_get_sections(struct cras_use_case_mgr *mgr)
/* snd_use_case_get_list fills list with pairs of device name and
* comment, so device names are in even-indexed elements. */
+ const char *dev_name;
for (i = 0; i < num_devs; i += 2) {
- if (ucm_parse_device_section(mgr, list[i], &sections) < 0) {
- ucm_section_free_list(sections);
- sections = NULL;
- break;
+ enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_UNDEFINED;
+ int dev_idx = -1;
+ const char *jack_name;
+ const char *jack_type;
+ const char *mixer_name;
+ struct mixer_name *m_name;
+ int rc;
+ const char *target_device_name;
+
+ dev_name = strdup(list[i]);
+ if (!dev_name)
+ continue;
+
+ target_device_name =
+ ucm_get_playback_device_name_for_dev(mgr, dev_name);
+ if (target_device_name)
+ dir = CRAS_STREAM_OUTPUT;
+ else {
+ target_device_name =
+ ucm_get_capture_device_name_for_dev(mgr,
+ dev_name);
+ if (target_device_name)
+ dir = CRAS_STREAM_INPUT;
+ }
+ if (target_device_name) {
+ dev_idx = get_device_index_from_target(
+ target_device_name);
+ free((void *)target_device_name);
+ }
+
+ if (dir == CRAS_STREAM_UNDEFINED) {
+ syslog(LOG_ERR,
+ "UCM configuration for device '%s' missing"
+ " PlaybackPCM or CapturePCM definition.",
+ dev_name);
+ goto error_cleanup;
+ }
+
+ if (dev_idx == -1) {
+ syslog(LOG_ERR,
+ "PlaybackPCM or CapturePCM for '%s' must be in"
+ " the form 'hw:<card>,<number>'",
+ dev_name);
+ goto error_cleanup;
+ }
+
+ jack_name = ucm_get_jack_name_for_dev(mgr, dev_name);
+ jack_type = ucm_get_jack_type_for_dev(mgr, dev_name);
+ mixer_name = ucm_get_mixer_name_for_dev(mgr, dev_name);
+
+ dev_sec = ucm_section_create(dev_name, dev_idx, dir, jack_name,
+ jack_type);
+ if (jack_name)
+ free((void *)jack_name);
+ if (jack_type)
+ free((void *)jack_type);
+
+ if (!dev_sec) {
+ syslog(LOG_ERR, "Failed to allocate memory.");
+ if (mixer_name)
+ free((void *)mixer_name);
+ goto error_cleanup;
+ }
+
+ dev_sec->jack_switch =
+ ucm_get_jack_switch_for_dev(mgr, dev_name);
+
+ if (mixer_name) {
+ rc = ucm_section_set_mixer_name(dev_sec, mixer_name);
+ free((void *)mixer_name);
+ if (rc)
+ goto error_cleanup;
}
+
+ m_name = ucm_get_mixer_names(mgr, dev_name, coupled_mixers, dir,
+ MIXER_NAME_VOLUME);
+ ucm_section_concat_coupled(dev_sec, m_name);
+
+ DL_APPEND(sections, dev_sec);
+ ucm_section_dump(dev_sec);
+ free((void *)dev_name);
}
if (num_devs > 0)
snd_use_case_free_list(list, num_devs);
return sections;
+
+error_cleanup:
+ if (num_devs > 0)
+ snd_use_case_free_list(list, num_devs);
+ ucm_section_free_list(sections);
+ free((void *)dev_name);
+ return NULL;
}
char *ucm_get_hotword_models(struct cras_use_case_mgr *mgr)
@@ -1057,61 +968,14 @@ char *ucm_get_hotword_models(struct cras_use_case_mgr *mgr)
return models;
}
-void ucm_disable_all_hotword_models(struct cras_use_case_mgr *mgr)
+int ucm_set_hotword_model(struct cras_use_case_mgr *mgr, const char *model)
{
const char **list;
int num_enmods, mod_idx;
-
- if (!mgr)
- return;
-
- /* Disable all currently enabled hotword model modifiers. */
- num_enmods = snd_use_case_get_list(mgr->mgr, "_enamods", &list);
- if (num_enmods <= 0)
- return;
-
- for (mod_idx = 0; mod_idx < num_enmods; mod_idx++) {
- if (!strncmp(list[mod_idx], hotword_model_prefix,
- strlen(hotword_model_prefix)))
- ucm_set_modifier_enabled(mgr, list[mod_idx], 0);
- }
- snd_use_case_free_list(list, num_enmods);
-}
-
-int ucm_enable_hotword_model(struct cras_use_case_mgr *mgr)
-{
- if (mgr->hotword_modifier)
- return ucm_set_modifier_enabled(mgr, mgr->hotword_modifier, 1);
- return -EINVAL;
-}
-
-static int ucm_is_modifier_enabled(struct cras_use_case_mgr *mgr,
- char *modifier, long *value)
-{
- int rc;
- char *id;
- size_t len = strlen(modifier) + 11 + 1;
-
- id = (char *)malloc(len);
-
- if (!id)
- return -ENOMEM;
-
- snprintf(id, len, "_modstatus/%s", modifier);
- rc = snd_use_case_geti(mgr->mgr, id, value);
- free(id);
- return rc;
-}
-
-int ucm_set_hotword_model(struct cras_use_case_mgr *mgr, const char *model)
-{
- char *model_mod;
- long mod_status = 0;
+ char *model_mod = NULL;
size_t model_mod_size =
strlen(model) + 1 + strlen(hotword_model_prefix) + 1;
-
model_mod = (char *)malloc(model_mod_size);
-
if (!model_mod)
return -ENOMEM;
snprintf(model_mod, model_mod_size, "%s %s", hotword_model_prefix,
@@ -1121,16 +985,21 @@ int ucm_set_hotword_model(struct cras_use_case_mgr *mgr, const char *model)
return -EINVAL;
}
- /* If check failed, just move on, dont fail incoming model */
- if (mgr->hotword_modifier)
- ucm_is_modifier_enabled(mgr, mgr->hotword_modifier,
- &mod_status);
+ /* Disable all currently enabled horword model modifiers. */
+ num_enmods = snd_use_case_get_list(mgr->mgr, "_enamods", &list);
+ if (num_enmods <= 0)
+ goto enable_mod;
+
+ for (mod_idx = 0; mod_idx < num_enmods; mod_idx++) {
+ if (!strncmp(list[mod_idx], hotword_model_prefix,
+ strlen(hotword_model_prefix)))
+ ucm_set_modifier_enabled(mgr, list[mod_idx], 0);
+ }
+ snd_use_case_free_list(list, num_enmods);
- ucm_disable_all_hotword_models(mgr);
- free(mgr->hotword_modifier);
- mgr->hotword_modifier = model_mod;
- if (mod_status)
- return ucm_enable_hotword_model(mgr);
+enable_mod:
+ ucm_set_modifier_enabled(mgr, model_mod, 1);
+ free((void *)model_mod);
return 0;
}
@@ -1146,18 +1015,17 @@ int ucm_has_fully_specified_ucm_flag(struct cras_use_case_mgr *mgr)
return ret;
}
-inline const char *
-ucm_get_playback_mixer_elem_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
+const char *ucm_get_mixer_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
{
- return ucm_get_value_for_dev(mgr, playback_mixer_elem_var, dev);
-}
+ const char *name = NULL;
+ int rc;
-inline const char *
-ucm_get_capture_mixer_elem_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
-{
- return ucm_get_value_for_dev(mgr, capture_mixer_elem_var, dev);
+ rc = get_var(mgr, mixer_var, dev, uc_verb(mgr), &name);
+ if (rc)
+ return NULL;
+
+ return name;
}
struct mixer_name *ucm_get_main_volume_names(struct cras_use_case_mgr *mgr)
@@ -1203,16 +1071,37 @@ int ucm_list_section_devices_by_device_name(
return listed;
}
-inline const char *ucm_get_jack_control_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
+const char *ucm_get_jack_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
{
- return ucm_get_value_for_dev(mgr, jack_control_var, dev);
+ const char *name = NULL;
+ int rc;
+
+ rc = get_var(mgr, jack_var, dev, uc_verb(mgr), &name);
+ if (rc)
+ return NULL;
+
+ return name;
}
-inline const char *ucm_get_jack_dev_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev)
+const char *ucm_get_jack_type_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev)
{
- return ucm_get_value_for_dev(mgr, jack_dev_var, dev);
+ const char *name = NULL;
+ int rc;
+
+ rc = get_var(mgr, jack_type_var, dev, uc_verb(mgr), &name);
+ if (rc)
+ return NULL;
+
+ if (strcmp(name, "hctl") && strcmp(name, "gpio") &&
+ strcmp(name, "always")) {
+ syslog(LOG_ERR, "Unknown jack type: %s", name);
+ if (name)
+ free((void *)name);
+ return NULL;
+ }
+ return name;
}
int ucm_get_jack_switch_for_dev(struct cras_use_case_mgr *mgr, const char *dev)
@@ -1235,3 +1124,15 @@ unsigned int ucm_get_dma_period_for_dev(struct cras_use_case_mgr *mgr,
return 0;
return value;
}
+
+unsigned int ucm_get_enable_htimestamp_flag(struct cras_use_case_mgr *mgr)
+{
+ char *flag;
+ int ret = 0;
+ flag = ucm_get_flag(mgr, enable_htimestamp_var);
+ if (!flag)
+ return 0;
+ ret = !strcmp(flag, "1");
+ free(flag);
+ return ret;
+}
diff --git a/cras/src/server/cras_alsa_ucm.h b/cras/src/server/cras_alsa_ucm.h
index 55c3cf62..36f68a01 100644
--- a/cras/src/server/cras_alsa_ucm.h
+++ b/cras/src/server/cras_alsa_ucm.h
@@ -67,28 +67,6 @@ int ucm_swap_mode_exists(struct cras_use_case_mgr *mgr);
int ucm_enable_swap_mode(struct cras_use_case_mgr *mgr, const char *node_name,
int enable);
-/* Checks if modifier of noise cancellation for given node_name exists in ucm.
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * node_name - The node name.
- * Returns:
- * 1 if it exists, 0 otherwise.
- */
-int ucm_node_noise_cancellation_exists(struct cras_use_case_mgr *mgr,
- const char *node_name);
-
-/* Enables or disables noise cancellation for the given node_name. First checks
- * if the modifier is already enabled or disabled.
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * node_name - The node name.
- * enable - Enable device if non-zero.
- * Returns:
- * 0 on success or negative error code on failure.
- */
-int ucm_enable_node_noise_cancellation(struct cras_use_case_mgr *mgr,
- const char *node_name, int enable);
-
/* Enables or disables a UCM device. First checks if the device is already
* enabled or disabled.
* Args:
@@ -120,6 +98,15 @@ char *ucm_get_flag(struct cras_use_case_mgr *mgr, const char *flag_name);
*/
char *ucm_get_cap_control(struct cras_use_case_mgr *mgr, const char *ucm_dev);
+/* Gets the mic positions string for internal mic.
+ * Args:
+ * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
+ * Returns:
+ * A pointer to the allocated string containing the mic positions
+ * information, or NULL if not specified.
+ */
+char *ucm_get_mic_positions(struct cras_use_case_mgr *mgr);
+
/* Gets the new node type name which user wants to override the old one for
* given ucm device.
* Args:
@@ -168,6 +155,17 @@ char *ucm_get_dev_for_mixer(struct cras_use_case_mgr *mgr, const char *mixer,
const char *ucm_get_edid_file_for_dev(struct cras_use_case_mgr *mgr,
const char *dev);
+/* Gets the default dsp name.
+ * Args:
+ * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
+ * direction - playback(CRAS_STREAM_OUTPUT) or capture(CRAS_STREAM_INPUT).
+ * Returns:
+ * A pointer to the allocated string containing the default dsp name, or
+ * NULL if no default dsp name is found.
+ */
+const char *ucm_get_dsp_name_default(struct cras_use_case_mgr *mgr,
+ int direction);
+
/* Gets the dsp name which is associated with the given ucm device.
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
@@ -198,27 +196,38 @@ int ucm_get_min_buffer_level(struct cras_use_case_mgr *mgr,
*/
unsigned int ucm_get_disable_software_volume(struct cras_use_case_mgr *mgr);
-/* Gets the value for default node gain.
+/* Gets the value for minimum software gain.
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to check for default node gain.
- * gain - The pointer to the returned value.
+ * dev - The device to check for minimum software gain.
+ * gain - The pointer to the returned value;
* Returns:
* 0 on success, other error codes on failure.
*/
-int ucm_get_default_node_gain(struct cras_use_case_mgr *mgr, const char *dev,
+int ucm_get_min_software_gain(struct cras_use_case_mgr *mgr, const char *dev,
long *gain);
-/* Gets the value for intrinsic sensitivity.
+/* Gets the value for maximum software gain.
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to query for intrinsic volume.
- * sensitivity - The pointer to the returned value.
+ * dev - The device to check for maximum software gain.
+ * gain - The pointer to the returned value;
* Returns:
* 0 on success, other error codes on failure.
*/
-int ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr *mgr,
- const char *dev, long *sensitivity);
+int ucm_get_max_software_gain(struct cras_use_case_mgr *mgr, const char *dev,
+ long *gain);
+
+/* Gets the value for default node gain.
+ * Args:
+ * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
+ * dev - The device to check for default node gain.
+ * gain - The pointer to the returned value;
+ * Returns:
+ * 0 on success, other error codes on failure.
+ */
+int ucm_get_default_node_gain(struct cras_use_case_mgr *mgr, const char *dev,
+ long *gain);
/* Gets the flag if an input device can preempt hotword recording.
* Args:
@@ -230,19 +239,20 @@ int ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr *mgr,
*/
int ucm_get_preempt_hotword(struct cras_use_case_mgr *mgr, const char *dev);
-/* Gets the ALSA device index on the card for given UCM dev.
+/* Gets the device name of this device on the card..
*
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The UCM device to check for ALSA device index.
+ * dev - The device to check for device name
* direction - playback(CRAS_STREAM_OUTPUT) or capture(CRAS_STREAM_INPUT).
* Returns:
- * Non-negative integer for the ALSA device index on the card, -1 if not
- * found. The ALSA device index is parsed from the PCM name which is
- * formatted as "hw:<some-name>,<idx>".
+ * A pointer to the allocated string containing the device name, or NULL
+ * if no device name is found. The device name is of format
+ * "card_name:device_index".
*/
-int ucm_get_alsa_dev_idx_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
- enum CRAS_STREAM_DIRECTION direction);
+const char *ucm_get_device_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev,
+ enum CRAS_STREAM_DIRECTION direction);
/* Gets the node name of the echo reference device on the card.
* Args:
@@ -269,20 +279,6 @@ ucm_get_echo_reference_dev_name_for_dev(struct cras_use_case_mgr *mgr,
int ucm_get_sample_rate_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
enum CRAS_STREAM_DIRECTION direction);
-/* Gets the channel count at which to run this device.
- *
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to check for channel count.
- * direction - playback(CRAS_STREAM_OUTPUT) or capture(CRAS_STREAM_INPUT).
- * channels - The pointer to the returned channel count.
- * Returns:
- * 0 on success, other error codes on failure.
- */
-int ucm_get_channels_for_dev(struct cras_use_case_mgr *mgr, const char *dev,
- enum CRAS_STREAM_DIRECTION direction,
- size_t *channels);
-
/* Gets the capture channel map for this device.
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
@@ -328,26 +324,11 @@ char *ucm_get_hotword_models(struct cras_use_case_mgr *mgr);
/* Sets the desired hotword model.
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * model - locale for model
* Returns:
* 0 on success or negative error code on failure.
*/
int ucm_set_hotword_model(struct cras_use_case_mgr *mgr, const char *model);
-/* Enable previously set hotword modifier
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * Returns:
- * 0 on success or negative error code on failure.
- */
-int ucm_enable_hotword_model(struct cras_use_case_mgr *mgr);
-
-/* Disable all hotword model modifiers
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- */
-void ucm_disable_all_hotword_models(struct cras_use_case_mgr *mgr);
-
/* Checks if this card has fully specified UCM config.
*
* Args:
@@ -357,19 +338,7 @@ void ucm_disable_all_hotword_models(struct cras_use_case_mgr *mgr);
*/
int ucm_has_fully_specified_ucm_flag(struct cras_use_case_mgr *mgr);
-/* Gets the playback mixer name of this device on the card.
- *
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to check for device name
- * Returns:
- * A pointer to the allocated string containing the mixer name, or NULL
- * if no device name is found.
- */
-const char *ucm_get_playback_mixer_elem_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev);
-
-/* Gets the capture mixer name of this device on the card.
+/* Gets the mixer name of this device on the card.
*
* Args:
* mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
@@ -378,8 +347,8 @@ const char *ucm_get_playback_mixer_elem_for_dev(struct cras_use_case_mgr *mgr,
* A pointer to the allocated string containing the mixer name, or NULL
* if no device name is found.
*/
-const char *ucm_get_capture_mixer_elem_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev);
+const char *ucm_get_mixer_name_for_dev(struct cras_use_case_mgr *mgr,
+ const char *dev);
/* Gets the mixer names for the main volume controls on the card.
*
@@ -450,30 +419,6 @@ const char *ucm_get_jack_name_for_dev(struct cras_use_case_mgr *mgr,
const char *ucm_get_jack_type_for_dev(struct cras_use_case_mgr *mgr,
const char *dev);
-/* Gets the jack dev of this device on the card.
- *
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to check for jack name.
- * Returns:
- * A pointer to the allocated string containing the input jack name, or NULL
- * if no jack name is found.
- */
-const char *ucm_get_jack_dev_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev);
-
-/* Gets the jack control of this device on the card.
- *
- * Args:
- * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
- * dev - The device to check for jack type.
- * Returns:
- * A pointer to the allocated string containing the alsa jack name, or NULL
- * if no jack type is found or the found jack type is invalid.
- */
-const char *ucm_get_jack_control_for_dev(struct cras_use_case_mgr *mgr,
- const char *dev);
-
/* Gets the jack switch number for this device.
* Some sound cards can detect multiple types of connections into the
* audio jack - for example distinguish between line-out and headphones
@@ -509,4 +454,12 @@ unsigned int ucm_get_dma_period_for_dev(struct cras_use_case_mgr *mgr,
*/
unsigned int ucm_get_optimize_no_stream_flag(struct cras_use_case_mgr *mgr);
+/* Retrieve the flag that enables use of htimestamp.
+ * Args:
+ * mgr - The cras_use_case_mgr pointer returned from alsa_ucm_create.
+ * Returns:
+ * 1 if the flag is enabled. 0 otherwise.
+ */
+unsigned int ucm_get_enable_htimestamp_flag(struct cras_use_case_mgr *mgr);
+
#endif /* _CRAS_ALSA_UCM_H */
diff --git a/cras/src/server/cras_alsa_ucm_section.c b/cras/src/server/cras_alsa_ucm_section.c
index d4df8c7d..36d44220 100644
--- a/cras/src/server/cras_alsa_ucm_section.c
+++ b/cras/src/server/cras_alsa_ucm_section.c
@@ -13,11 +13,14 @@
static void ucm_section_free(struct ucm_section *section)
{
- free((void *)section->name);
- free((void *)section->pcm_name);
- free((void *)section->jack_name);
- free((void *)section->jack_type);
- free((void *)section->mixer_name);
+ if (section->name)
+ free((void *)section->name);
+ if (section->jack_name)
+ free((void *)section->jack_name);
+ if (section->jack_type)
+ free((void *)section->jack_type);
+ if (section->mixer_name)
+ free((void *)section->mixer_name);
mixer_name_free(section->coupled);
free(section);
}
@@ -31,8 +34,7 @@ void ucm_section_free_list(struct ucm_section *sections)
}
}
-struct ucm_section *ucm_section_create(const char *name, const char *pcm_name,
- int dev_idx, int dependent_dev_idx,
+struct ucm_section *ucm_section_create(const char *name, int dev_idx,
enum CRAS_STREAM_DIRECTION dir,
const char *jack_name,
const char *jack_type)
@@ -48,16 +50,11 @@ struct ucm_section *ucm_section_create(const char *name, const char *pcm_name,
return NULL;
section->dev_idx = dev_idx;
- section->dependent_dev_idx = dependent_dev_idx;
section->dir = dir;
section->name = strdup(name);
if (!section->name)
goto error;
- section->pcm_name = strdup(pcm_name);
- if (!section->pcm_name)
- goto error;
-
if (jack_name) {
section->jack_name = strdup(jack_name);
if (!section->jack_name)
diff --git a/cras/src/server/cras_alsa_ucm_section.h b/cras/src/server/cras_alsa_ucm_section.h
index 77c5ed89..0ffa5ab4 100644
--- a/cras/src/server/cras_alsa_ucm_section.h
+++ b/cras/src/server/cras_alsa_ucm_section.h
@@ -17,12 +17,8 @@ extern "C" {
struct ucm_section {
/* Section name. */
const char *name;
- /* Value of PlaybackPCM or CapturePCM. */
- const char *pcm_name;
/* Device PCM index. */
int dev_idx;
- /* Device PCM index to associate this section to. */
- int dependent_dev_idx;
/* Output or Input. */
enum CRAS_STREAM_DIRECTION dir;
/* Associated jack's name. */
@@ -31,7 +27,7 @@ struct ucm_section {
const char *jack_type;
/* Switch number for jack from linux/input.h, or -1. */
int jack_switch;
- /* (Playback/Capture)MixerElem value. */
+ /* MixerName value. */
const char *mixer_name;
/* CoupledMixers value. */
struct mixer_name *coupled;
@@ -42,10 +38,7 @@ struct ucm_section {
*
* Args:
* name - Section name (must not be NULL).
- * pcm_name - PCM name used for snd_pcm_open.
* dev_idx - Section's device index (PCM number).
- * dependent_dev_idx - Another ALSA device index (PCM number) under which
- * we want to make this section a node.
* dir - Device direction: INPUT or OUTPUT.
* jack_name - Name of an associated jack (or NULL).
* jack_type - Type of the associated jack (or NULL).
@@ -53,8 +46,7 @@ struct ucm_section {
* Returns:
* A valid pointer on success, NULL for memory allocation error.
*/
-struct ucm_section *ucm_section_create(const char *name, const char *pcm_name,
- int dev_idx, int dependent_dev_idx,
+struct ucm_section *ucm_section_create(const char *name, int dev_idx,
enum CRAS_STREAM_DIRECTION dir,
const char *jack_name,
const char *jack_type);
diff --git a/cras/src/server/cras_apm_list.c b/cras/src/server/cras_apm_list.c
index ab891137..d0ea9a96 100644
--- a/cras/src/server/cras_apm_list.c
+++ b/cras/src/server/cras_apm_list.c
@@ -22,6 +22,8 @@
#include "iniparser_wrapper.h"
#include "utlist.h"
+static const unsigned int MAX_INI_NAME_LEN = 63;
+
#define AEC_CONFIG_NAME "aec.ini"
#define APM_CONFIG_NAME "apm.ini"
@@ -61,10 +63,6 @@
* stream.
* work_queue - A task queue instance created and destroyed by
* libwebrtc_apm.
- * is_aec_use_case - True if the input and output devices pair is in the
- * typical AEC use case. This flag decides whether to use settings
- * tuned specifically for this hardware if exists. Otherwise it uses
- * the generic settings like run inside browser.
*/
struct cras_apm {
webrtc_apm apm_ptr;
@@ -75,7 +73,6 @@ struct cras_apm {
struct cras_audio_format fmt;
struct cras_audio_area *area;
void *work_queue;
- bool is_aec_use_case;
struct cras_apm *prev, *next;
};
@@ -84,10 +81,6 @@ struct cras_apm {
* have more than one cras_apm when multiple input devices are
* enabled. The most common scenario is the silent input iodev be
* enabled when CRAS switches active input device.
- *
- * Note that cras_apm_list is owned and modified in main thread.
- * Only in synchronized audio thread event this cras_apm_list is safe
- * to access for passing single APM instance between threads.
*/
struct cras_apm_list {
void *stream_ptr;
@@ -97,22 +90,6 @@ struct cras_apm_list {
};
/*
- * Wrappers of APM instances that are active, which means it is associated
- * to a dev/stream pair in audio thread and ready for processing.
- *
- * Members:
- * apm - The APM for audio data processing.
- * stream_ptr - Stream pointer from the associated dev/stream pair.
- * effects - The effecets bit map of APM.
- */
-struct active_apm {
- struct cras_apm *apm;
- void *stream_ptr;
- int effects;
- struct active_apm *prev, *next;
-} * active_apms;
-
-/*
* Object used to analyze playback audio from output iodev. It is responsible
* to get buffer containing latest output data and provide it to the APM
* instances which want to analyze reverse stream.
@@ -135,8 +112,9 @@ struct cras_apm_reverse_module {
};
static struct cras_apm_reverse_module *rmodule = NULL;
+static struct cras_apm_list *apm_list = NULL;
static const char *aec_config_dir = NULL;
-static char ini_name[MAX_INI_NAME_LENGTH + 1];
+static char ini_name[MAX_INI_NAME_LEN + 1];
static dictionary *aec_ini = NULL;
static dictionary *apm_ini = NULL;
@@ -144,14 +122,14 @@ static dictionary *apm_ini = NULL;
* or removed. */
static void update_process_reverse_flag()
{
- struct active_apm *active;
+ struct cras_apm_list *list;
if (!rmodule)
return;
rmodule->process_reverse = 0;
- DL_FOREACH (active_apms, active) {
+ DL_FOREACH (apm_list, list) {
rmodule->process_reverse |=
- !!(active->effects & APM_ECHO_CANCELLATION);
+ !!(list->effects & APM_ECHO_CANCELLATION);
}
}
@@ -176,36 +154,33 @@ struct cras_apm_list *cras_apm_list_create(void *stream_ptr, uint64_t effects)
if (effects == 0)
return NULL;
+ DL_SEARCH_SCALAR(apm_list, list, stream_ptr, stream_ptr);
+ if (list)
+ return list;
+
list = (struct cras_apm_list *)calloc(1, sizeof(*list));
- if (list == NULL) {
- syslog(LOG_ERR, "No memory in creating apm list");
- return NULL;
- }
list->stream_ptr = stream_ptr;
list->effects = effects;
list->apms = NULL;
+ DL_APPEND(apm_list, list);
return list;
}
-static struct active_apm *get_active_apm(void *stream_ptr, void *dev_ptr)
+struct cras_apm *cras_apm_list_get(struct cras_apm_list *list, void *dev_ptr)
{
- struct active_apm *active;
+ struct cras_apm *apm;
+
+ if (list == NULL)
+ return NULL;
- DL_FOREACH (active_apms, active) {
- if ((active->apm->dev_ptr == dev_ptr) &&
- (active->stream_ptr == stream_ptr))
- return active;
+ DL_FOREACH (list->apms, apm) {
+ if (apm->dev_ptr == dev_ptr)
+ return apm;
}
return NULL;
}
-struct cras_apm *cras_apm_list_get_active_apm(void *stream_ptr, void *dev_ptr)
-{
- struct active_apm *active = get_active_apm(stream_ptr, dev_ptr);
- return active ? active->apm : NULL;
-}
-
uint64_t cras_apm_list_get_effects(struct cras_apm_list *list)
{
if (list == NULL)
@@ -214,7 +189,7 @@ uint64_t cras_apm_list_get_effects(struct cras_apm_list *list)
return list->effects;
}
-void cras_apm_list_remove_apm(struct cras_apm_list *list, void *dev_ptr)
+void cras_apm_list_remove(struct cras_apm_list *list, void *dev_ptr)
{
struct cras_apm *apm;
@@ -240,12 +215,13 @@ static void get_best_channels(struct cras_audio_format *apm_fmt)
int ch;
int8_t layout[CRAS_CH_MAX];
- /* Using the format from dev_fmt is dangerous because input device
- * could have wild configurations like unuse the 1st channel and
- * connects 2nd channel to the only mic. Data in the first channel
- * is what APM cares about so always construct a new channel layout
- * containing subset of original channels that matches either FL, FR,
- * or FC.
+ /* Assume device format has correct channel layout populated. */
+ if (apm_fmt->num_channels <= 2)
+ return;
+
+ /* If the device provides recording from more channels than we care
+ * about, construct a new channel layout containing subset of original
+ * channels that matches either FL, FR, or FC.
* TODO(hychao): extend the logic when we have a stream that wants
* to record channels like RR(rear right).
*/
@@ -264,10 +240,8 @@ static void get_best_channels(struct cras_audio_format *apm_fmt)
apm_fmt->channel_layout[ch] = layout[ch];
}
-struct cras_apm *cras_apm_list_add_apm(struct cras_apm_list *list,
- void *dev_ptr,
- const struct cras_audio_format *dev_fmt,
- bool is_aec_use_case)
+struct cras_apm *cras_apm_list_add(struct cras_apm_list *list, void *dev_ptr,
+ const struct cras_audio_format *dev_fmt)
{
struct cras_apm *apm;
@@ -288,23 +262,8 @@ struct cras_apm *cras_apm_list_add_apm(struct cras_apm_list *list,
apm->fmt = *dev_fmt;
get_best_channels(&apm->fmt);
- /* Use tuned settings only when the forward dev(capture) and reverse
- * dev(playback) both are in typical AEC use case. */
- apm->is_aec_use_case = is_aec_use_case;
- if (rmodule->odev) {
- apm->is_aec_use_case &=
- cras_iodev_is_aec_use_case(rmodule->odev->active_node);
- }
-
- /* Use the configs tuned specifically for internal device. Otherwise
- * just pass NULL so every other settings will be default. */
- apm->apm_ptr =
- apm->is_aec_use_case ?
- webrtc_apm_create(apm->fmt.num_channels,
- apm->fmt.frame_rate, aec_ini,
- apm_ini) :
- webrtc_apm_create(apm->fmt.num_channels,
- apm->fmt.frame_rate, NULL, NULL);
+ apm->apm_ptr = webrtc_apm_create(apm->fmt.num_channels,
+ apm->fmt.frame_rate, aec_ini, apm_ini);
if (apm->apm_ptr == NULL) {
syslog(LOG_ERR,
"Fail to create webrtc apm for ch %zu"
@@ -327,59 +286,25 @@ struct cras_apm *cras_apm_list_add_apm(struct cras_apm_list *list,
cras_audio_area_config_channels(apm->area, &apm->fmt);
DL_APPEND(list->apms, apm);
+ update_process_reverse_flag();
return apm;
}
-void cras_apm_list_start_apm(struct cras_apm_list *list, void *dev_ptr)
+int cras_apm_list_destroy(struct cras_apm_list *list)
{
- struct active_apm *active;
+ struct cras_apm_list *tmp;
struct cras_apm *apm;
- if (list == NULL)
- return;
-
- /* Check if this apm has already been started. */
- apm = cras_apm_list_get_active_apm(list->stream_ptr, dev_ptr);
- if (apm)
- return;
-
- DL_SEARCH_SCALAR(list->apms, apm, dev_ptr, dev_ptr);
- if (apm == NULL)
- return;
-
- active = (struct active_apm *)calloc(1, sizeof(*active));
- if (active == NULL) {
- syslog(LOG_ERR, "No memory to start apm.");
- return;
- }
- active->apm = apm;
- active->stream_ptr = list->stream_ptr;
- active->effects = list->effects;
- DL_APPEND(active_apms, active);
-
- update_process_reverse_flag();
-}
-
-void cras_apm_list_stop_apm(struct cras_apm_list *list, void *dev_ptr)
-{
- struct active_apm *active;
-
- if (list == NULL)
- return;
-
- active = get_active_apm(list->stream_ptr, dev_ptr);
- if (active) {
- DL_DELETE(active_apms, active);
- free(active);
+ DL_FOREACH (apm_list, tmp) {
+ if (tmp == list) {
+ DL_DELETE(apm_list, tmp);
+ break;
+ }
}
- update_process_reverse_flag();
-}
-
-int cras_apm_list_destroy(struct cras_apm_list *list)
-{
- struct cras_apm *apm;
+ if (tmp == NULL)
+ return 0;
DL_FOREACH (list->apms, apm) {
DL_DELETE(list->apms, apm);
@@ -387,6 +312,8 @@ int cras_apm_list_destroy(struct cras_apm_list *list)
}
free(list);
+ update_process_reverse_flag();
+
return 0;
}
@@ -462,7 +389,8 @@ static void handle_device_disabled(struct cras_iodev *iodev, void *cb_data)
static int process_reverse(struct float_buffer *fbuf, unsigned int frame_rate)
{
- struct active_apm *active;
+ struct cras_apm_list *list;
+ struct cras_apm *apm;
int ret;
float *const *wp;
@@ -471,16 +399,18 @@ static int process_reverse(struct float_buffer *fbuf, unsigned int frame_rate)
wp = float_buffer_write_pointer(fbuf);
- DL_FOREACH (active_apms, active) {
- if (!(active->effects & APM_ECHO_CANCELLATION))
+ DL_FOREACH (apm_list, list) {
+ if (!(list->effects & APM_ECHO_CANCELLATION))
continue;
- ret = webrtc_apm_process_reverse_stream_f(active->apm->apm_ptr,
- fbuf->num_channels,
- frame_rate, wp);
- if (ret) {
- syslog(LOG_ERR, "APM process reverse err");
- return ret;
+ DL_FOREACH (list->apms, apm) {
+ ret = webrtc_apm_process_reverse_stream_f(
+ apm->apm_ptr, fbuf->num_channels, frame_rate,
+ wp);
+ if (ret) {
+ syslog(LOG_ERR, "APM process reverse err");
+ return ret;
+ }
}
}
float_buffer_reset(fbuf);
@@ -527,9 +457,9 @@ void reverse_data_configure(struct ext_dsp_module *ext,
static void get_aec_ini(const char *config_dir)
{
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", config_dir,
+ snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_dir,
AEC_CONFIG_NAME);
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
+ ini_name[MAX_INI_NAME_LEN] = '\0';
if (aec_ini) {
iniparser_freedict(aec_ini);
@@ -542,9 +472,9 @@ static void get_aec_ini(const char *config_dir)
static void get_apm_ini(const char *config_dir)
{
- snprintf(ini_name, MAX_INI_NAME_LENGTH, "%s/%s", config_dir,
+ snprintf(ini_name, MAX_INI_NAME_LEN, "%s/%s", config_dir,
APM_CONFIG_NAME);
- ini_name[MAX_INI_NAME_LENGTH] = '\0';
+ ini_name[MAX_INI_NAME_LEN] = '\0';
if (apm_ini) {
iniparser_freedict(apm_ini);
@@ -689,13 +619,6 @@ struct cras_audio_format *cras_apm_list_get_format(struct cras_apm *apm)
return &apm->fmt;
}
-bool cras_apm_list_get_use_tuned_settings(struct cras_apm *apm)
-{
- /* If input and output devices in AEC use case, plus that a
- * tuned setting is provided. */
- return apm->is_aec_use_case && (aec_ini || apm_ini);
-}
-
void cras_apm_list_set_aec_dump(struct cras_apm_list *list, void *dev_ptr,
int start, int fd)
{
diff --git a/cras/src/server/cras_apm_list.h b/cras/src/server/cras_apm_list.h
index 7a36ceae..486b943d 100644
--- a/cras/src/server/cras_apm_list.h
+++ b/cras/src/server/cras_apm_list.h
@@ -27,25 +27,7 @@ int cras_apm_list_deinit();
/*
* Creates an list to hold all APM instances created when a stream
- * attaches to iodev(s). This should be called in main thread.
- *
- * Below diagram explains the life cycle of an APM instance, how are
- * related APIs used, and in which thread should each API be called.
- *
- * Main thread Audio thread
- * maintaining apm_list maintaining active_apms
- * ----------- ------------
- * cras_apm_list_create
- * cras_apm_list_add_apm -> cras_apm_list_start_apm
- *
- * cras_apm_list_get_active_apm
- * cras_apm_list_process
- * cras_apm_list_get_processed
- * cras_apm_list_put_processed
- *
- * cras_apm_list_remove_apm <- cras_apm_list_stop_apm
- * cras_apm_list_destroy
- *
+ * attaches to an iodev.
* Args:
* stream_ptr - Pointer to the stream.
* effects - Bit map specifying the enabled effects on this stream.
@@ -55,39 +37,22 @@ struct cras_apm_list *cras_apm_list_create(void *stream_ptr, uint64_t effects);
/*
* Creates a cras_apm associated to given dev_ptr and adds it to the list.
* If there already exists an APM instance linked to dev_ptr, we assume
- * the open format is unchanged so just return it. This should be called
- * in main thread.
+ * the open format is unchanged so just return it.
* Args:
* list - The list holding APM instances.
* dev_ptr - Pointer to the iodev to add new APM for.
* fmt - Format of the audio data used for this cras_apm.
- * is_aec_use_case - If the dev_ptr is for typical AEC use case.
*/
-struct cras_apm *cras_apm_list_add_apm(struct cras_apm_list *list,
- void *dev_ptr,
- const struct cras_audio_format *fmt,
- bool is_aec_use_case);
+struct cras_apm *cras_apm_list_add(struct cras_apm_list *list, void *dev_ptr,
+ const struct cras_audio_format *fmt);
/*
- * Gets the active APM instance that is associated to given stream and dev pair.
- * This should be called in audio thread.
+ * Gets the cras_apm instance in the list that associates with given dev.
* Args:
- * stream_ptr - Pointer to the stream.
+ * list - The list holding APM instances.
* dev_ptr - The iodev as key to look up associated APM.
*/
-struct cras_apm *cras_apm_list_get_active_apm(void *stream_ptr, void *dev_ptr);
-
-/*
- * Starts the APM instance in the list that is associated with dev_ptr by
- * adding it to the active APM list in audio thread.
- */
-void cras_apm_list_start_apm(struct cras_apm_list *list, void *dev_ptr);
-
-/*
- * Stops the APM instance in the list that is associated with dev_ptr by
- * removing it from the active APM list in audio thread.
- */
-void cras_apm_list_stop_apm(struct cras_apm_list *list, void *dev_ptr);
+struct cras_apm *cras_apm_list_get(struct cras_apm_list *list, void *dev_ptr);
/*
* Gets the effects bit map of the APM list.
@@ -101,13 +66,12 @@ int cras_apm_list_destroy(struct cras_apm_list *list);
/*
* Removes an APM from the list, expected to be used when an iodev is no
- * longer open for the client stream holding the APM list. This should
- * be called in main thread.
+ * longer open for the client stream holding the APM list.
* Args:
* list - The list holding APM instances.
* dev_ptr - Device pointer used to look up which apm to remove.
*/
-void cras_apm_list_remove_apm(struct cras_apm_list *list, void *dev_ptr);
+void cras_apm_list_remove(struct cras_apm_list *list, void *dev_ptr);
/* Passes audio data from hardware for cras_apm to process.
* Args:
@@ -143,11 +107,6 @@ void cras_apm_list_put_processed(struct cras_apm *apm, unsigned int frames);
*/
struct cras_audio_format *cras_apm_list_get_format(struct cras_apm *apm);
-/*
- * Gets if this apm instance is using tuned settings.
- */
-bool cras_apm_list_get_use_tuned_settings(struct cras_apm *apm);
-
/* Sets debug recording to start or stop.
* Args:
* list - List contains the apm instance to start/stop debug recording.
@@ -162,7 +121,7 @@ void cras_apm_list_set_aec_dump(struct cras_apm_list *list, void *dev_ptr,
/*
* If webrtc audio processing library is not available then define all
- * cras_apm_list functions as empty. As long as cras_apm_list_add returns
+ * cras_apm_list functions as dummy. As long as cras_apm_list_add returns
* NULL, non of the other functions should be called.
*/
static inline int cras_apm_list_init(const char *device_config_dir)
@@ -178,13 +137,13 @@ static inline struct cras_apm_list *cras_apm_list_create(void *stream_ptr,
return NULL;
}
static inline struct cras_apm *
-cras_apm_list_add_apm(struct cras_apm_list *list, void *dev_ptr,
- const struct cras_audio_format *fmt, bool is_aec_use_case)
+cras_apm_list_add(struct cras_apm_list *list, void *dev_ptr,
+ const struct cras_audio_format *fmt)
{
return NULL;
}
-static inline struct cras_apm *cras_apm_list_get_active_apm(void *stream_ptr,
- void *dev_ptr)
+static inline struct cras_apm *cras_apm_list_get(struct cras_apm_list *list,
+ void *dev_ptr)
{
return NULL;
}
@@ -196,8 +155,8 @@ static inline int cras_apm_list_destroy(struct cras_apm_list *list)
{
return 0;
}
-static inline void cras_apm_list_remove_apm(struct cras_apm_list *list,
- void *dev_ptr)
+static inline void cras_apm_list_remove(struct cras_apm_list *list,
+ void *dev_ptr)
{
}
@@ -218,14 +177,6 @@ static inline void cras_apm_list_put_processed(struct cras_apm *apm,
unsigned int frames)
{
}
-static inline void cras_apm_list_start_apm(struct cras_apm_list *list,
- void *dev_ptr)
-{
-}
-static inline void cras_apm_list_stop_apm(struct cras_apm_list *list,
- void *dev_ptr)
-{
-}
static inline struct cras_audio_format *
cras_apm_list_get_format(struct cras_apm *apm)
@@ -233,11 +184,6 @@ cras_apm_list_get_format(struct cras_apm *apm)
return NULL;
}
-static inline bool cras_apm_list_get_use_tuned_settings(struct cras_apm *apm)
-{
- return 0;
-}
-
static inline void cras_apm_list_set_aec_dump(struct cras_apm_list *list,
void *dev_ptr, int start, int fd)
{
diff --git a/cras/src/server/cras_audio_thread_monitor.c b/cras/src/server/cras_audio_thread_monitor.c
index ed3afbac..59212459 100644
--- a/cras/src/server/cras_audio_thread_monitor.c
+++ b/cras/src/server/cras_audio_thread_monitor.c
@@ -50,16 +50,6 @@ int cras_audio_thread_event_send(enum CRAS_AUDIO_THREAD_EVENT_TYPE event_type)
return cras_main_message_send(&msg.header);
}
-int cras_audio_thread_event_a2dp_overrun()
-{
- return cras_audio_thread_event_send(AUDIO_THREAD_EVENT_A2DP_OVERRUN);
-}
-
-int cras_audio_thread_event_a2dp_throttle()
-{
- return cras_audio_thread_event_send(AUDIO_THREAD_EVENT_A2DP_THROTTLE);
-}
-
int cras_audio_thread_event_debug()
{
return cras_audio_thread_event_send(AUDIO_THREAD_EVENT_DEBUG);
@@ -85,11 +75,6 @@ int cras_audio_thread_event_drop_samples()
return cras_audio_thread_event_send(AUDIO_THREAD_EVENT_DROP_SAMPLES);
}
-int cras_audio_thread_event_dev_overrun()
-{
- return cras_audio_thread_event_send(AUDIO_THREAD_EVENT_DEV_OVERRUN);
-}
-
static struct timespec last_event_snapshot_time[AUDIO_THREAD_EVENT_TYPE_COUNT];
/*
diff --git a/cras/src/server/cras_audio_thread_monitor.h b/cras/src/server/cras_audio_thread_monitor.h
index 39b21765..b7355caa 100644
--- a/cras/src/server/cras_audio_thread_monitor.h
+++ b/cras/src/server/cras_audio_thread_monitor.h
@@ -7,16 +7,6 @@
#define CRAS_AUDIO_THREAD_MONITOR_H_
/*
- * Notifies the main thread when A2DP buffer overruns.
- */
-int cras_audio_thread_event_a2dp_overrun();
-
-/*
- * Notifies the main thread when A2DP packet transmittion throttles.
- */
-int cras_audio_thread_event_a2dp_throttle();
-
-/*
* Sends a debug event to the audio thread for debugging.
*/
int cras_audio_thread_event_debug();
@@ -42,11 +32,6 @@ int cras_audio_thread_event_severe_underrun();
int cras_audio_thread_event_drop_samples();
/*
- * Notifies the main thread when a device overrun event happens.
- */
-int cras_audio_thread_event_dev_overrun();
-
-/*
* Initializes audio thread monitor and sets main thread callback.
*/
int cras_audio_thread_monitor_init();
diff --git a/cras/src/server/cras_bt_battery_provider.c b/cras/src/server/cras_bt_battery_provider.c
deleted file mode 100644
index 13e6590f..00000000
--- a/cras/src/server/cras_bt_battery_provider.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-#include <dbus/dbus.h>
-#include <errno.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-
-#include "cras_bt_adapter.h"
-#include "cras_bt_battery_provider.h"
-#include "cras_bt_constants.h"
-#include "cras_dbus_util.h"
-#include "cras_observer.h"
-#include "utlist.h"
-
-/* CRAS registers one battery provider to BlueZ, so we use a singleton. */
-static struct cras_bt_battery_provider battery_provider = {
- .object_path = CRAS_DEFAULT_BATTERY_PROVIDER,
- .interface = BLUEZ_INTERFACE_BATTERY_PROVIDER,
- .conn = NULL,
- .is_registered = false,
- .observer = NULL,
- .batteries = NULL,
-};
-
-static int cmp_battery_address(const struct cras_bt_battery *battery,
- const char *address)
-{
- return strcmp(battery->address, address);
-}
-
-static void replace_colon_with_underscore(char *str)
-{
- for (int i = 0; str[i]; i++) {
- if (str[i] == ':')
- str[i] = '_';
- }
-}
-
-/* Converts address XX:XX:XX:XX:XX:XX to Battery Provider object path:
- * /org/chromium/Cras/Bluetooth/BatteryProvider/XX_XX_XX_XX_XX_XX
- */
-static char *address_to_battery_path(const char *address)
-{
- char *object_path = malloc(strlen(CRAS_DEFAULT_BATTERY_PROVIDER) +
- strlen(address) + 2);
-
- sprintf(object_path, "%s/%s", CRAS_DEFAULT_BATTERY_PROVIDER, address);
- replace_colon_with_underscore(object_path);
-
- return object_path;
-}
-
-/* Converts address XX:XX:XX:XX:XX:XX to device object path:
- * /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX
- */
-static char *address_to_device_path(const char *address)
-{
- char *object_path = malloc(strlen(CRAS_DEFAULT_BATTERY_PREFIX) +
- strlen(address) + 1);
-
- sprintf(object_path, "%s%s", CRAS_DEFAULT_BATTERY_PREFIX, address);
- replace_colon_with_underscore(object_path);
-
- return object_path;
-}
-
-static struct cras_bt_battery *battery_new(const char *address, uint32_t level)
-{
- struct cras_bt_battery *battery;
-
- battery = calloc(1, sizeof(struct cras_bt_battery));
- battery->address = strdup(address);
- battery->object_path = address_to_battery_path(address);
- battery->device_path = address_to_device_path(address);
- battery->level = level;
-
- return battery;
-}
-
-static void battery_free(struct cras_bt_battery *battery)
-{
- if (battery->address)
- free(battery->address);
- if (battery->object_path)
- free(battery->object_path);
- if (battery->device_path)
- free(battery->device_path);
- free(battery);
-}
-
-static void populate_battery_properties(DBusMessageIter *iter,
- const struct cras_bt_battery *battery)
-{
- DBusMessageIter dict, entry, variant;
- const char *property_percentage = "Percentage";
- const char *property_device = "Device";
- uint8_t level = battery->level;
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
-
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &property_percentage);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_BYTE_AS_STRING, &variant);
- dbus_message_iter_append_basic(&variant, DBUS_TYPE_BYTE, &level);
- dbus_message_iter_close_container(&entry, &variant);
- dbus_message_iter_close_container(&dict, &entry);
-
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &property_device);
- dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
- DBUS_TYPE_OBJECT_PATH_AS_STRING,
- &variant);
- dbus_message_iter_append_basic(&variant, DBUS_TYPE_OBJECT_PATH,
- &battery->device_path);
- dbus_message_iter_close_container(&entry, &variant);
- dbus_message_iter_close_container(&dict, &entry);
-
- dbus_message_iter_close_container(iter, &dict);
-}
-
-/* Creates a new battery object and exposes it on D-Bus. */
-static struct cras_bt_battery *
-get_or_create_battery(struct cras_bt_battery_provider *provider,
- const char *address, uint32_t level)
-{
- struct cras_bt_battery *battery;
- DBusMessage *msg;
- DBusMessageIter iter, dict, entry;
-
- LL_SEARCH(provider->batteries, battery, address, cmp_battery_address);
-
- if (battery)
- return battery;
-
- syslog(LOG_DEBUG, "Creating new battery for %s", address);
-
- battery = battery_new(address, level);
- LL_APPEND(provider->batteries, battery);
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_BATTERY_PROVIDER,
- DBUS_INTERFACE_OBJECT_MANAGER,
- DBUS_SIGNAL_INTERFACES_ADDED);
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &battery->object_path);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sa{sv}}",
- &dict);
- dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL,
- &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &provider->interface);
- populate_battery_properties(&entry, battery);
- dbus_message_iter_close_container(&dict, &entry);
- dbus_message_iter_close_container(&iter, &dict);
-
- if (!dbus_connection_send(provider->conn, msg, NULL)) {
- syslog(LOG_ERR,
- "Error sending " DBUS_SIGNAL_INTERFACES_ADDED " signal");
- }
-
- dbus_message_unref(msg);
-
- return battery;
-}
-
-/* Updates the level of a battery object and signals it on D-Bus. */
-static void
-update_battery_level(const struct cras_bt_battery_provider *provider,
- struct cras_bt_battery *battery, uint32_t level)
-{
- DBusMessage *msg;
- DBusMessageIter iter;
-
- if (battery->level == level)
- return;
-
- battery->level = level;
-
- msg = dbus_message_new_signal(battery->object_path,
- DBUS_INTERFACE_PROPERTIES,
- DBUS_SIGNAL_PROPERTIES_CHANGED);
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &provider->interface);
- populate_battery_properties(&iter, battery);
-
- if (!dbus_connection_send(provider->conn, msg, NULL)) {
- syslog(LOG_ERR, "Error sending " DBUS_SIGNAL_PROPERTIES_CHANGED
- " signal");
- }
-
- dbus_message_unref(msg);
-}
-
-/* Invoked when HFP sends an alert about a battery value change. */
-static void on_bt_battery_changed(void *context, const char *address,
- uint32_t level)
-{
- struct cras_bt_battery_provider *provider = context;
-
- syslog(LOG_DEBUG, "Battery changed for address %s, level %d", address,
- level);
-
- if (!provider->is_registered) {
- syslog(LOG_WARNING, "Received battery level update while "
- "battery provider is not registered");
- return;
- }
-
- struct cras_bt_battery *battery =
- get_or_create_battery(provider, address, level);
-
- update_battery_level(provider, battery, level);
-}
-
-/* Invoked when we receive a D-Bus return of RegisterBatteryProvider from
- * BlueZ.
- */
-static void
-cras_bt_on_battery_provider_registered(DBusPendingCall *pending_call,
- void *data)
-{
- DBusMessage *reply;
- struct cras_bt_battery_provider *provider = data;
- struct cras_observer_ops observer_ops;
-
- reply = dbus_pending_call_steal_reply(pending_call);
- dbus_pending_call_unref(pending_call);
-
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- syslog(LOG_ERR, "RegisterBatteryProvider returned error: %s",
- dbus_message_get_error_name(reply));
- dbus_message_unref(reply);
- return;
- }
-
- syslog(LOG_INFO, "RegisterBatteryProvider succeeded");
-
- provider->is_registered = true;
-
- memset(&observer_ops, 0, sizeof(observer_ops));
- observer_ops.bt_battery_changed = on_bt_battery_changed;
- provider->observer = cras_observer_add(&observer_ops, provider);
-
- dbus_message_unref(reply);
-}
-
-int cras_bt_register_battery_provider(DBusConnection *conn,
- const struct cras_bt_adapter *adapter)
-{
- const char *adapter_path;
- DBusMessage *method_call;
- DBusMessageIter message_iter;
- DBusPendingCall *pending_call;
-
- if (battery_provider.is_registered) {
- syslog(LOG_ERR, "Battery Provider already registered");
- return -EBUSY;
- }
-
- if (battery_provider.conn)
- dbus_connection_unref(battery_provider.conn);
-
- battery_provider.conn = conn;
- dbus_connection_ref(battery_provider.conn);
-
- adapter_path = cras_bt_adapter_object_path(adapter);
- method_call = dbus_message_new_method_call(
- BLUEZ_SERVICE, adapter_path,
- BLUEZ_INTERFACE_BATTERY_PROVIDER_MANAGER,
- "RegisterBatteryProvider");
- if (!method_call)
- return -ENOMEM;
-
- dbus_message_iter_init_append(method_call, &message_iter);
- dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
- &battery_provider.object_path);
-
- if (!dbus_connection_send_with_reply(conn, method_call, &pending_call,
- DBUS_TIMEOUT_USE_DEFAULT)) {
- dbus_message_unref(method_call);
- return -ENOMEM;
- }
-
- dbus_message_unref(method_call);
-
- if (!pending_call)
- return -EIO;
-
- if (!dbus_pending_call_set_notify(
- pending_call, cras_bt_on_battery_provider_registered,
- &battery_provider, NULL)) {
- dbus_pending_call_cancel(pending_call);
- dbus_pending_call_unref(pending_call);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-/* Removes a battery object and signals the removal on D-Bus as well. */
-static void cleanup_battery(struct cras_bt_battery_provider *provider,
- struct cras_bt_battery *battery)
-{
- DBusMessage *msg;
- DBusMessageIter iter, entry;
-
- if (!battery)
- return;
-
- LL_DELETE(provider->batteries, battery);
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_BATTERY_PROVIDER,
- DBUS_INTERFACE_OBJECT_MANAGER,
- DBUS_SIGNAL_INTERFACES_REMOVED);
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
- &battery->object_path);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &entry);
- dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
- &provider->interface);
- dbus_message_iter_close_container(&iter, &entry);
-
- if (!dbus_connection_send(provider->conn, msg, NULL)) {
- syslog(LOG_ERR, "Error sending " DBUS_SIGNAL_INTERFACES_REMOVED
- " signal");
- }
-
- dbus_message_unref(msg);
-
- battery_free(battery);
-}
-
-void cras_bt_battery_provider_reset()
-{
- struct cras_bt_battery *battery;
-
- syslog(LOG_INFO, "Resetting battery provider");
-
- if (!battery_provider.is_registered)
- return;
-
- battery_provider.is_registered = false;
-
- LL_FOREACH (battery_provider.batteries, battery) {
- cleanup_battery(&battery_provider, battery);
- }
-
- if (battery_provider.conn) {
- dbus_connection_unref(battery_provider.conn);
- battery_provider.conn = NULL;
- }
-
- if (battery_provider.observer) {
- cras_observer_remove(battery_provider.observer);
- battery_provider.observer = NULL;
- }
-}
diff --git a/cras/src/server/cras_bt_battery_provider.h b/cras/src/server/cras_bt_battery_provider.h
deleted file mode 100644
index 1998cd78..00000000
--- a/cras/src/server/cras_bt_battery_provider.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef CRAS_BT_BATTERY_PROVIDER_H_
-#define CRAS_BT_BATTERY_PROVIDER_H_
-
-#include <dbus/dbus.h>
-#include <stdbool.h>
-
-#include "cras_bt_adapter.h"
-
-/* Object to represent a battery that is exposed to BlueZ. */
-struct cras_bt_battery {
- char *address;
- char *object_path;
- char *device_path;
- uint32_t level;
- struct cras_bt_battery *next;
-};
-
-/* Object to register as battery provider so that bluetoothd will monitor
- * battery objects that we expose.
- */
-struct cras_bt_battery_provider {
- const char *object_path;
- const char *interface;
- DBusConnection *conn;
- bool is_registered;
- struct cras_observer_client *observer;
- struct cras_bt_battery *batteries;
-};
-
-/* Registers battery provider to bluetoothd. This is used when a Bluetooth
- * adapter got enumerated.
- * Args:
- * conn - The D-Bus connection.
- * adapter - The enumerated bluetooth adapter.
- */
-int cras_bt_register_battery_provider(DBusConnection *conn,
- const struct cras_bt_adapter *adapter);
-
-/* Resets internal state of battery provider. */
-void cras_bt_battery_provider_reset();
-
-#endif /* CRAS_BT_BATTERY_PROVIDER_H_ */
diff --git a/cras/src/server/cras_bt_constants.h b/cras/src/server/cras_bt_constants.h
index 318aecab..8d9ad5dd 100644
--- a/cras/src/server/cras_bt_constants.h
+++ b/cras/src/server/cras_bt_constants.h
@@ -6,16 +6,12 @@
#ifndef CRAS_BT_CONSTANTS_H_
#define CRAS_BT_CONSTANTS_H_
-#define BLUEZ_SERVICE "org.bluez"
+#define BLUEZ_SERVICE "org.chromium.Bluetooth"
#define BLUEZ_INTERFACE_ADAPTER "org.bluez.Adapter1"
-#define BLUEZ_INTERFACE_BATTERY_PROVIDER "org.bluez.BatteryProvider1"
-#define BLUEZ_INTERFACE_BATTERY_PROVIDER_MANAGER \
- "org.bluez.BatteryProviderManager1"
#define BLUEZ_INTERFACE_DEVICE "org.bluez.Device1"
#define BLUEZ_INTERFACE_MEDIA "org.bluez.Media1"
#define BLUEZ_INTERFACE_MEDIA_ENDPOINT "org.bluez.MediaEndpoint1"
-#define BLUEZ_INTERFACE_MEDIA_PLAYER "org.mpris.MediaPlayer2.Player"
#define BLUEZ_INTERFACE_MEDIA_TRANSPORT "org.bluez.MediaTransport1"
#define BLUEZ_INTERFACE_PLAYER "org.bluez.MediaPlayer1"
#define BLUEZ_INTERFACE_PROFILE "org.bluez.Profile1"
@@ -24,9 +20,6 @@
#ifndef DBUS_INTERFACE_OBJECT_MANAGER
#define DBUS_INTERFACE_OBJECT_MANAGER "org.freedesktop.DBus.ObjectManager"
#endif
-#define DBUS_SIGNAL_INTERFACES_ADDED "InterfacesAdded"
-#define DBUS_SIGNAL_INTERFACES_REMOVED "InterfacesRemoved"
-#define DBUS_SIGNAL_PROPERTIES_CHANGED "PropertiesChanged"
/* UUIDs taken from lib/uuid.h in the BlueZ source */
#define HSP_HS_UUID "00001108-0000-1000-8000-00805f9b34fb"
@@ -43,29 +36,4 @@
#define GENERIC_AUDIO_UUID "00001203-0000-1000-8000-00805f9b34fb"
-/* Constants for CRAS BT player */
-#define CRAS_DEFAULT_PLAYER "/org/chromium/Cras/Bluetooth/DefaultPlayer"
-/* The longest possible player playback status is "forward-seek" */
-#define CRAS_PLAYER_PLAYBACK_STATUS_SIZE_MAX 13 * sizeof(char)
-#define CRAS_PLAYER_PLAYBACK_STATUS_DEFAULT "playing"
-/* Neither BlueZ or the MRPIS specs limited the player identity max size, 128
- * should be large enough for most.
- */
-#define CRAS_PLAYER_IDENTITY_SIZE_MAX 128 * sizeof(char)
-#define CRAS_PLAYER_IDENTITY_DEFAULT "DefaultPlayer"
-#define CRAS_PLAYER_METADATA_SIZE_MAX 128 * sizeof(char)
-
-#define CRAS_DEFAULT_BATTERY_PROVIDER \
- "/org/chromium/Cras/Bluetooth/BatteryProvider"
-#define CRAS_DEFAULT_BATTERY_PREFIX "/org/bluez/hci0/dev_"
-
-/* Instead of letting CRAS obtain the A2DP streaming packet size (a.k.a. AVDTP
- * MTU) from BlueZ Media Transport, force the packet size to the default L2CAP
- * packet size. This prevent the audio peripheral device to negotiate a larger
- * packet size and later failed to fulfill it and causing audio artifact. This
- * defined constant is for experiment only and is put back behind a
- * chrome://flag.
- */
-#define A2DP_FIX_PACKET_SIZE 672
-
#endif /* CRAS_BT_CONSTANTS_H_ */
diff --git a/cras/src/server/cras_bt_device.c b/cras/src/server/cras_bt_device.c
index 6b06dd13..bc6b43d9 100644
--- a/cras/src/server/cras_bt_device.c
+++ b/cras/src/server/cras_bt_device.c
@@ -31,10 +31,8 @@
#include "cras_iodev.h"
#include "cras_iodev_list.h"
#include "cras_main_message.h"
-#include "cras_server_metrics.h"
#include "cras_system_state.h"
#include "cras_tm.h"
-#include "sfh.h"
#include "utlist.h"
/*
@@ -54,15 +52,12 @@ static const unsigned int PROFILE_DROP_SUSPEND_DELAY_MS = 5000;
*/
static const unsigned int CONN_WATCH_PERIOD_MS = 2000;
static const unsigned int CONN_WATCH_MAX_RETRIES = 30;
-
-/* This is used when a critical SCO failure happens and is worth scheduling a
- * suspend in case for some reason BT headset stays connected in baseband and
- * confuses user.
- */
-static const unsigned int SCO_SUSPEND_DELAY_MS = 5000;
+static const unsigned int PROFILE_CONN_RETRIES = 3;
static const unsigned int CRAS_SUPPORTED_PROFILES =
- CRAS_BT_DEVICE_PROFILE_A2DP_SINK | CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE;
+ CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
+ CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE |
+ CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
/* Object to represent a general bluetooth device, and used to
* associate with some CRAS modules if it supports audio.
@@ -78,8 +73,6 @@ static const unsigned int CRAS_SUPPORTED_PROFILES =
* connected - If this devices is connected.
* connected_profiles - OR'ed all connected audio profiles.
* profiles - OR'ed by all audio profiles this device supports.
- * hidden_profiles - OR'ed by all audio profiles this device actually
- * supports but is not scanned by BlueZ.
* bt_iodevs - The pointer to the cras_iodevs of this device.
* active_profile - The flag to indicate the active audio profile this
* device is currently using.
@@ -91,8 +84,6 @@ static const unsigned int CRAS_SUPPORTED_PROFILES =
* profile switch.
* sco_fd - The file descriptor of the SCO connection.
* sco_ref_count - The reference counts of the SCO connection.
- * suspend_reason - The reason code for why suspend is scheduled.
- * stable_id - The unique and persistent id of this bt_device.
*/
struct cras_bt_device {
DBusConnection *conn;
@@ -104,9 +95,8 @@ struct cras_bt_device {
int paired;
int trusted;
int connected;
- unsigned int connected_profiles;
- unsigned int profiles;
- unsigned int hidden_profiles;
+ enum cras_bt_device_profile connected_profiles;
+ enum cras_bt_device_profile profiles;
struct cras_iodev *bt_iodevs[CRAS_NUM_DIRECTIONS];
unsigned int active_profile;
int use_hardware_volume;
@@ -116,8 +106,6 @@ struct cras_bt_device {
struct cras_timer *switch_profile_timer;
int sco_fd;
size_t sco_ref_count;
- enum cras_bt_device_suspend_reason suspend_reason;
- unsigned int stable_id;
struct cras_bt_device *prev, *next;
};
@@ -134,8 +122,7 @@ struct bt_device_msg {
enum BT_DEVICE_COMMAND cmd;
struct cras_bt_device *device;
struct cras_iodev *dev;
- unsigned int arg1;
- unsigned int arg2;
+ unsigned int arg;
};
static struct cras_bt_device *devices;
@@ -177,9 +164,6 @@ struct cras_bt_device *cras_bt_device_create(DBusConnection *conn,
free(device);
return NULL;
}
- device->stable_id =
- SuperFastHash(device->object_path, strlen(device->object_path),
- strlen(device->object_path));
DL_APPEND(devices, device);
@@ -349,11 +333,6 @@ const char *cras_bt_device_object_path(const struct cras_bt_device *device)
return device->object_path;
}
-int cras_bt_device_get_stable_id(const struct cras_bt_device *device)
-{
- return device->stable_id;
-}
-
struct cras_bt_adapter *
cras_bt_device_adapter(const struct cras_bt_device *device)
{
@@ -407,25 +386,6 @@ void cras_bt_device_append_iodev(struct cras_bt_device *device,
}
}
-/*
- * Sets the audio nodes to 'plugged' means UI can select it and open it
- * for streams. Sets to 'unplugged' to hide these nodes from UI, when device
- * disconnects in progress.
- */
-static void bt_device_set_nodes_plugged(struct cras_bt_device *device,
- int plugged)
-{
- struct cras_iodev *iodev;
-
- iodev = device->bt_iodevs[CRAS_STREAM_INPUT];
- if (iodev)
- cras_iodev_set_node_plugged(iodev->active_node, plugged);
-
- iodev = device->bt_iodevs[CRAS_STREAM_OUTPUT];
- if (iodev)
- cras_iodev_set_node_plugged(iodev->active_node, plugged);
-}
-
static void bt_device_switch_profile(struct cras_bt_device *device,
struct cras_iodev *bt_iodev,
int enable_dev);
@@ -436,8 +396,6 @@ void cras_bt_device_rm_iodev(struct cras_bt_device *device,
struct cras_iodev *bt_iodev;
int rc;
- bt_device_set_nodes_plugged(device, 0);
-
bt_iodev = device->bt_iodevs[iodev->direction];
if (bt_iodev) {
unsigned try_profile;
@@ -509,8 +467,6 @@ static void bt_device_remove_conflict(struct cras_bt_device *device)
cras_a2dp_suspend_connected_device(connected);
}
-static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg);
-
int cras_bt_device_audio_gateway_initialized(struct cras_bt_device *device)
{
BTLOG(btlog, BT_AUDIO_GATEWAY_INIT, device->profiles, 0);
@@ -519,23 +475,10 @@ int cras_bt_device_audio_gateway_initialized(struct cras_bt_device *device)
device->connected_profiles |= (CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE |
CRAS_BT_DEVICE_PROFILE_HSP_HEADSET);
- /* If device connects HFP but not reporting correct UUID, manually add
- * it to allow CRAS to enumerate audio node for it. We're seeing this
- * behavior on qualification test software. */
- if (!cras_bt_device_supports_profile(
- device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE)) {
- unsigned int profiles =
- device->profiles | CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE;
- cras_bt_device_set_supported_profiles(device, profiles);
- device->hidden_profiles |= CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE;
- bt_device_conn_watch_cb(NULL, (void *)device);
- }
-
return 0;
}
-unsigned int
-cras_bt_device_get_active_profile(const struct cras_bt_device *device)
+int cras_bt_device_get_active_profile(const struct cras_bt_device *device)
{
return device->active_profile;
}
@@ -585,19 +528,6 @@ static void cras_bt_device_log_profile(const struct cras_bt_device *device,
}
}
-static void cras_bt_device_log_profiles(const struct cras_bt_device *device,
- unsigned int profiles)
-{
- unsigned int profile;
-
- while (profiles) {
- /* Get the LSB of profiles */
- profile = profiles & -profiles;
- cras_bt_device_log_profile(device, profile);
- profiles ^= profile;
- }
-}
-
static int
cras_bt_device_is_profile_connected(const struct cras_bt_device *device,
enum cras_bt_device_profile profile)
@@ -605,9 +535,8 @@ cras_bt_device_is_profile_connected(const struct cras_bt_device *device,
return !!(device->connected_profiles & profile);
}
-static void
-bt_device_schedule_suspend(struct cras_bt_device *device, unsigned int msec,
- enum cras_bt_device_suspend_reason suspend_reason);
+static void bt_device_schedule_suspend(struct cras_bt_device *device,
+ unsigned int msec);
/* Callback used to periodically check if supported profiles are connected. */
static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg)
@@ -615,10 +544,6 @@ static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg)
struct cras_tm *tm;
struct cras_bt_device *device = (struct cras_bt_device *)arg;
int rc;
- bool a2dp_supported;
- bool a2dp_connected;
- bool hfp_supported;
- bool hfp_connected;
BTLOG(btlog, BT_DEV_CONN_WATCH_CB, device->conn_watch_retries,
device->profiles);
@@ -628,34 +553,27 @@ static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg)
if (!device->profiles)
return;
- a2dp_supported = cras_bt_device_supports_profile(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
- a2dp_connected = cras_bt_device_is_profile_connected(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
- hfp_supported = cras_bt_device_supports_profile(
- device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
- hfp_connected = cras_bt_device_is_profile_connected(
- device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
-
- /* If not both A2DP and HFP are supported, simply wait for BlueZ
- * to notify us about the new connection.
- * Otherwise, when seeing one but not the other profile is connected,
- * send message to ask BlueZ to connect the pending one.
- */
- if (a2dp_supported && hfp_supported) {
- /* If both a2dp and hfp are not connected, do nothing. BlueZ
- * should be responsible to notify connection of one profile.
- */
- if (!a2dp_connected && hfp_connected)
+ /* If A2DP is not ready, try connect it after a while. */
+ if (cras_bt_device_supports_profile(device,
+ CRAS_BT_DEVICE_PROFILE_A2DP_SINK) &&
+ !cras_bt_device_is_profile_connected(
+ device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK)) {
+ if (0 == device->conn_watch_retries % PROFILE_CONN_RETRIES)
cras_bt_device_connect_profile(device->conn, device,
A2DP_SINK_UUID);
- if (a2dp_connected && !hfp_connected)
- cras_bt_device_connect_profile(device->conn, device,
- HFP_HF_UUID);
+ goto arm_retry_timer;
}
- if (a2dp_supported != a2dp_connected || hfp_supported != hfp_connected)
+ /* If HFP is not ready, try connect it after a while. */
+ if (cras_bt_device_supports_profile(
+ device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE) &&
+ !cras_bt_device_is_profile_connected(
+ device, CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE)) {
+ if (0 == device->conn_watch_retries % PROFILE_CONN_RETRIES)
+ cras_bt_device_connect_profile(device->conn, device,
+ HFP_HF_UUID);
goto arm_retry_timer;
+ }
/* Expected profiles are all connected, no more connection watch
* callback will be scheduled.
@@ -675,11 +593,9 @@ static void bt_device_conn_watch_cb(struct cras_timer *timer, void *arg)
if (rc) {
syslog(LOG_ERR, "Start audio gateway failed, rc %d",
rc);
- bt_device_schedule_suspend(device, 0,
- HFP_AG_START_FAILURE);
+ bt_device_schedule_suspend(device, 0);
}
}
- bt_device_set_nodes_plugged(device, 1);
return;
arm_retry_timer:
@@ -693,7 +609,7 @@ arm_retry_timer:
bt_device_conn_watch_cb, device);
} else {
syslog(LOG_ERR, "Connection watch timeout.");
- bt_device_schedule_suspend(device, 0, CONN_WATCH_TIME_OUT);
+ bt_device_schedule_suspend(device, 0);
}
}
@@ -710,24 +626,16 @@ cras_bt_device_start_new_conn_watch_timer(struct cras_bt_device *device)
tm, CONN_WATCH_PERIOD_MS, bt_device_conn_watch_cb, device);
}
-static void bt_device_cancel_suspend(struct cras_bt_device *device);
-
void cras_bt_device_set_connected(struct cras_bt_device *device, int value)
{
struct cras_tm *tm = cras_system_state_get_tm();
- if (!device->connected && value) {
- BTLOG(btlog, BT_DEV_CONNECTED, device->profiles,
- device->stable_id);
- }
+ if (device->connected || value)
+ BTLOG(btlog, BT_DEV_CONNECTED_CHANGE, device->profiles, value);
if (device->connected && !value) {
- BTLOG(btlog, BT_DEV_DISCONNECTED, device->profiles,
- device->stable_id);
cras_bt_profile_on_device_disconnected(device);
- /* Device is disconnected, resets connected profiles and the
- * suspend timer which scheduled earlier. */
+ /* Device is disconnected, resets connected profiles. */
device->connected_profiles = 0;
- bt_device_cancel_suspend(device);
}
device->connected = value;
@@ -741,48 +649,47 @@ void cras_bt_device_set_connected(struct cras_bt_device *device, int value)
void cras_bt_device_notify_profile_dropped(struct cras_bt_device *device,
enum cras_bt_device_profile profile)
{
- device->connected_profiles &= ~profile;
-
- /* Do nothing if device already disconnected. */
- if (!device->connected)
- return;
+ device->connected_profiles &= !profile;
/* If any profile, a2dp or hfp/hsp, has dropped for some reason,
* we shall make sure this device is fully disconnected within
* given time so that user does not see a headset stay connected
* but works with partial function.
*/
- bt_device_schedule_suspend(device, PROFILE_DROP_SUSPEND_DELAY_MS,
- UNEXPECTED_PROFILE_DROP);
+ bt_device_schedule_suspend(device, PROFILE_DROP_SUSPEND_DELAY_MS);
}
-/* Refresh the list of known supported profiles.
+/*
+ * Check if the uuid is of a new audio profile that isn't listed
+ * as supported by device.
* Args:
- * device - The BT device holding scanned profiles bitmap.
- * profiles - The OR'ed profiles the device claims to support as is notified
- * by BlueZ.
+ * device - The BT device holding supported profiles bitmap.
+ * uuid - UUID string from the device properties notified by BlueZ.
* Returns:
- * The OR'ed profiles that are both supported by Cras and isn't previously
- * supported by the device.
+ * True if uuid is a new audio profiles not already supported by device.
*/
-int cras_bt_device_set_supported_profiles(struct cras_bt_device *device,
- unsigned int profiles)
+int cras_bt_device_add_supported_profiles(struct cras_bt_device *device,
+ const char *uuid)
{
- /* Do nothing if no new profiles. */
- if ((device->profiles & profiles) == profiles)
+ enum cras_bt_device_profile profile =
+ cras_bt_device_profile_from_uuid(uuid);
+
+ if (profile == 0)
return 0;
- unsigned int new_profiles = profiles & ~device->profiles;
+ /* Do nothing if this profile is not new. */
+ if (device->profiles & profile)
+ return 0;
/* Log this event as we might need to re-intialize the BT audio nodes
* if new audio profile is reported for already connected device. */
- if (device->connected && (new_profiles & CRAS_SUPPORTED_PROFILES))
+ if (device->connected && (profile & CRAS_SUPPORTED_PROFILES))
BTLOG(btlog, BT_NEW_AUDIO_PROFILE_AFTER_CONNECT,
- device->profiles, new_profiles);
- cras_bt_device_log_profiles(device, new_profiles);
- device->profiles = profiles | device->hidden_profiles;
+ device->profiles, profile);
+ device->profiles |= profile;
+ cras_bt_device_log_profile(device, profile);
- return (new_profiles & CRAS_SUPPORTED_PROFILES);
+ return (profile & CRAS_SUPPORTED_PROFILES);
}
void cras_bt_device_update_properties(struct cras_bt_device *device,
@@ -850,7 +757,6 @@ void cras_bt_device_update_properties(struct cras_bt_device *device,
"as") == 0 &&
strcmp(key, "UUIDs") == 0) {
DBusMessageIter uuid_array_iter;
- unsigned int profiles = 0;
dbus_message_iter_recurse(&variant_iter,
&uuid_array_iter);
@@ -860,21 +766,22 @@ void cras_bt_device_update_properties(struct cras_bt_device *device,
dbus_message_iter_get_basic(&uuid_array_iter,
&uuid);
- profiles |=
- cras_bt_device_profile_from_uuid(uuid);
+
+ /*
+ * If updated properties includes new audio
+ * profile, and device is connected, we need
+ * to start connection watcher. This is needed
+ * because on some bluetooth device, supported
+ * profiles do not present when device
+ * interface is added and they are updated
+ * later.
+ */
+ if (cras_bt_device_add_supported_profiles(
+ device, uuid))
+ watch_needed = device->connected;
dbus_message_iter_next(&uuid_array_iter);
}
-
- /* If updated properties includes new audio profile and
- * device is connected, we need to start connection
- * watcher. This is needed because on some bluetooth
- * devices, supported profiles do not present when
- * device interface is added and they are updated later.
- */
- if (cras_bt_device_set_supported_profiles(device,
- profiles))
- watch_needed = device->connected;
}
dbus_message_iter_next(properties_array_iter);
@@ -905,7 +812,7 @@ void cras_bt_device_update_properties(struct cras_bt_device *device,
} else if (strcmp(key, "Connected") == 0) {
device->connected = 0;
} else if (strcmp(key, "UUIDs") == 0) {
- device->profiles = device->hidden_profiles;
+ device->profiles = 0;
}
dbus_message_iter_next(invalidated_array_iter);
@@ -945,7 +852,6 @@ static int bt_address(const char *str, struct sockaddr *addr)
static int apply_codec_settings(int fd, uint8_t codec)
{
struct bt_voice voice;
- uint32_t pkt_status;
memset(&voice, 0, sizeof(voice));
if (codec == HFP_CODEC_ID_CVSD)
@@ -963,12 +869,6 @@ static int apply_codec_settings(int fd, uint8_t codec)
syslog(LOG_ERR, "Failed to apply voice setting");
return -1;
}
-
- pkt_status = 1;
- if (setsockopt(fd, SOL_BLUETOOTH, BT_PKT_STATUS, &pkt_status,
- sizeof(pkt_status))) {
- syslog(LOG_ERR, "Failed to enable BT_PKT_STATUS");
- }
return 0;
}
@@ -978,7 +878,7 @@ int cras_bt_device_sco_connect(struct cras_bt_device *device, int codec)
struct sockaddr addr;
struct cras_bt_adapter *adapter;
struct timespec timeout = { 1, 0 };
- struct pollfd pollfd;
+ struct pollfd *pollfds;
adapter = cras_bt_device_adapter(device);
if (!adapter) {
@@ -992,8 +892,6 @@ int cras_bt_device_sco_connect(struct cras_bt_device *device, int codec)
if (sk < 0) {
syslog(LOG_ERR, "Failed to create socket: %s (%d)",
strerror(errno), errno);
- cras_server_metrics_hfp_sco_connection_error(
- CRAS_METRICS_SCO_SKT_OPEN_ERROR);
return -errno;
}
@@ -1008,6 +906,9 @@ int cras_bt_device_sco_connect(struct cras_bt_device *device, int codec)
/* Connect to remote in nonblocking mode */
fcntl(sk, F_SETFL, O_NONBLOCK);
+ pollfds = (struct pollfd *)malloc(sizeof(*pollfds));
+ pollfds[0].fd = sk;
+ pollfds[0].events = POLLOUT;
if (bt_address(cras_bt_device_address(device), &addr))
goto error;
@@ -1020,35 +921,22 @@ int cras_bt_device_sco_connect(struct cras_bt_device *device, int codec)
if (err && errno != EINPROGRESS) {
syslog(LOG_ERR, "Failed to connect: %s (%d)", strerror(errno),
errno);
- cras_server_metrics_hfp_sco_connection_error(
- CRAS_METRICS_SCO_SKT_CONNECT_ERROR);
goto error;
}
- pollfd.fd = sk;
- pollfd.events = POLLOUT;
-
- err = ppoll(&pollfd, 1, &timeout, NULL);
+ err = ppoll(pollfds, 1, &timeout, NULL);
if (err <= 0) {
syslog(LOG_ERR, "Connect SCO: poll for writable timeout");
- cras_server_metrics_hfp_sco_connection_error(
- CRAS_METRICS_SCO_SKT_POLL_TIMEOUT);
goto error;
}
- if (pollfd.revents & (POLLERR | POLLHUP)) {
- syslog(LOG_ERR,
- "SCO socket error, revents: %u. Suspend in %u seconds",
- pollfd.revents, SCO_SUSPEND_DELAY_MS);
- cras_server_metrics_hfp_sco_connection_error(
- CRAS_METRICS_SCO_SKT_POLL_ERR_HUP);
- bt_device_schedule_suspend(device, SCO_SUSPEND_DELAY_MS,
- HFP_SCO_SOCKET_ERROR);
+ if (pollfds[0].revents & (POLLERR | POLLHUP)) {
+ syslog(LOG_ERR, "SCO socket error, revents: %u",
+ pollfds[0].revents);
+ bt_device_schedule_suspend(device, 0);
goto error;
}
- cras_server_metrics_hfp_sco_connection_error(
- CRAS_METRICS_SCO_SKT_SUCCESS);
BTLOG(btlog, BT_SCO_CONNECT, 1, sk);
return sk;
@@ -1065,23 +953,12 @@ int cras_bt_device_sco_packet_size(struct cras_bt_device *device,
struct sco_options so;
socklen_t len = sizeof(so);
struct cras_bt_adapter *adapter;
- uint32_t wbs_pkt_len = 0;
- socklen_t optlen = sizeof(wbs_pkt_len);
adapter = cras_bt_adapter_get(device->adapter_obj_path);
if (cras_bt_adapter_on_usb(adapter)) {
- if (codec == HFP_CODEC_ID_MSBC) {
- /* BT_SNDMTU and BT_RCVMTU return the same value. */
- if (getsockopt(sco_socket, SOL_BLUETOOTH, BT_SNDMTU,
- &wbs_pkt_len, &optlen))
- syslog(LOG_ERR, "Failed to get BT_SNDMTU");
-
- return (wbs_pkt_len > 0) ? wbs_pkt_len :
- USB_MSBC_PKT_SIZE;
- } else {
- return USB_CVSD_PKT_SIZE;
- }
+ return (codec == HFP_CODEC_ID_MSBC) ? USB_MSBC_PKT_SIZE :
+ USB_CVSD_PKT_SIZE;
}
/* For non-USB cases, query the SCO MTU from driver. */
@@ -1111,8 +988,7 @@ int cras_bt_device_get_use_hardware_volume(struct cras_bt_device *device)
static void init_bt_device_msg(struct bt_device_msg *msg,
enum BT_DEVICE_COMMAND cmd,
struct cras_bt_device *device,
- struct cras_iodev *dev, unsigned int arg1,
- unsigned int arg2)
+ struct cras_iodev *dev, unsigned int arg)
{
memset(msg, 0, sizeof(*msg));
msg->header.type = CRAS_MAIN_BT;
@@ -1120,8 +996,7 @@ static void init_bt_device_msg(struct bt_device_msg *msg,
msg->cmd = cmd;
msg->device = device;
msg->dev = dev;
- msg->arg1 = arg1;
- msg->arg2 = arg2;
+ msg->arg = arg;
}
int cras_bt_device_cancel_suspend(struct cras_bt_device *device)
@@ -1129,20 +1004,19 @@ int cras_bt_device_cancel_suspend(struct cras_bt_device *device)
struct bt_device_msg msg;
int rc;
- init_bt_device_msg(&msg, BT_DEVICE_CANCEL_SUSPEND, device, NULL, 0, 0);
+ init_bt_device_msg(&msg, BT_DEVICE_CANCEL_SUSPEND, device, NULL, 0);
rc = cras_main_message_send((struct cras_main_message *)&msg);
return rc;
}
-int cras_bt_device_schedule_suspend(
- struct cras_bt_device *device, unsigned int msec,
- enum cras_bt_device_suspend_reason suspend_reason)
+int cras_bt_device_schedule_suspend(struct cras_bt_device *device,
+ unsigned int msec)
{
struct bt_device_msg msg;
int rc;
- init_bt_device_msg(&msg, BT_DEVICE_SCHEDULE_SUSPEND, device, NULL, msec,
- suspend_reason);
+ init_bt_device_msg(&msg, BT_DEVICE_SCHEDULE_SUSPEND, device, NULL,
+ msec);
rc = cras_main_message_send((struct cras_main_message *)&msg);
return rc;
}
@@ -1176,7 +1050,7 @@ int cras_bt_device_switch_profile_enable_dev(struct cras_bt_device *device,
int rc;
init_bt_device_msg(&msg, BT_DEVICE_SWITCH_PROFILE_ENABLE_DEV, device,
- bt_iodev, 0, 0);
+ bt_iodev, 0);
rc = cras_main_message_send((struct cras_main_message *)&msg);
return rc;
}
@@ -1187,8 +1061,7 @@ int cras_bt_device_switch_profile(struct cras_bt_device *device,
struct bt_device_msg msg;
int rc;
- init_bt_device_msg(&msg, BT_DEVICE_SWITCH_PROFILE, device, bt_iodev, 0,
- 0);
+ init_bt_device_msg(&msg, BT_DEVICE_SWITCH_PROFILE, device, bt_iodev, 0);
rc = cras_main_message_send((struct cras_main_message *)&msg);
return rc;
}
@@ -1277,45 +1150,21 @@ static void bt_device_suspend_cb(struct cras_timer *timer, void *arg)
struct cras_bt_device *device = (struct cras_bt_device *)arg;
BTLOG(btlog, BT_DEV_SUSPEND_CB, device->profiles,
- device->suspend_reason);
+ device->connected_profiles);
device->suspend_timer = NULL;
- /* Error log the reason so we can track them in user reports. */
- switch (device->suspend_reason) {
- case A2DP_LONG_TX_FAILURE:
- syslog(LOG_ERR, "Suspend dev: A2DP long Tx failure");
- break;
- case A2DP_TX_FATAL_ERROR:
- syslog(LOG_ERR, "Suspend dev: A2DP Tx fatal error");
- break;
- case CONN_WATCH_TIME_OUT:
- syslog(LOG_ERR, "Suspend dev: Conn watch times out");
- break;
- case HFP_SCO_SOCKET_ERROR:
- syslog(LOG_ERR, "Suspend dev: SCO socket error");
- break;
- case HFP_AG_START_FAILURE:
- syslog(LOG_ERR, "Suspend dev: HFP AG start failure");
- break;
- case UNEXPECTED_PROFILE_DROP:
- syslog(LOG_ERR, "Suspend dev: Unexpected profile drop");
- break;
- }
-
cras_a2dp_suspend_connected_device(device);
cras_hfp_ag_suspend_connected_device(device);
cras_bt_device_disconnect(device->conn, device);
}
-static void
-bt_device_schedule_suspend(struct cras_bt_device *device, unsigned int msec,
- enum cras_bt_device_suspend_reason suspend_reason)
+static void bt_device_schedule_suspend(struct cras_bt_device *device,
+ unsigned int msec)
{
struct cras_tm *tm = cras_system_state_get_tm();
if (device->suspend_timer)
return;
- device->suspend_reason = suspend_reason;
device->suspend_timer =
cras_tm_create_timer(tm, msec, bt_device_suspend_cb, device);
}
@@ -1351,8 +1200,7 @@ static void bt_device_process_msg(struct cras_main_message *msg, void *arg)
bt_device_switch_profile(bt_msg->device, bt_msg->dev, 1);
break;
case BT_DEVICE_SCHEDULE_SUSPEND:
- bt_device_schedule_suspend(bt_msg->device, bt_msg->arg1,
- bt_msg->arg2);
+ bt_device_schedule_suspend(bt_msg->device, bt_msg->arg);
break;
case BT_DEVICE_CANCEL_SUSPEND:
bt_device_cancel_suspend(bt_msg->device);
diff --git a/cras/src/server/cras_bt_device.h b/cras/src/server/cras_bt_device.h
index 9d3a2b9e..904a5f47 100644
--- a/cras/src/server/cras_bt_device.h
+++ b/cras/src/server/cras_bt_device.h
@@ -13,16 +13,6 @@ struct cras_bt_device;
struct cras_iodev;
struct cras_timer;
-/* All the reasons for when CRAS schedule a suspend to BT device. */
-enum cras_bt_device_suspend_reason {
- A2DP_LONG_TX_FAILURE,
- A2DP_TX_FATAL_ERROR,
- CONN_WATCH_TIME_OUT,
- HFP_SCO_SOCKET_ERROR,
- HFP_AG_START_FAILURE,
- UNEXPECTED_PROFILE_DROP,
-};
-
enum cras_bt_device_profile {
CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE = (1 << 0),
CRAS_BT_DEVICE_PROFILE_A2DP_SINK = (1 << 1),
@@ -50,10 +40,6 @@ void cras_bt_device_reset();
struct cras_bt_device *cras_bt_device_get(const char *object_path);
const char *cras_bt_device_object_path(const struct cras_bt_device *device);
-
-/* Gets the stable id of given cras_bt_device. */
-int cras_bt_device_get_stable_id(const struct cras_bt_device *device);
-
struct cras_bt_adapter *
cras_bt_device_adapter(const struct cras_bt_device *device);
const char *cras_bt_device_address(const struct cras_bt_device *device);
@@ -67,8 +53,8 @@ void cras_bt_device_update_properties(struct cras_bt_device *device,
DBusMessageIter *invalidated_array_iter);
/* Updates the supported profiles on dev. Expose for unit test. */
-int cras_bt_device_set_supported_profiles(struct cras_bt_device *device,
- unsigned int profiles);
+int cras_bt_device_add_supported_profiles(struct cras_bt_device *device,
+ const char *uuid);
/* Checks if profile is claimed supported by the device. */
int cras_bt_device_supports_profile(const struct cras_bt_device *device,
@@ -137,8 +123,7 @@ void cras_bt_device_rm_iodev(struct cras_bt_device *device,
struct cras_iodev *iodev);
/* Gets the active profile of the bt device. */
-unsigned int
-cras_bt_device_get_active_profile(const struct cras_bt_device *device);
+int cras_bt_device_get_active_profile(const struct cras_bt_device *device);
/* Sets the active profile of the bt device. */
void cras_bt_device_set_active_profile(struct cras_bt_device *device,
@@ -185,9 +170,8 @@ void cras_bt_device_a2dp_configured(struct cras_bt_device *device);
int cras_bt_device_cancel_suspend(struct cras_bt_device *device);
/* Schedules device to suspend after given delay. */
-int cras_bt_device_schedule_suspend(
- struct cras_bt_device *device, unsigned int msec,
- enum cras_bt_device_suspend_reason suspend_reason);
+int cras_bt_device_schedule_suspend(struct cras_bt_device *device,
+ unsigned int msec);
/* Notifies bt device that audio gateway is initialized.
* Args:
diff --git a/cras/src/server/cras_bt_io.c b/cras/src/server/cras_bt_io.c
index acdca809..637f0a79 100644
--- a/cras/src/server/cras_bt_io.c
+++ b/cras/src/server/cras_bt_io.c
@@ -8,7 +8,6 @@
#include "cras_bt_io.h"
#include "cras_bt_device.h"
-#include "cras_hfp_iodev.h"
#include "cras_utf8.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
@@ -70,7 +69,7 @@ static struct cras_ionode *add_profile_dev(struct cras_iodev *bt_iodev,
n->base.type = CRAS_NODE_TYPE_BLUETOOTH;
n->base.volume = 100;
n->base.stable_id = dev->info.stable_id;
- n->base.capture_gain = 0;
+ n->base.max_software_gain = 0;
gettimeofday(&n->base.plugged_time, NULL);
strcpy(n->base.name, dev->info.name);
@@ -106,16 +105,6 @@ static void bt_switch_to_profile(struct cras_bt_device *device,
}
}
-/* Switches the active profile to A2DP if it can. */
-static void bt_possibly_switch_to_a2dp(struct bt_io *btio)
-{
- if (!cras_bt_device_has_a2dp(btio->device))
- return;
- cras_bt_device_set_active_profile(btio->device,
- CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
- cras_bt_device_switch_profile(btio->device, &btio->base);
-}
-
/* Checks if bt device is active for the given profile.
*/
static int device_using_profile(struct cras_bt_device *device,
@@ -136,7 +125,6 @@ static int open_dev(struct cras_iodev *iodev)
{
struct bt_io *btio = (struct bt_io *)iodev;
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
/* Force to use HFP if opening input dev. */
if (device_using_profile(btio->device,
@@ -148,16 +136,8 @@ static int open_dev(struct cras_iodev *iodev)
return -EAGAIN;
}
- if (dev && dev->open_dev) {
- rc = dev->open_dev(dev);
- if (rc == 0)
- return 0;
-
- /* If input iodev open fails, switch profile back to A2DP. */
- if (iodev->direction == CRAS_STREAM_INPUT)
- bt_possibly_switch_to_a2dp(btio);
- return rc;
- }
+ if (dev && dev->open_dev)
+ return dev->open_dev(dev);
return 0;
}
@@ -170,6 +150,12 @@ static int update_supported_formats(struct cras_iodev *iodev)
if (!dev)
return -EINVAL;
+ if (dev->format == NULL) {
+ dev->format = (struct cras_audio_format *)malloc(
+ sizeof(*dev->format));
+ *dev->format = *iodev->format;
+ }
+
if (dev->update_supported_formats) {
rc = dev->update_supported_formats(dev);
if (rc)
@@ -200,9 +186,6 @@ static int update_supported_formats(struct cras_iodev *iodev)
(length + 1) * sizeof(*iodev->supported_formats));
for (i = 0; i < length + 1; i++)
iodev->supported_formats[i] = dev->supported_formats[i];
-
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels = dev->info.max_supported_channels;
return 0;
}
@@ -214,13 +197,7 @@ static int configure_dev(struct cras_iodev *iodev)
return -EINVAL;
/* Fill back the format iodev is using. */
- if (dev->format == NULL) {
- dev->format = (struct cras_audio_format *)malloc(
- sizeof(*dev->format));
- if (!dev->format)
- return -ENOMEM;
- *dev->format = *iodev->format;
- }
+ *dev->format = *iodev->format;
rc = dev->configure_dev(dev);
if (rc)
@@ -228,11 +205,6 @@ static int configure_dev(struct cras_iodev *iodev)
iodev->buffer_size = dev->buffer_size;
iodev->min_buffer_level = dev->min_buffer_level;
- if (dev->start)
- dev->state = CRAS_IODEV_STATE_OPEN;
- else
- dev->state = CRAS_IODEV_STATE_NO_STREAM_RUN;
-
return 0;
}
@@ -244,21 +216,22 @@ static int close_dev(struct cras_iodev *iodev)
if (!dev)
return -EINVAL;
- /* If input iodev is in open state and being closed, switch profile
- * from HFP to A2DP. */
- if (cras_iodev_is_open(iodev) &&
- device_using_profile(
+ /* Force back to A2DP if closing HFP. */
+ if (device_using_profile(
btio->device,
CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY |
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY) &&
- (iodev->direction == CRAS_STREAM_INPUT))
- bt_possibly_switch_to_a2dp(btio);
+ iodev->direction == CRAS_STREAM_INPUT &&
+ cras_bt_device_has_a2dp(btio->device)) {
+ cras_bt_device_set_active_profile(
+ btio->device, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
+ cras_bt_device_switch_profile(btio->device, iodev);
+ }
rc = dev->close_dev(dev);
if (rc < 0)
return rc;
cras_iodev_free_format(iodev);
- dev->state = CRAS_IODEV_STATE_CLOSE;
return 0;
}
@@ -331,7 +304,6 @@ static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
struct cras_ionode *node;
struct bt_node *active = (struct bt_node *)iodev->active_node;
struct cras_iodev *dev;
- int rc;
if (device_using_profile(btio->device, active->profile))
goto leave;
@@ -355,38 +327,11 @@ leave:
dev = active_profile_dev(iodev);
if (dev && dev->update_active_node)
dev->update_active_node(dev, node_idx, dev_enabled);
-
- /* Update supported formats here to get the supported formats from the
- * new updated active profile dev.
- */
- rc = update_supported_formats(iodev);
- if (rc) {
- syslog(LOG_ERR, "Failed to update supported formats, rc=%d",
- rc);
- }
-}
-
-static int output_underrun(struct cras_iodev *iodev)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev)
- return -EINVAL;
-
- if (dev->output_underrun) {
- dev->min_cb_level = iodev->min_cb_level;
- dev->max_cb_level = iodev->max_cb_level;
- dev->buffer_size = iodev->buffer_size;
- return dev->output_underrun(dev);
- }
-
- return 0;
}
static int no_stream(struct cras_iodev *iodev, int enable)
{
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
-
if (!dev)
return -EINVAL;
@@ -401,15 +346,8 @@ static int no_stream(struct cras_iodev *iodev, int enable)
dev->min_cb_level = iodev->min_cb_level;
dev->max_cb_level = iodev->max_cb_level;
dev->buffer_size = iodev->buffer_size;
- rc = dev->no_stream(dev, enable);
- if (rc < 0)
- return rc;
+ return dev->no_stream(dev, enable);
}
- if (enable)
- dev->state = CRAS_IODEV_STATE_NO_STREAM_RUN;
- else
- dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
return 0;
}
@@ -428,45 +366,14 @@ static int is_free_running(const struct cras_iodev *iodev)
static int start(const struct cras_iodev *iodev)
{
struct cras_iodev *dev = active_profile_dev(iodev);
- int rc;
-
if (!dev)
return -EINVAL;
- if (dev->start) {
- rc = dev->start(dev);
- if (rc)
- return rc;
- }
- dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ if (dev->start)
+ return dev->start(dev);
return 0;
}
-static unsigned int frames_to_play_in_sleep(struct cras_iodev *iodev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev || !dev->frames_to_play_in_sleep)
- return cras_iodev_default_frames_to_play_in_sleep(
- iodev, hw_level, hw_tstamp);
-
- return dev->frames_to_play_in_sleep(dev, hw_level, hw_tstamp);
-}
-
-static int get_valid_frames(struct cras_iodev *iodev,
- struct timespec *hw_tstamp)
-{
- struct cras_iodev *dev = active_profile_dev(iodev);
- if (!dev)
- return -EINVAL;
-
- if (dev->get_valid_frames)
- return dev->get_valid_frames(dev, hw_tstamp);
-
- return cras_iodev_frames_queued(iodev, hw_tstamp);
-}
-
struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
struct cras_iodev *dev,
enum cras_bt_device_profile profile)
@@ -501,11 +408,8 @@ struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
iodev->update_supported_formats = update_supported_formats;
iodev->update_active_node = update_active_node;
iodev->no_stream = no_stream;
- iodev->output_underrun = output_underrun;
iodev->is_free_running = is_free_running;
- iodev->get_valid_frames = get_valid_frames;
iodev->start = start;
- iodev->frames_to_play_in_sleep = frames_to_play_in_sleep;
/* Input also checks |software_volume_needed| flag for using software
* gain. Keep it as false for BT input.
@@ -518,30 +422,23 @@ struct cras_iodev *cras_bt_io_create(struct cras_bt_device *device,
iodev->set_volume = set_bt_volume;
}
- /* Create the fake node so it's the only node exposed to UI, and
- * point it to the first profile dev. */
+ /* Create the dummy node set to plugged so it's the only node exposed
+ * to UI, and point it to the first profile dev. */
active = (struct bt_node *)calloc(1, sizeof(*active));
if (!active)
- goto error;
+ return NULL;
active->base.dev = iodev;
active->base.idx = btio->next_node_id++;
- active->base.type = dev->active_node->type;
+ active->base.type = CRAS_NODE_TYPE_BLUETOOTH;
active->base.volume = 100;
- active->base.stable_id = cras_bt_device_get_stable_id(device);
- active->base.ui_gain_scaler = 1.0f;
- /*
- * If the same headset is connected in wideband mode, we shall assign
- * a separate stable_id so the node priority/preference mechanism in
- * Chrome UI doesn't break.
- */
- if ((active->base.type == CRAS_NODE_TYPE_BLUETOOTH) &&
- (dev->direction == CRAS_STREAM_INPUT))
- active->base.stable_id =
- SuperFastHash((const char *)&active->base.type,
- sizeof(active->base.type),
- active->base.stable_id);
+ active->base.plugged = 1;
+ active->base.stable_id =
+ SuperFastHash(cras_bt_device_object_path(device),
+ strlen(cras_bt_device_object_path(device)),
+ strlen(cras_bt_device_object_path(device)));
active->profile = profile;
active->profile_dev = dev;
+ gettimeofday(&active->base.plugged_time, NULL);
strcpy(active->base.name, dev->info.name);
/* The node name exposed to UI should be a valid UTF8 string. */
if (!is_utf8_string(active->base.name))
@@ -650,20 +547,6 @@ int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
return !!(profile & btnode->profile);
}
-enum cras_bt_device_profile
-cras_bt_io_profile_to_log(struct cras_iodev *bt_iodev)
-{
- struct bt_node *btnode = (struct bt_node *)bt_iodev->active_node;
-
- if (btnode->profile & CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE)
- return CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE;
-
- if (hfp_iodev_is_hsp(btnode->profile_dev))
- return CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
- else
- return CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY;
-}
-
unsigned int cras_bt_io_try_remove(struct cras_iodev *bt_iodev,
struct cras_iodev *dev)
{
diff --git a/cras/src/server/cras_bt_io.h b/cras/src/server/cras_bt_io.h
index a867afd9..b833cd9e 100644
--- a/cras/src/server/cras_bt_io.h
+++ b/cras/src/server/cras_bt_io.h
@@ -30,12 +30,6 @@ int cras_bt_io_append(struct cras_iodev *bt_iodev, struct cras_iodev *dev,
int cras_bt_io_on_profile(struct cras_iodev *bt_iodev,
enum cras_bt_device_profile profile);
-/* Returns A2DP, HFP or HSP that this bt_iodev is running for.
- * Do NOT use this function except for logging.
- */
-enum cras_bt_device_profile
-cras_bt_io_profile_to_log(struct cras_iodev *bt_iodev);
-
/* Dry-run the profile device removal from bt_iodev.
* Returns:
* 0 if the bt_iodev will be empty and should to be destroied
diff --git a/cras/src/server/cras_bt_manager.c b/cras/src/server/cras_bt_manager.c
index a7103406..3a3ea4ae 100644
--- a/cras/src/server/cras_bt_manager.c
+++ b/cras/src/server/cras_bt_manager.c
@@ -19,7 +19,6 @@
#include "cras_bt_player.h"
#include "cras_bt_profile.h"
#include "cras_bt_transport.h"
-#include "cras_bt_battery_provider.h"
#include "utlist.h"
struct cras_bt_event_log *btlog;
@@ -42,6 +41,9 @@ static void cras_bt_interface_added(DBusConnection *conn,
if (adapter) {
cras_bt_adapter_update_properties(
adapter, properties_array_iter, NULL);
+ cras_bt_register_endpoints(conn, adapter);
+ cras_bt_register_player(conn, adapter);
+ cras_bt_register_profiles(conn);
syslog(LOG_INFO, "Bluetooth Adapter: %s added",
cras_bt_adapter_address(adapter));
@@ -52,28 +54,6 @@ static void cras_bt_interface_added(DBusConnection *conn,
}
}
- } else if (strcmp(interface_name, BLUEZ_INTERFACE_MEDIA) == 0) {
- struct cras_bt_adapter *adapter;
-
- adapter = cras_bt_adapter_get(object_path);
- if (adapter) {
- cras_bt_register_endpoints(conn, adapter);
- cras_bt_register_player(conn, adapter);
-
- syslog(LOG_INFO,
- "Bluetooth Endpoint and/or Player: %s added",
- cras_bt_adapter_address(adapter));
- } else {
- syslog(LOG_WARNING,
- "Failed to create Bluetooth Endpoint and/or Player: %s",
- object_path);
- }
-
- } else if (strcmp(interface_name, BLUEZ_PROFILE_MGMT_INTERFACE) == 0) {
- cras_bt_register_profiles(conn);
-
- syslog(LOG_INFO, "Bluetooth Profile Manager added");
-
} else if (strcmp(interface_name, BLUEZ_INTERFACE_DEVICE) == 0) {
struct cras_bt_device *device;
@@ -121,32 +101,6 @@ static void cras_bt_interface_added(DBusConnection *conn,
object_path);
}
}
- } else if (strcmp(interface_name,
- BLUEZ_INTERFACE_BATTERY_PROVIDER_MANAGER) == 0) {
- struct cras_bt_adapter *adapter;
- int ret;
-
- syslog(LOG_INFO,
- "Bluetooth Battery Provider Manager available");
-
- adapter = cras_bt_adapter_get(object_path);
- if (adapter) {
- syslog(LOG_INFO,
- "Registering Battery Provider for adapter %s",
- cras_bt_adapter_address(adapter));
- ret = cras_bt_register_battery_provider(conn, adapter);
- if (ret != 0) {
- syslog(LOG_ERR,
- "Error registering Battery Provider "
- "for adapter %s: %s",
- cras_bt_adapter_address(adapter),
- strerror(-ret));
- }
- } else {
- syslog(LOG_WARNING,
- "Adapter not available when trying to create "
- "Battery Provider");
- }
}
}
@@ -185,10 +139,6 @@ static void cras_bt_interface_removed(DBusConnection *conn,
cras_bt_transport_object_path(transport));
cras_bt_transport_remove(transport);
}
- } else if (strcmp(interface_name,
- BLUEZ_INTERFACE_BATTERY_PROVIDER_MANAGER) == 0) {
- syslog(LOG_INFO, "Bluetooth Battery Provider Manager removed");
- cras_bt_battery_provider_reset();
}
}
diff --git a/cras/src/server/cras_bt_player.c b/cras/src/server/cras_bt_player.c
index 446cd916..13343a65 100644
--- a/cras/src/server/cras_bt_player.c
+++ b/cras/src/server/cras_bt_player.c
@@ -4,18 +4,17 @@
*/
#include <dbus/dbus.h>
#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <syslog.h>
-#include "cras_bt_adapter.h"
#include "cras_bt_constants.h"
+#include "cras_bt_adapter.h"
#include "cras_bt_player.h"
#include "cras_dbus_util.h"
-#include "cras_utf8.h"
#include "utlist.h"
+#define CRAS_DEFAULT_PLAYER "/org/chromium/Cras/Bluetooth/DefaultPlayer"
+
static void cras_bt_on_player_registered(DBusPendingCall *pending_call,
void *data)
{
@@ -110,11 +109,10 @@ static int cras_bt_add_player(DBusConnection *conn,
*/
static struct cras_bt_player player = {
.object_path = CRAS_DEFAULT_PLAYER,
- .playback_status = NULL,
- .identity = NULL,
+ .playback_status = "playing",
+ .identity = "DefaultPlayer",
.loop_status = "None",
.shuffle = 0,
- .metadata = NULL,
.position = 0,
.can_go_next = 0,
.can_go_prev = 0,
@@ -136,123 +134,6 @@ static DBusHandlerResult cras_bt_player_handle_message(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static struct cras_bt_player_metadata *cras_bt_player_metadata_init()
-{
- struct cras_bt_player_metadata *metadata =
- malloc(sizeof(struct cras_bt_player_metadata));
- metadata->title = calloc(1, CRAS_PLAYER_METADATA_SIZE_MAX);
- metadata->album = calloc(1, CRAS_PLAYER_METADATA_SIZE_MAX);
- metadata->artist = calloc(1, CRAS_PLAYER_METADATA_SIZE_MAX);
- metadata->length = 0;
-
- return metadata;
-}
-
-static void cras_bt_player_init()
-{
- player.playback_status = malloc(CRAS_PLAYER_PLAYBACK_STATUS_SIZE_MAX);
- player.identity = malloc(CRAS_PLAYER_IDENTITY_SIZE_MAX);
-
- strcpy(player.playback_status, CRAS_PLAYER_PLAYBACK_STATUS_DEFAULT);
- strcpy(player.identity, CRAS_PLAYER_IDENTITY_DEFAULT);
- player.position = 0;
-
- player.metadata = cras_bt_player_metadata_init();
-}
-
-static void cras_bt_player_append_metadata_artist(DBusMessageIter *iter,
- const char *artist)
-{
- DBusMessageIter dict, varient, array;
- const char *artist_key = "xesam:artist";
-
- dbus_message_iter_open_container(iter, DBUS_TYPE_DICT_ENTRY, NULL,
- &dict);
- dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &artist_key);
- dbus_message_iter_open_container(
- &dict, DBUS_TYPE_VARIANT,
- DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, &varient);
- dbus_message_iter_open_container(&varient, DBUS_TYPE_ARRAY,
- DBUS_TYPE_STRING_AS_STRING, &array);
- dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &artist);
- dbus_message_iter_close_container(&varient, &array);
- dbus_message_iter_close_container(&dict, &varient);
- dbus_message_iter_close_container(iter, &dict);
-}
-
-static void cras_bt_player_append_metadata(DBusMessageIter *iter,
- const char *title,
- const char *artist,
- const char *album,
- dbus_int64_t length)
-{
- DBusMessageIter varient, array;
- dbus_message_iter_open_container(
- iter, DBUS_TYPE_VARIANT,
- DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
- DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &varient);
- dbus_message_iter_open_container(
- &varient, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &array);
- if (!is_utf8_string(title)) {
- syslog(LOG_INFO, "Non-utf8 title: %s", title);
- title = "";
- }
- if (!is_utf8_string(album)) {
- syslog(LOG_INFO, "Non-utf8 album: %s", album);
- album = "";
- }
- if (!is_utf8_string(artist)) {
- syslog(LOG_INFO, "Non-utf8 artist: %s", artist);
- artist = "";
- }
-
- append_key_value(&array, "xesam:title", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &title);
- append_key_value(&array, "xesam:album", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &album);
- append_key_value(&array, "mpris:length", DBUS_TYPE_INT64,
- DBUS_TYPE_INT64_AS_STRING, &length);
- cras_bt_player_append_metadata_artist(&array, artist);
-
- dbus_message_iter_close_container(&varient, &array);
- dbus_message_iter_close_container(iter, &varient);
-}
-
-static bool cras_bt_player_parse_metadata(const char *title, const char *album,
- const char *artist,
- const dbus_int64_t length)
-{
- bool require_update = false;
-
- if (title && strcmp(player.metadata->title, title)) {
- snprintf(player.metadata->title, CRAS_PLAYER_METADATA_SIZE_MAX,
- "%s", title);
- require_update = true;
- }
- if (artist && strcmp(player.metadata->artist, artist)) {
- snprintf(player.metadata->artist, CRAS_PLAYER_METADATA_SIZE_MAX,
- "%s", artist);
- require_update = true;
- }
- if (album && strcmp(player.metadata->album, album)) {
- snprintf(player.metadata->album, CRAS_PLAYER_METADATA_SIZE_MAX,
- "%s", album);
- require_update = true;
- }
- if (length && player.metadata->length != length) {
- player.metadata->length = length;
- require_update = true;
- }
-
- return require_update;
-}
-
int cras_bt_player_create(DBusConnection *conn)
{
static const DBusObjectPathVTable player_vtable = {
@@ -265,7 +146,6 @@ int cras_bt_player_create(DBusConnection *conn)
dbus_error_init(&dbus_error);
- cras_bt_player_init();
if (!dbus_connection_register_object_path(
conn, player.object_path, &player_vtable, &dbus_error)) {
syslog(LOG_ERR, "Cannot register player %s",
@@ -286,201 +166,3 @@ int cras_bt_register_player(DBusConnection *conn,
{
return cras_bt_add_player(conn, adapter, &player);
}
-
-int cras_bt_player_update_playback_status(DBusConnection *conn,
- const char *status)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict;
- const char *playerInterface = BLUEZ_INTERFACE_MEDIA_PLAYER;
-
- if (!player.playback_status)
- return -ENXIO;
-
- /* Verify the string value matches one of the possible status defined in
- * bluez/profiles/audio/avrcp.c
- */
- if (strcasecmp(status, "stopped") != 0 &&
- strcasecmp(status, "playing") != 0 &&
- strcasecmp(status, "paused") != 0 &&
- strcasecmp(status, "forward-seek") != 0 &&
- strcasecmp(status, "reverse-seek") != 0 &&
- strcasecmp(status, "error") != 0)
- return -EINVAL;
-
- if (!strcasecmp(player.playback_status, status))
- return 0;
-
- strcpy(player.playback_status, status);
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_PLAYER,
- DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- if (!msg)
- return -ENOMEM;
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &playerInterface);
- dbus_message_iter_open_container(
- &iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict);
- append_key_value(&dict, "PlaybackStatus", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &status);
- dbus_message_iter_close_container(&iter, &dict);
-
- if (!dbus_connection_send(conn, msg, NULL)) {
- dbus_message_unref(msg);
- return -ENOMEM;
- }
-
- dbus_message_unref(msg);
- return 0;
-}
-
-int cras_bt_player_update_identity(DBusConnection *conn, const char *identity)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict;
- const char *playerInterface = BLUEZ_INTERFACE_MEDIA_PLAYER;
-
- if (!player.identity)
- return -ENXIO;
-
- if (!identity)
- return -EINVAL;
-
- if (!is_utf8_string(identity)) {
- syslog(LOG_INFO, "Non-utf8 identity: %s", identity);
- identity = "";
- }
-
- if (!strcasecmp(player.identity, identity))
- return 0;
-
- strcpy(player.identity, identity);
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_PLAYER,
- DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- if (!msg)
- return -ENOMEM;
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &playerInterface);
- dbus_message_iter_open_container(
- &iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict);
- append_key_value(&dict, "Identity", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING, &identity);
- dbus_message_iter_close_container(&iter, &dict);
-
- if (!dbus_connection_send(conn, msg, NULL)) {
- dbus_message_unref(msg);
- return -ENOMEM;
- }
-
- dbus_message_unref(msg);
- return 0;
-}
-
-int cras_bt_player_update_position(DBusConnection *conn,
- const dbus_int64_t position)
-{
- DBusMessage *msg;
- DBusMessageIter iter, dict;
- const char *playerInterface = BLUEZ_INTERFACE_MEDIA_PLAYER;
-
- if (position < 0)
- return -EINVAL;
-
- player.position = position;
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_PLAYER,
- DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- if (!msg)
- return -ENOMEM;
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &playerInterface);
- dbus_message_iter_open_container(
- &iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &dict);
- append_key_value(&dict, "Position", DBUS_TYPE_INT64,
- DBUS_TYPE_INT64_AS_STRING, &player.position);
- dbus_message_iter_close_container(&iter, &dict);
-
- if (!dbus_connection_send(conn, msg, NULL)) {
- dbus_message_unref(msg);
- return -ENOMEM;
- }
-
- dbus_message_unref(msg);
- return 0;
-}
-
-int cras_bt_player_update_metadata(DBusConnection *conn, const char *title,
- const char *artist, const char *album,
- const dbus_int64_t length)
-{
- DBusMessage *msg;
- DBusMessageIter iter, array, dict;
- const char *property = "Metadata";
- const char *playerInterface = BLUEZ_INTERFACE_MEDIA_PLAYER;
-
- if (!player.metadata)
- return -ENXIO;
-
- msg = dbus_message_new_signal(CRAS_DEFAULT_PLAYER,
- DBUS_INTERFACE_PROPERTIES,
- "PropertiesChanged");
- if (!msg)
- return -ENOMEM;
-
- dbus_message_iter_init_append(msg, &iter);
- dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
- &playerInterface);
- dbus_message_iter_open_container(
- &iter, DBUS_TYPE_ARRAY,
- DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
- DBUS_TYPE_VARIANT_AS_STRING
- DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
- &array);
- dbus_message_iter_open_container(&array, DBUS_TYPE_DICT_ENTRY, NULL,
- &dict);
- dbus_message_iter_append_basic(&dict, DBUS_TYPE_STRING, &property);
-
- if (!cras_bt_player_parse_metadata(title, album, artist, length)) {
- /* Nothing to update. */
- dbus_message_unref(msg);
- return 0;
- }
-
- cras_bt_player_append_metadata(&dict, player.metadata->title,
- player.metadata->artist,
- player.metadata->album,
- player.metadata->length);
-
- dbus_message_iter_close_container(&array, &dict);
- dbus_message_iter_close_container(&iter, &array);
-
- if (!dbus_connection_send(conn, msg, NULL)) {
- dbus_message_unref(msg);
- return -ENOMEM;
- }
-
- dbus_message_unref(msg);
- return 0;
-}
diff --git a/cras/src/server/cras_bt_player.h b/cras/src/server/cras_bt_player.h
index 25a6c8c5..9b66d70e 100644
--- a/cras/src/server/cras_bt_player.h
+++ b/cras/src/server/cras_bt_player.h
@@ -11,27 +11,16 @@
#include "cras_bt_adapter.h"
-/* Object to hold current metadata. This is not a full list of what BlueZ/MPRIS
- * supports but a subset because Chromium only provides the following.
- */
-struct cras_bt_player_metadata {
- char *title;
- char *artist;
- char *album;
- int64_t length;
-};
-
/* Object to register as media player so that bluetoothd will report hardware
* volume from device through bt_transport. Properties of the player are defined
* in BlueZ's media API.
*/
struct cras_bt_player {
const char *object_path;
- char *playback_status;
- char *identity;
+ const char *playback_status;
+ const char *identity;
const char *loop_status;
- struct cras_bt_player_metadata *metadata;
- int64_t position;
+ int position;
bool can_go_next;
bool can_go_prev;
bool can_play;
@@ -56,40 +45,4 @@ int cras_bt_player_create(DBusConnection *conn);
int cras_bt_register_player(DBusConnection *conn,
const struct cras_bt_adapter *adapter);
-/* Updates playback status for player and notifies bluetoothd
- * Args:
- * conn - The dbus connection.
- * status - The player playback status.
- */
-int cras_bt_player_update_playback_status(DBusConnection *conn,
- const char *status);
-
-/* Updates the player identity and notifies bluetoothd.
- * Args:
- * conn - The dbus connection.
- * identity - The identity of the registered player. This could be the name
- * of the app or the name of the site playing media.
- */
-int cras_bt_player_update_identity(DBusConnection *conn, const char *identity);
-
-/* Updates the player current track's position and notifies bluetoothd.
- * Args:
- * conn - The dbus connection.
- * position - The current track position in microseconds.
- */
-int cras_bt_player_update_position(DBusConnection *conn,
- const dbus_int64_t position);
-
-/* Updates the player current metadata and notifies bluetoothd.
- * Args:
- * conn - The dbus connection.
- * title - The title associated to the current media session.
- * artist - The artist associated to the current media session.
- * album - The album associated to the current media session.
- * length - The duration in microseconds associated to the current media
- * session.
- */
-int cras_bt_player_update_metadata(DBusConnection *conn, const char *title,
- const char *artist, const char *album,
- const dbus_int64_t length);
#endif /* CRAS_BT_PLAYER_H_ */
diff --git a/cras/src/server/cras_bt_profile.c b/cras/src/server/cras_bt_profile.c
index 9b4171fa..d180a1b4 100644
--- a/cras/src/server/cras_bt_profile.c
+++ b/cras/src/server/cras_bt_profile.c
@@ -362,46 +362,6 @@ int cras_bt_register_profile(DBusConnection *conn,
return 0;
}
-int cras_bt_unregister_profile(DBusConnection *conn,
- struct cras_bt_profile *profile)
-{
- DBusMessage *method_call;
- DBusMessageIter message_iter;
- DBusError dbus_error;
- DBusMessage *reply;
-
- method_call = dbus_message_new_method_call(BLUEZ_SERVICE,
- PROFILE_MANAGER_OBJ_PATH,
- BLUEZ_PROFILE_MGMT_INTERFACE,
- "UnregisterProfile");
-
- if (!method_call)
- return -ENOMEM;
- dbus_error_init(&dbus_error);
- dbus_message_iter_init_append(method_call, &message_iter);
- dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
- &profile->object_path);
- reply = dbus_connection_send_with_reply_and_block(
- conn, method_call, DBUS_TIMEOUT_USE_DEFAULT, &dbus_error);
-
- if (!reply) {
- dbus_error_free(&dbus_error);
- dbus_message_unref(method_call);
- return -EIO;
- }
-
- dbus_message_unref(method_call);
-
- if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
- syslog(LOG_ERR, "Unregister profile returned error: %s",
- dbus_message_get_error_name(reply));
- dbus_message_unref(reply);
- return -EIO;
- }
- dbus_message_unref(reply);
- return 0;
-}
-
int cras_bt_register_profiles(DBusConnection *conn)
{
struct cras_bt_profile *profile;
@@ -439,19 +399,6 @@ int cras_bt_add_profile(DBusConnection *conn, struct cras_bt_profile *profile)
return 0;
}
-int cras_bt_rm_profile(DBusConnection *conn, struct cras_bt_profile *profile)
-{
- DL_DELETE(profiles, profile);
-
- if (!dbus_connection_unregister_object_path(conn,
- profile->object_path)) {
- syslog(LOG_ERR, "Could not unregister BT profile %s",
- profile->object_path);
- return -ENOMEM;
- }
- return 0;
-}
-
void cras_bt_profile_reset()
{
struct cras_bt_profile *profile;
diff --git a/cras/src/server/cras_bt_profile.h b/cras/src/server/cras_bt_profile.h
index 4f8ab448..ed426605 100644
--- a/cras/src/server/cras_bt_profile.h
+++ b/cras/src/server/cras_bt_profile.h
@@ -41,13 +41,6 @@ struct cras_bt_profile {
*/
int cras_bt_add_profile(DBusConnection *conn, struct cras_bt_profile *profile);
-/* Removes |profile| from the list of profiles registered with bluez.
- * Args:
- * conn - The dbus connection.
- * profile - Pointer to the profile structure to be removed.
- */
-int cras_bt_rm_profile(DBusConnection *conn, struct cras_bt_profile *profile);
-
/* Gets the profile by object path.
* Args:
* path - The object path of the desired profile.
@@ -64,22 +57,6 @@ void cras_bt_profile_reset();
/* Notifies all profiles when a device is disconnected. */
void cras_bt_profile_on_device_disconnected(struct cras_bt_device *device);
-/* Registeres |profile| with bluez.
- * Args:
- * conn - The dbus connection.
- * profile - Pointer to the profile structure to be registered.
- */
-int cras_bt_register_profile(DBusConnection *conn,
- struct cras_bt_profile *profile);
-
-/* Unregisteres |profile| with bluez.
- * Args:
- * conn - The dbus connection.
- * profile - Pointer to the profile structure to be unregistered.
- */
-int cras_bt_unregister_profile(DBusConnection *conn,
- struct cras_bt_profile *profile);
-
/* Registers all added profiles.
* Args:
* conn - The dbus connection.
diff --git a/cras/src/server/cras_bt_transport.c b/cras/src/server/cras_bt_transport.c
index 402cd75a..9e06dacf 100644
--- a/cras/src/server/cras_bt_transport.c
+++ b/cras/src/server/cras_bt_transport.c
@@ -17,7 +17,6 @@
#include "cras_bt_log.h"
#include "cras_bt_transport.h"
#include "cras_bt_constants.h"
-#include "cras_system_state.h"
#include "utlist.h"
struct cras_bt_transport {
@@ -101,8 +100,6 @@ void cras_bt_transport_destroy(struct cras_bt_transport *transport)
if (transport->fd >= 0)
close(transport->fd);
- cras_bt_device_set_use_hardware_volume(transport->device, 0);
-
free(transport->object_path);
free(transport->configuration);
free(transport);
@@ -287,24 +284,17 @@ void cras_bt_transport_update_properties(struct cras_bt_transport *transport,
} else if (type == DBUS_TYPE_OBJECT_PATH) {
const char *obj_path;
- if (strcmp(key, "Device") == 0) {
- /* Property: object Device [readonly] */
- dbus_message_iter_get_basic(&variant_iter,
- &obj_path);
- transport->device =
- cras_bt_device_get(obj_path);
- if (!transport->device) {
- syslog(LOG_ERR,
- "Device %s not found at update "
- "transport properties",
- obj_path);
- transport->device =
- cras_bt_device_create(
- transport->conn,
- obj_path);
- cras_bt_transport_update_device(
- transport);
- }
+ /* Property: object Device [readonly] */
+ dbus_message_iter_get_basic(&variant_iter, &obj_path);
+ transport->device = cras_bt_device_get(obj_path);
+ if (!transport->device) {
+ syslog(LOG_ERR,
+ "Device %s not found at update"
+ "transport properties",
+ obj_path);
+ transport->device = cras_bt_device_create(
+ transport->conn, obj_path);
+ cras_bt_transport_update_device(transport);
}
} else if (strcmp(dbus_message_iter_get_signature(&variant_iter),
"ay") == 0 &&
@@ -331,7 +321,6 @@ void cras_bt_transport_update_properties(struct cras_bt_transport *transport,
dbus_message_iter_get_basic(&variant_iter, &volume);
transport->volume = volume;
- BTLOG(btlog, BT_TRANSPORT_UPDATE_VOLUME, volume, 0);
cras_bt_transport_update_device(transport);
}
@@ -385,7 +374,6 @@ int cras_bt_transport_set_volume(struct cras_bt_transport *transport,
DBusMessageIter message_iter, variant;
DBusPendingCall *pending_call;
- BTLOG(btlog, BT_TRANSPORT_SET_VOLUME, volume, 0);
method_call =
dbus_message_new_method_call(BLUEZ_SERVICE,
transport->object_path,
@@ -476,10 +464,6 @@ int cras_bt_transport_acquire(struct cras_bt_transport *transport)
goto acquire_fail;
}
- if (cras_system_get_bt_fix_a2dp_packet_size_enabled() &&
- transport->write_mtu > A2DP_FIX_PACKET_SIZE)
- transport->write_mtu = A2DP_FIX_PACKET_SIZE;
-
BTLOG(btlog, BT_TRANSPORT_ACQUIRE, 1, transport->fd);
dbus_message_unref(reply);
return 0;
diff --git a/cras/src/server/cras_capture_rclient.c b/cras/src/server/cras_capture_rclient.c
index 9b1f2b84..c13792cd 100644
--- a/cras/src/server/cras_capture_rclient.c
+++ b/cras/src/server/cras_capture_rclient.c
@@ -11,12 +11,63 @@
#include "cras_rclient.h"
#include "cras_rclient_util.h"
#include "cras_rstream.h"
+#include "cras_system_state.h"
#include "cras_types.h"
#include "cras_util.h"
+#include "stream_list.h"
+
+/* Entry point for handling a message from the client. Called from the main
+ * server context. */
+static int ccr_handle_message_from_client(struct cras_rclient *client,
+ const struct cras_server_message *msg,
+ int *fds, unsigned int num_fds)
+{
+ int rc = 0;
+ assert(client && msg);
+
+ rc = rclient_validate_message_fds(msg, fds, num_fds);
+ if (rc < 0) {
+ for (int i = 0; i < (int)num_fds; i++)
+ if (fds[i] >= 0)
+ close(fds[i]);
+ return rc;
+ }
+ int fd = num_fds > 0 ? fds[0] : -1;
+
+ switch (msg->id) {
+ case CRAS_SERVER_CONNECT_STREAM: {
+ int client_shm_fd = num_fds > 1 ? fds[1] : -1;
+ struct cras_connect_message cmsg;
+ if (MSG_LEN_VALID(msg, struct cras_connect_message)) {
+ rc = rclient_handle_client_stream_connect(
+ client,
+ (const struct cras_connect_message *)msg, fd,
+ client_shm_fd);
+ } else if (!convert_connect_message_old(msg, &cmsg)) {
+ rc = rclient_handle_client_stream_connect(
+ client, &cmsg, fd, client_shm_fd);
+ } else {
+ return -EINVAL;
+ }
+ break;
+ }
+ case CRAS_SERVER_DISCONNECT_STREAM:
+ if (!MSG_LEN_VALID(msg, struct cras_disconnect_stream_message))
+ return -EINVAL;
+ rc = rclient_handle_client_stream_disconnect(
+ client,
+ (const struct cras_disconnect_stream_message *)msg);
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
/* Declarations of cras_rclient operators for cras_capture_rclient. */
static const struct cras_rclient_ops cras_capture_rclient_ops = {
- .handle_message_from_client = rclient_handle_message_from_client,
+ .handle_message_from_client = ccr_handle_message_from_client,
.send_message_to_client = rclient_send_message_to_client,
.destroy = rclient_destroy,
};
@@ -29,7 +80,24 @@ static const struct cras_rclient_ops cras_capture_rclient_ops = {
* the connection has succeeded. */
struct cras_rclient *cras_capture_rclient_create(int fd, size_t id)
{
- return rclient_generic_create(
- fd, id, &cras_capture_rclient_ops,
- cras_stream_direction_mask(CRAS_STREAM_INPUT));
+ struct cras_rclient *client;
+ struct cras_client_connected msg;
+ int state_fd;
+
+ client = (struct cras_rclient *)calloc(1, sizeof(struct cras_rclient));
+ if (!client)
+ return NULL;
+
+ client->fd = fd;
+ client->id = id;
+
+ client->ops = &cras_capture_rclient_ops;
+ client->supported_directions =
+ cras_stream_direction_mask(CRAS_STREAM_INPUT);
+
+ cras_fill_client_connected(&msg, client->id);
+ state_fd = cras_sys_state_shm_fd();
+ client->ops->send_message_to_client(client, &msg.header, &state_fd, 1);
+
+ return client;
}
diff --git a/cras/src/server/cras_control_rclient.c b/cras/src/server/cras_control_rclient.c
index cd0c4d3b..c0eea5d6 100644
--- a/cras/src/server/cras_control_rclient.c
+++ b/cras/src/server/cras_control_rclient.c
@@ -15,8 +15,6 @@
#include "cras_dsp.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
-#include "cras_hfp_ag_profile.h"
-#include "cras_main_thread_log.h"
#include "cras_messages.h"
#include "cras_observer.h"
#include "cras_rclient.h"
@@ -25,6 +23,7 @@
#include "cras_system_state.h"
#include "cras_types.h"
#include "cras_util.h"
+#include "stream_list.h"
#include "utlist.h"
/* Handles dumping audio thread debug info back to the client. */
@@ -272,14 +271,7 @@ static int direction_valid(enum CRAS_STREAM_DIRECTION direction)
}
/* Entry point for handling a message from the client. Called from the main
- * server context.
- *
- * If the message from clients has incorrect length (truncated message), return
- * an error up to CRAS server.
- * If the message from clients has invalid content, should return the errors to
- * clients by send_message_to_client and return 0 here.
- *
- */
+ * server context. */
static int ccr_handle_message_from_client(struct cras_rclient *client,
const struct cras_server_message *msg,
int *fds, unsigned int num_fds)
@@ -299,15 +291,18 @@ static int ccr_handle_message_from_client(struct cras_rclient *client,
switch (msg->id) {
case CRAS_SERVER_CONNECT_STREAM: {
int client_shm_fd = num_fds > 1 ? fds[1] : -1;
+ struct cras_connect_message cmsg;
if (MSG_LEN_VALID(msg, struct cras_connect_message)) {
- rclient_handle_client_stream_connect(
+ return rclient_handle_client_stream_connect(
client,
(const struct cras_connect_message *)msg, fd,
client_shm_fd);
+ } else if (!convert_connect_message_old(msg, &cmsg)) {
+ return rclient_handle_client_stream_connect(
+ client, &cmsg, fd, client_shm_fd);
} else {
return -EINVAL;
}
- break;
}
case CRAS_SERVER_DISCONNECT_STREAM:
if (!MSG_LEN_VALID(msg, struct cras_disconnect_stream_message))
@@ -340,6 +335,14 @@ static int ccr_handle_message_from_client(struct cras_rclient *client,
cras_system_set_mute_locked(
((const struct cras_set_system_mute *)msg)->mute);
break;
+ case CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN: {
+ const struct cras_set_system_capture_gain *m =
+ (const struct cras_set_system_capture_gain *)msg;
+ if (!MSG_LEN_VALID(msg, struct cras_set_system_capture_gain))
+ return -EINVAL;
+ cras_system_set_capture_gain(m->gain);
+ break;
+ }
case CRAS_SERVER_SET_SYSTEM_CAPTURE_MUTE:
if (!MSG_LEN_VALID(msg, struct cras_set_system_mute))
return -EINVAL;
@@ -399,19 +402,6 @@ static int ccr_handle_message_from_client(struct cras_rclient *client,
case CRAS_SERVER_GET_ATLOG_FD:
get_atlog_fd(client);
break;
- case CRAS_SERVER_DUMP_MAIN: {
- struct cras_client_audio_debug_info_ready msg;
- struct cras_server_state *state;
-
- state = cras_system_state_get_no_lock();
- memcpy(&state->main_thread_debug_info.main_log, main_log,
- sizeof(struct main_thread_event_log));
-
- cras_fill_client_audio_debug_info_ready(&msg);
- client->ops->send_message_to_client(client, &msg.header, NULL,
- 0);
- break;
- }
case CRAS_SERVER_DUMP_BT: {
struct cras_client_audio_debug_info_ready msg;
struct cras_server_state *state;
@@ -419,15 +409,10 @@ static int ccr_handle_message_from_client(struct cras_rclient *client,
state = cras_system_state_get_no_lock();
#ifdef CRAS_DBUS
memcpy(&state->bt_debug_info.bt_log, btlog,
- sizeof(struct cras_bt_event_log));
- memcpy(&state->bt_debug_info.wbs_logger,
- cras_hfp_ag_get_wbs_logger(),
- sizeof(struct packet_status_logger));
+ sizeof(struct cras_bt_debug_info));
#else
memset(&state->bt_debug_info.bt_log, 0,
sizeof(struct cras_bt_debug_info));
- memset(&state->bt_debug_info.wbs_logger, 0,
- sizeof(struct packet_status_logger));
#endif
cras_fill_client_audio_debug_info_ready(&msg);
@@ -473,33 +458,17 @@ static int ccr_handle_message_from_client(struct cras_rclient *client,
case CRAS_CONFIG_GLOBAL_REMIX: {
const struct cras_config_global_remix *m =
(const struct cras_config_global_remix *)msg;
- float *coefficient;
-
if (!MSG_LEN_VALID(msg, struct cras_config_global_remix) ||
m->num_channels > CRAS_MAX_REMIX_CHANNELS)
return -EINVAL;
- const size_t coefficient_len =
- (size_t)m->num_channels * (size_t)m->num_channels;
- const size_t size_with_coefficients =
- sizeof(*m) +
- coefficient_len * sizeof(m->coefficient[0]);
+ size_t size_with_coefficients =
+ sizeof(*m) + m->num_channels * m->num_channels *
+ sizeof(m->coefficient[0]);
if (size_with_coefficients != msg->length)
return -EINVAL;
-
- coefficient =
- (float *)calloc(coefficient_len, sizeof(coefficient));
- if (!coefficient) {
- syslog(LOG_ERR,
- "Failed to create local coefficient array.");
- break;
- }
- memcpy(coefficient, m->coefficient,
- coefficient_len * sizeof(coefficient));
-
audio_thread_config_global_remix(
cras_iodev_list_get_audio_thread(), m->num_channels,
- coefficient);
- free(coefficient);
+ m->coefficient);
break;
}
case CRAS_SERVER_GET_HOTWORD_MODELS: {
@@ -562,11 +531,25 @@ static const struct cras_rclient_ops cras_control_rclient_ops = {
* the conneciton has succeeded. */
struct cras_rclient *cras_control_rclient_create(int fd, size_t id)
{
- /* Supports all directions but not CRAS_STREAM_UNDEFINED. */
- int supported_directions =
- CRAS_STREAM_ALL_DIRECTION ^
+ struct cras_rclient *client;
+ struct cras_client_connected msg;
+ int state_fd;
+
+ client = (struct cras_rclient *)calloc(1, sizeof(struct cras_rclient));
+ if (!client)
+ return NULL;
+
+ client->fd = fd;
+ client->id = id;
+ client->ops = &cras_control_rclient_ops;
+ client->supported_directions = CRAS_STREAM_ALL_DIRECTION;
+ /* Filters CRAS_STREAM_UNDEFINED stream out. */
+ client->supported_directions ^=
cras_stream_direction_mask(CRAS_STREAM_UNDEFINED);
- return rclient_generic_create(fd, id, &cras_control_rclient_ops,
- supported_directions);
+ cras_fill_client_connected(&msg, client->id);
+ state_fd = cras_sys_state_shm_fd();
+ client->ops->send_message_to_client(client, &msg.header, &state_fd, 1);
+
+ return client;
}
diff --git a/cras/src/server/cras_dbus.c b/cras/src/server/cras_dbus.c
index 5975f1c6..d127485d 100644
--- a/cras/src/server/cras_dbus.c
+++ b/cras/src/server/cras_dbus.c
@@ -15,7 +15,7 @@
#include "cras_system_state.h"
#include "cras_tm.h"
-static void dbus_watch_callback(void *arg, int revents)
+static void dbus_watch_callback(void *arg)
{
DBusWatch *watch = (DBusWatch *)arg;
int r, flags;
@@ -48,8 +48,7 @@ static dbus_bool_t dbus_watch_add(DBusWatch *watch, void *data)
*/
if ((flags & DBUS_WATCH_READABLE) && dbus_watch_get_enabled(watch)) {
r = cras_system_add_select_fd(dbus_watch_get_unix_fd(watch),
- dbus_watch_callback, watch,
- POLLIN);
+ dbus_watch_callback, watch);
if (r != 0)
return FALSE;
}
diff --git a/cras/src/server/cras_dbus_control.c b/cras/src/server/cras_dbus_control.c
index b66e1276..978c64a3 100644
--- a/cras/src/server/cras_dbus_control.c
+++ b/cras/src/server/cras_dbus_control.c
@@ -11,16 +11,12 @@
#include <syslog.h>
#include "audio_thread.h"
-#include "cras_bt_player.h"
#include "cras_dbus.h"
#include "cras_dbus_control.h"
#include "cras_dbus_util.h"
-#include "cras_hfp_ag_profile.h"
#include "cras_iodev_list.h"
-#include "cras_main_thread_log.h"
#include "cras_observer.h"
#include "cras_system_state.h"
-#include "cras_utf8.h"
#include "cras_util.h"
#include "utlist.h"
@@ -50,6 +46,9 @@
" <method name=\"SetSuspendAudio\">\n" \
" <arg name=\"suspend\" type=\"b\" direction=\"in\"/>\n" \
" </method>\n" \
+ " <method name=\"SetInputGain\">\n" \
+ " <arg name=\"gain\" type=\"i\" direction=\"in\"/>\n" \
+ " </method>\n" \
" <method name=\"SetInputNodeGain\">\n" \
" <arg name=\"node_id\" type=\"t\" direction=\"in\"/>\n" \
" <arg name=\"gain\" type=\"i\" direction=\"in\"/>\n" \
@@ -60,6 +59,7 @@
" <method name=\"GetVolumeState\">\n" \
" <arg name=\"output_volume\" type=\"i\" direction=\"out\"/>\n" \
" <arg name=\"output_mute\" type=\"b\" direction=\"out\"/>\n" \
+ " <arg name=\"input_gain\" type=\"i\" direction=\"out\"/>\n" \
" <arg name=\"input_mute\" type=\"b\" direction=\"out\"/>\n" \
" <arg name=\"output_user_mute\" type=\"b\" direction=\"out\"/>\n" \
" </method>\n" \
@@ -75,9 +75,6 @@
" <method name=\"GetSystemAecGroupId\">\n" \
" <arg name=\"group_id\" type=\"i\" direction=\"out\"/>\n" \
" </method>\n" \
- " <method name=\"GetDeprioritizeBtWbsMic\">\n" \
- " <arg name=\"deprioritized\" type=\"b\" direction=\"out\"/>\n" \
- " </method>\n" \
" <method name=\"SetActiveOutputNode\">\n" \
" <arg name=\"node_id\" type=\"t\" direction=\"in\"/>\n" \
" </method>\n" \
@@ -96,9 +93,6 @@
" <method name=\"RemoveActiveOutputNode\">\n" \
" <arg name=\"node_id\" type=\"t\" direction=\"in\"/>\n" \
" </method>\n" \
- " <method name=\"SetFixA2dpPacketSize\">\n" \
- " <arg name=\"toggle\" type=\"b\" direction=\"in\"/>\n" \
- " </method>\n" \
" <method name=\"GetNumberOfActiveStreams\">\n" \
" <arg name=\"num\" type=\"i\" direction=\"out\"/>\n" \
" </method>\n" \
@@ -108,9 +102,6 @@
" <method name=\"GetNumberOfActiveInputStreams\">\n" \
" <arg name=\"num\" type=\"i\" direction=\"out\"/>\n" \
" </method>\n" \
- " <method name=\"GetNumberOfInputStreamsWithPermission\">\n" \
- " <arg name=\"num\" type=\"a{sv}\" direction=\"out\"/>\n" \
- " </method>\n" \
" <method name=\"SetGlobalOutputChannelRemix\">\n" \
" <arg name=\"num_channels\" type=\"i\" direction=\"in\"/>\n" \
" <arg name=\"coefficient\" type=\"ad\" direction=\"in\"/>\n" \
@@ -125,21 +116,6 @@
" <method name=\"SetWbsEnabled\">\n" \
" <arg name=\"enabled\" type=\"b\" direction=\"in\"/>\n" \
" </method>\n" \
- " <method name=\"SetNoiseCancellationEnabled\">\n" \
- " <arg name=\"enabled\" type=\"b\" direction=\"in\"/>\n" \
- " </method>\n" \
- " <method name=\"SetPlayerPlaybackStatus\">\n" \
- " <arg name=\"status\" type=\"s\" direction=\"in\"/>\n" \
- " </method>\n" \
- " <method name=\"SetPlayerIdentity\">\n" \
- " <arg name=\"identity\" type=\"s\" direction=\"in\"/>\n" \
- " </method>\n" \
- " <method name=\"SetPlayerPosition\">\n" \
- " <arg name=\"position\" type=\"x\" direction=\"in\"/>\n" \
- " </method>\n" \
- " <method name=\"SetPlayerMetadata\">\n" \
- " <arg name=\"metadata\" type=\"a{sv}\" direction=\"in\"/>\n" \
- " </method>\n" \
" </interface>\n" \
" <interface name=\"" DBUS_INTERFACE_INTROSPECTABLE "\">\n" \
" <method name=\"Introspect\">\n" \
@@ -172,79 +148,6 @@ static int get_single_arg(DBusMessage *message, int dbus_type, void *arg)
return 0;
}
-static bool get_string_metadata(DBusMessageIter *iter, const char **dst)
-{
- if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING)
- return FALSE;
-
- dbus_message_iter_get_basic(iter, dst);
- return TRUE;
-}
-
-static bool get_int64_metadata(DBusMessageIter *iter, dbus_int64_t *dst)
-{
- if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT64)
- return FALSE;
-
- dbus_message_iter_get_basic(iter, dst);
- return TRUE;
-}
-
-static bool get_metadata(DBusMessage *message, const char **title,
- const char **artist, const char **album,
- dbus_int64_t *length)
-{
- DBusError dbus_error;
- DBusMessageIter iter, dict;
-
- dbus_error_init(&dbus_error);
- dbus_message_iter_init(message, &iter);
-
- if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
- return FALSE;
-
- dbus_message_iter_recurse(&iter, &dict);
-
- while (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_INVALID) {
- DBusMessageIter entry, var;
- const char *key;
-
- if (dbus_message_iter_get_arg_type(&dict) !=
- DBUS_TYPE_DICT_ENTRY)
- return FALSE;
-
- dbus_message_iter_recurse(&dict, &entry);
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
- return FALSE;
-
- dbus_message_iter_get_basic(&entry, &key);
- dbus_message_iter_next(&entry);
-
- if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT)
- return FALSE;
-
- dbus_message_iter_recurse(&entry, &var);
- if (strcasecmp(key, "title") == 0) {
- if (!get_string_metadata(&var, title))
- return FALSE;
- } else if (strcasecmp(key, "artist") == 0) {
- if (!get_string_metadata(&var, artist))
- return FALSE;
- } else if (strcasecmp(key, "album") == 0) {
- if (!get_string_metadata(&var, album))
- return FALSE;
- } else if (strcasecmp(key, "length") == 0) {
- if (!get_int64_metadata(&var, length))
- return FALSE;
- } else
- syslog(LOG_WARNING, "%s not supported, ignoring", key);
-
- dbus_message_iter_next(&dict);
- }
-
- return TRUE;
-}
-
/* Helper to send an empty reply. */
static void send_empty_reply(DBusConnection *conn, DBusMessage *message)
{
@@ -376,7 +279,6 @@ static DBusHandlerResult handle_set_output_user_mute(DBusConnection *conn,
return rc;
cras_system_set_user_mute(new_mute);
- MAINLOG(main_log, MAIN_THREAD_SET_OUTPUT_USER_MUTE, new_mute, 0, 0);
send_empty_reply(conn, message);
@@ -399,6 +301,23 @@ handle_set_suspend_audio(DBusConnection *conn, DBusMessage *message, void *arg)
return DBUS_HANDLER_RESULT_HANDLED;
}
+static DBusHandlerResult handle_set_input_gain(DBusConnection *conn,
+ DBusMessage *message, void *arg)
+{
+ int rc;
+ dbus_int32_t new_gain;
+
+ rc = get_single_arg(message, DBUS_TYPE_INT32, &new_gain);
+ if (rc)
+ return rc;
+
+ cras_system_set_capture_gain(new_gain);
+
+ send_empty_reply(conn, message);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
static DBusHandlerResult handle_set_input_node_gain(DBusConnection *conn,
DBusMessage *message,
void *arg)
@@ -450,6 +369,7 @@ handle_get_volume_state(DBusConnection *conn, DBusMessage *message, void *arg)
dbus_int32_t volume;
dbus_bool_t system_muted;
dbus_bool_t user_muted;
+ dbus_int32_t capture_gain;
dbus_bool_t capture_muted;
reply = dbus_message_new_method_return(message);
@@ -457,10 +377,12 @@ handle_get_volume_state(DBusConnection *conn, DBusMessage *message, void *arg)
volume = cras_system_get_volume();
system_muted = cras_system_get_system_mute();
user_muted = cras_system_get_user_mute();
+ capture_gain = cras_system_get_capture_gain();
capture_muted = cras_system_get_capture_mute();
dbus_message_append_args(reply, DBUS_TYPE_INT32, &volume,
DBUS_TYPE_BOOLEAN, &system_muted,
+ DBUS_TYPE_INT32, &capture_gain,
DBUS_TYPE_BOOLEAN, &capture_muted,
DBUS_TYPE_BOOLEAN, &user_muted,
DBUS_TYPE_INVALID);
@@ -507,6 +429,7 @@ static dbus_bool_t append_node_dict(DBusMessageIter *iter,
dbus_uint64_t stable_dev_id = node->stable_id;
const char *node_type = node->type;
const char *node_name = node->name;
+ const char *mic_positions = node->mic_positions;
dbus_bool_t active;
dbus_uint64_t plugged_time = node->plugged_time.tv_sec * 1000000ULL +
node->plugged_time.tv_usec;
@@ -519,14 +442,6 @@ static dbus_bool_t append_node_dict(DBusMessageIter *iter,
id = (id << 32) | node->ionode_idx;
active = !!node->active;
- // If dev_name is not utf8, libdbus may abort cras.
- if (!is_utf8_string(dev_name)) {
- syslog(LOG_ERR,
- "Non-utf8 device name '%s' cannot be sent via dbus",
- dev_name);
- dev_name = "";
- }
-
if (!dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{sv}",
&dict))
return FALSE;
@@ -552,6 +467,9 @@ static dbus_bool_t append_node_dict(DBusMessageIter *iter,
if (!append_key_value(&dict, "Name", DBUS_TYPE_STRING,
DBUS_TYPE_STRING_AS_STRING, &node_name))
return FALSE;
+ if (!append_key_value(&dict, "MicPositions", DBUS_TYPE_STRING,
+ DBUS_TYPE_STRING_AS_STRING, &mic_positions))
+ return FALSE;
if (!append_key_value(&dict, "Active", DBUS_TYPE_BOOLEAN,
DBUS_TYPE_BOOLEAN_AS_STRING, &active))
return FALSE;
@@ -678,27 +596,6 @@ static DBusHandlerResult handle_get_system_aec_group_id(DBusConnection *conn,
}
static DBusHandlerResult
-handle_get_deprioritize_bt_wbs_mic(DBusConnection *conn, DBusMessage *message,
- void *arg)
-{
- DBusMessage *reply;
- dbus_uint32_t serial = 0;
- dbus_bool_t deprioritized;
-
- reply = dbus_message_new_method_return(message);
-
- deprioritized = cras_system_get_deprioritize_bt_wbs_mic();
- dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &deprioritized,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send(conn, reply, &serial);
-
- dbus_message_unref(reply);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult
handle_set_active_node(DBusConnection *conn, DBusMessage *message, void *arg,
enum CRAS_STREAM_DIRECTION direction)
{
@@ -752,24 +649,6 @@ handle_rm_active_node(DBusConnection *conn, DBusMessage *message, void *arg,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static DBusHandlerResult handle_set_fix_a2dp_packet_size(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- int rc;
- dbus_bool_t enabled = FALSE;
-
- rc = get_single_arg(message, DBUS_TYPE_BOOLEAN, &enabled);
- if (rc)
- return rc;
-
- cras_system_set_bt_fix_a2dp_packet_size_enabled(enabled);
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
static DBusHandlerResult handle_get_num_active_streams(DBusConnection *conn,
DBusMessage *message,
void *arg)
@@ -812,65 +691,6 @@ handle_get_num_active_streams_use_output_hw(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static bool append_num_input_streams_with_permission(
- DBusMessage *message, uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- DBusMessageIter array;
- DBusMessageIter dict;
- unsigned type;
-
- dbus_message_iter_init_append(message, &array);
- for (type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type) {
- const char *client_type_str = cras_client_type_str(type);
- if (!is_utf8_string(client_type_str)) {
- syslog(LOG_ERR,
- "Non-utf8 clinet_type_str '%s' cannot be sent "
- "via dbus",
- client_type_str);
- client_type_str = "";
- }
-
- if (!dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
- "{sv}", &dict))
- return false;
- if (!append_key_value(&dict, "ClientType", DBUS_TYPE_STRING,
- DBUS_TYPE_STRING_AS_STRING,
- &client_type_str))
- return false;
- if (!append_key_value(&dict, "NumStreamsWithPermission",
- DBUS_TYPE_UINT32,
- DBUS_TYPE_UINT32_AS_STRING,
- &num_input_streams[type]))
- return false;
- if (!dbus_message_iter_close_container(&array, &dict))
- return false;
- }
- return true;
-}
-
-static DBusHandlerResult
-handle_get_num_input_streams_with_permission(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- DBusMessage *reply;
- dbus_uint32_t serial = 0;
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE] = {};
-
- reply = dbus_message_new_method_return(message);
-
- cras_system_state_get_input_streams_with_permission(num_input_streams);
- if (!append_num_input_streams_with_permission(reply, num_input_streams))
- goto error;
-
- dbus_connection_send(conn, reply, &serial);
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_HANDLED;
-
-error:
- dbus_message_unref(reply);
- return DBUS_HANDLER_RESULT_NEED_MEMORY;
-}
-
static DBusHandlerResult
handle_set_global_output_channel_remix(DBusConnection *conn,
DBusMessage *message, void *arg)
@@ -961,124 +781,6 @@ static DBusHandlerResult handle_set_wbs_enabled(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static DBusHandlerResult
-handle_set_noise_cancellation_enabled(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- int rc;
- dbus_bool_t enabled;
-
- rc = get_single_arg(message, DBUS_TYPE_BOOLEAN, &enabled);
- if (rc)
- return rc;
-
- cras_system_set_noise_cancellation_enabled(enabled);
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult handle_set_player_playback_status(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- char *status;
- DBusError dbus_error;
- int rc;
-
- dbus_error_init(&dbus_error);
-
- rc = get_single_arg(message, DBUS_TYPE_STRING, &status);
- if (rc)
- return rc;
-
- rc = cras_bt_player_update_playback_status(conn, status);
- if (rc) {
- syslog(LOG_WARNING,
- "CRAS failed to update BT Player Status: %d", rc);
- }
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult handle_set_player_identity(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- char *identity;
- DBusError dbus_error;
- int rc;
-
- dbus_error_init(&dbus_error);
-
- rc = get_single_arg(message, DBUS_TYPE_STRING, &identity);
- if (rc)
- return rc;
-
- rc = cras_bt_player_update_identity(conn, identity);
- if (rc) {
- syslog(LOG_WARNING,
- "CRAS failed to update BT Player Identity: %d", rc);
- }
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult handle_set_player_position(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- dbus_int64_t position;
- DBusError dbus_error;
- int rc;
-
- dbus_error_init(&dbus_error);
-
- rc = get_single_arg(message, DBUS_TYPE_INT64, &position);
- if (rc)
- return rc;
-
- rc = cras_bt_player_update_position(conn, position);
- if (rc) {
- syslog(LOG_WARNING,
- "CRAS failed to update BT Player Position: %d", rc);
- }
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult handle_set_player_metadata(DBusConnection *conn,
- DBusMessage *message,
- void *arg)
-{
- DBusError dbus_error;
- int rc;
-
- dbus_error_init(&dbus_error);
- const char *title = NULL, *artist = NULL, *album = NULL;
- dbus_int64_t length = 0;
-
- if (!get_metadata(message, &title, &artist, &album, &length))
- return -EINVAL;
-
- rc = cras_bt_player_update_metadata(conn, title, artist, album, length);
- if (rc) {
- syslog(LOG_WARNING, "CRAS failed to update BT Metadata: %d",
- rc);
- }
-
- send_empty_reply(conn, message);
-
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
/* Handle incoming messages. */
static DBusHandlerResult handle_control_message(DBusConnection *conn,
DBusMessage *message, void *arg)
@@ -1124,6 +826,9 @@ static DBusHandlerResult handle_control_message(DBusConnection *conn,
"SetSuspendAudio")) {
return handle_set_suspend_audio(conn, message, arg);
} else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
+ "SetInputGain")) {
+ return handle_set_input_gain(conn, message, arg);
+ } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
"SetInputNodeGain")) {
return handle_set_input_node_gain(conn, message, arg);
} else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
@@ -1146,9 +851,6 @@ static DBusHandlerResult handle_control_message(DBusConnection *conn,
"GetSystemAecGroupId")) {
return handle_get_system_aec_group_id(conn, message, arg);
} else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "GetDeprioritizeBtWbsMic")) {
- return handle_get_deprioritize_bt_wbs_mic(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
"SetActiveOutputNode")) {
return handle_set_active_node(conn, message, arg,
CRAS_STREAM_OUTPUT);
@@ -1173,9 +875,6 @@ static DBusHandlerResult handle_control_message(DBusConnection *conn,
return handle_rm_active_node(conn, message, arg,
CRAS_STREAM_OUTPUT);
} else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetFixA2dpPacketSize")) {
- return handle_set_fix_a2dp_packet_size(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
"GetNumberOfActiveStreams")) {
return handle_get_num_active_streams(conn, message, arg);
} else if (dbus_message_is_method_call(
@@ -1185,11 +884,6 @@ static DBusHandlerResult handle_control_message(DBusConnection *conn,
arg);
} else if (dbus_message_is_method_call(
message, CRAS_CONTROL_INTERFACE,
- "GetNumberOfInputStreamsWithPermission")) {
- return handle_get_num_input_streams_with_permission(
- conn, message, arg);
- } else if (dbus_message_is_method_call(
- message, CRAS_CONTROL_INTERFACE,
"GetNumberOfActiveOutputStreams")) {
return handle_get_num_active_streams_use_output_hw(
conn, message, arg);
@@ -1206,22 +900,6 @@ static DBusHandlerResult handle_control_message(DBusConnection *conn,
} else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
"SetWbsEnabled")) {
return handle_set_wbs_enabled(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetNoiseCancellationEnabled")) {
- return handle_set_noise_cancellation_enabled(conn, message,
- arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetPlayerPlaybackStatus")) {
- return handle_set_player_playback_status(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetPlayerIdentity")) {
- return handle_set_player_identity(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetPlayerPosition")) {
- return handle_set_player_position(conn, message, arg);
- } else if (dbus_message_is_method_call(message, CRAS_CONTROL_INTERFACE,
- "SetPlayerMetadata")) {
- return handle_set_player_metadata(conn, message, arg);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -1333,8 +1011,8 @@ static void signal_active_node_changed(void *context,
dbus_uint32_t serial = 0;
msg = create_dbus_message((dir == CRAS_STREAM_OUTPUT) ?
- "ActiveOutputNodeChanged" :
- "ActiveInputNodeChanged");
+ "ActiveOutputNodeChanged" :
+ "ActiveInputNodeChanged");
if (!msg)
return;
dbus_message_append_args(msg, DBUS_TYPE_UINT64, &node_id,
@@ -1418,25 +1096,6 @@ static void signal_num_active_streams_changed(void *context,
dbus_message_unref(msg);
}
-static void signal_num_input_streams_with_permission_changed(
- void *context, uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- struct cras_dbus_control *control = (struct cras_dbus_control *)context;
- dbus_uint32_t serial = 0;
- DBusMessage *msg;
-
- msg = create_dbus_message("NumberOfInputStreamsWithPermissionChanged");
- if (!msg)
- return;
-
- if (!append_num_input_streams_with_permission(msg, num_input_streams))
- goto error;
-
- dbus_connection_send(control->conn, msg, &serial);
-error:
- dbus_message_unref(msg);
-}
-
static void signal_hotword_triggered(void *context, int64_t tv_sec,
int64_t tv_nsec)
{
@@ -1502,8 +1161,6 @@ void cras_dbus_control_start(DBusConnection *conn)
observer_ops.capture_mute_changed = signal_capture_mute;
observer_ops.num_active_streams_changed =
signal_num_active_streams_changed;
- observer_ops.num_input_streams_with_permission_changed =
- signal_num_input_streams_with_permission_changed;
observer_ops.nodes_changed = signal_nodes_changed;
observer_ops.active_node_changed = signal_active_node_changed;
observer_ops.input_node_gain_changed = signal_node_capture_gain_changed;
diff --git a/cras/src/server/cras_device_monitor.c b/cras/src/server/cras_device_monitor.c
index e9730a0b..7dd0f5d7 100644
--- a/cras/src/server/cras_device_monitor.c
+++ b/cras/src/server/cras_device_monitor.c
@@ -13,7 +13,6 @@
enum CRAS_DEVICE_MONITOR_MSG_TYPE {
RESET_DEVICE,
SET_MUTE_STATE,
- ERROR_CLOSE,
};
struct cras_device_monitor_message {
@@ -63,21 +62,6 @@ int cras_device_monitor_set_device_mute_state(unsigned int dev_idx)
return 0;
}
-int cras_device_monitor_error_close(unsigned int dev_idx)
-{
- struct cras_device_monitor_message msg;
- int err;
-
- init_device_msg(&msg, ERROR_CLOSE, dev_idx);
- err = cras_main_message_send((struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send device message %d",
- ERROR_CLOSE);
- return err;
- }
- return 0;
-}
-
/* When device is in a bad state, e.g. severe underrun,
* it might break how audio thread works and cause busy wake up loop.
* Resetting the device can bring device back to normal state.
@@ -100,10 +84,6 @@ static void handle_device_message(struct cras_main_message *msg, void *arg)
case SET_MUTE_STATE:
cras_iodev_list_set_dev_mute(device_msg->dev_idx);
break;
- case ERROR_CLOSE:
- syslog(LOG_ERR, "Close erroneous device in main thread");
- cras_iodev_list_suspend_dev(device_msg->dev_idx);
- break;
default:
syslog(LOG_ERR, "Unknown device message type %u",
device_msg->message_type);
diff --git a/cras/src/server/cras_device_monitor.h b/cras/src/server/cras_device_monitor.h
index eca2372b..ac31adb9 100644
--- a/cras/src/server/cras_device_monitor.h
+++ b/cras/src/server/cras_device_monitor.h
@@ -15,8 +15,4 @@ int cras_device_monitor_set_device_mute_state(unsigned int dev_idx);
/* Initializes device monitor and sets main thread callback. */
int cras_device_monitor_init();
-/* Asks main thread to close device because error has occured in audio
- * thread. */
-int cras_device_monitor_error_close(unsigned int dev_idx);
-
#endif /* CRAS_DEVICE_MONITOR_H_ */
diff --git a/cras/src/server/cras_dsp.c b/cras/src/server/cras_dsp.c
index 9c4cc7b5..1a2707d3 100644
--- a/cras/src/server/cras_dsp.c
+++ b/cras/src/server/cras_dsp.c
@@ -36,7 +36,7 @@ struct cras_dsp_context {
static struct dumper *syslog_dumper;
static const char *ini_filename;
-static struct ini *global_ini;
+static struct ini *ini;
static struct cras_dsp_context *context_list;
static void initialize_environment(struct cras_expr_env *env)
@@ -60,7 +60,7 @@ static void destroy_pipeline(struct pipeline *pipeline)
* this ini so its life cycle is aligned with the associated dsp
* pipeline.
*/
- if (private_ini && (private_ini != global_ini))
+ if (private_ini && (private_ini != ini))
cras_dsp_ini_free(private_ini);
}
@@ -123,21 +123,19 @@ static void cmd_load_pipeline(struct cras_dsp_context *ctx,
static void cmd_reload_ini()
{
- struct ini *old_ini = global_ini;
+ struct ini *old_ini = ini;
struct cras_dsp_context *ctx;
- struct ini *new_ini = cras_dsp_ini_create(ini_filename);
- if (!new_ini) {
+ ini = cras_dsp_ini_create(ini_filename);
+ if (!ini) {
syslog(LOG_DEBUG, "cannot create dsp ini");
return;
}
DL_FOREACH (context_list, ctx) {
- cmd_load_pipeline(ctx, new_ini);
+ cmd_load_pipeline(ctx, ini);
}
- global_ini = new_ini;
-
if (old_ini)
cras_dsp_ini_free(old_ini);
}
@@ -155,11 +153,10 @@ void cras_dsp_init(const char *filename)
void cras_dsp_stop()
{
syslog_dumper_free(syslog_dumper);
- if (ini_filename)
- free((char *)ini_filename);
- if (global_ini) {
- cras_dsp_ini_free(global_ini);
- global_ini = NULL;
+ free((char *)ini_filename);
+ if (ini) {
+ cras_dsp_ini_free(ini);
+ ini = NULL;
}
}
@@ -205,18 +202,18 @@ void cras_dsp_set_variable_boolean(struct cras_dsp_context *ctx,
void cras_dsp_load_pipeline(struct cras_dsp_context *ctx)
{
- cmd_load_pipeline(ctx, global_ini);
+ cmd_load_pipeline(ctx, ini);
}
-void cras_dsp_load_mock_pipeline(struct cras_dsp_context *ctx,
- unsigned int num_channels)
+void cras_dsp_load_dummy_pipeline(struct cras_dsp_context *ctx,
+ unsigned int num_channels)
{
- struct ini *mock_ini;
- mock_ini = create_mock_ini(ctx->purpose, num_channels);
- if (mock_ini == NULL)
- syslog(LOG_ERR, "Failed to create mock ini");
+ struct ini *dummy_ini;
+ dummy_ini = create_dummy_ini(ctx->purpose, num_channels);
+ if (dummy_ini == NULL)
+ syslog(LOG_ERR, "Failed to create dummy ini");
else
- cmd_load_pipeline(ctx, mock_ini);
+ cmd_load_pipeline(ctx, dummy_ini);
}
struct pipeline *cras_dsp_get_pipeline(struct cras_dsp_context *ctx)
@@ -244,8 +241,8 @@ void cras_dsp_dump_info()
struct pipeline *pipeline;
struct cras_dsp_context *ctx;
- if (global_ini)
- cras_dsp_ini_dump(syslog_dumper, global_ini);
+ if (ini)
+ cras_dsp_ini_dump(syslog_dumper, ini);
DL_FOREACH (context_list, ctx) {
cras_expr_env_dump(syslog_dumper, &ctx->env);
pipeline = ctx->pipeline;
diff --git a/cras/src/server/cras_dsp.h b/cras/src/server/cras_dsp.h
index 366e2e67..9a72f42b 100644
--- a/cras/src/server/cras_dsp.h
+++ b/cras/src/server/cras_dsp.h
@@ -54,11 +54,11 @@ void cras_dsp_set_variable_boolean(struct cras_dsp_context *ctx,
* blocking the audio thread. */
void cras_dsp_load_pipeline(struct cras_dsp_context *ctx);
-/* Loads a mock pipeline of source directly connects to sink, of given
+/* Loads a dummy pipeline of source directly connects to sink, of given
* number of channels.
*/
-void cras_dsp_load_mock_pipeline(struct cras_dsp_context *ctx,
- unsigned int num_channels);
+void cras_dsp_load_dummy_pipeline(struct cras_dsp_context *ctx,
+ unsigned int num_channels);
/* Locks the pipeline in the context for access. Returns NULL if the
* pipeline is still being loaded or cannot be loaded. */
diff --git a/cras/src/server/cras_dsp_ini.c b/cras/src/server/cras_dsp_ini.c
index a331acf8..966c6b01 100644
--- a/cras/src/server/cras_dsp_ini.c
+++ b/cras/src/server/cras_dsp_ini.c
@@ -9,9 +9,10 @@
#include "cras_dsp_ini.h"
#include "iniparser_wrapper.h"
+#define MAX_INI_KEY_LENGTH 64 /* names like "output_source:output_0" */
#define MAX_NR_PORT 128 /* the max number of ports for a plugin */
#define MAX_PORT_NAME_LENGTH 20 /* names like "output_32" */
-#define MAX_MOCK_INI_CH 20 /* Max number of channels to create mock ini */
+#define MAX_DUMMY_INI_CH 8 /* Max number of channels to create dummy ini */
/* Format of the ini file (See dsp.ini.sample for an example).
@@ -62,7 +63,7 @@
static const char *getstring(struct ini *ini, const char *sec_name,
const char *key)
{
- char full_key[MAX_INI_KEY_LENGTH + 1];
+ char full_key[MAX_INI_KEY_LENGTH];
snprintf(full_key, sizeof(full_key), "%s:%s", sec_name, key);
return iniparser_getstring(ini->dict, full_key, NULL);
}
@@ -305,21 +306,19 @@ static int insert_swap_lr_plugin(struct ini *ini)
return 0;
}
-struct ini *create_mock_ini(const char *purpose, unsigned int num_channels)
+struct ini *create_dummy_ini(const char *purpose, unsigned int num_channels)
{
- static char mock_flow_names[MAX_MOCK_INI_CH][9] = {
- "{tmp:0}", "{tmp:1}", "{tmp:2}", "{tmp:3}", "{tmp:4}",
- "{tmp:5}", "{tmp:6}", "{tmp:7}", "{tmp:8}", "{tmp:9}",
- "{tmp:10}", "{tmp:11}", "{tmp:12}", "{tmp:13}", "{tmp:14}",
- "{tmp:15}", "{tmp:16}", "{tmp:17}", "{tmp:18}", "{tmp:19}",
+ static char dummy_flow_names[MAX_DUMMY_INI_CH][8] = {
+ "{tmp:0}", "{tmp:1}", "{tmp:2}", "{tmp:3}",
+ "{tmp:4}", "{tmp:5}", "{tmp:6}", "{tmp:7}",
};
struct ini *ini;
struct plugin *source, *sink;
- int tmp_flow_ids[MAX_MOCK_INI_CH];
+ int tmp_flow_ids[MAX_DUMMY_INI_CH];
int i;
- if (num_channels > MAX_MOCK_INI_CH) {
- syslog(LOG_ERR, "Unable to create %u channels of mock ini",
+ if (num_channels > MAX_DUMMY_INI_CH) {
+ syslog(LOG_ERR, "Unable to create %u channels of dummy ini",
num_channels);
return NULL;
}
@@ -331,7 +330,7 @@ struct ini *create_mock_ini(const char *purpose, unsigned int num_channels)
}
for (i = 0; i < num_channels; i++)
- tmp_flow_ids[i] = add_new_flow(ini, mock_flow_names[i]);
+ tmp_flow_ids[i] = add_new_flow(ini, dummy_flow_names[i]);
source = ARRAY_APPEND_ZERO(&ini->plugins);
source->title = "source";
diff --git a/cras/src/server/cras_dsp_ini.h b/cras/src/server/cras_dsp_ini.h
index c839d4b0..117cfd21 100644
--- a/cras/src/server/cras_dsp_ini.h
+++ b/cras/src/server/cras_dsp_ini.h
@@ -6,12 +6,12 @@
#ifndef CRAS_DSP_INI_H_
#define CRAS_DSP_INI_H_
-#include "iniparser_wrapper.h"
-
#ifdef __cplusplus
extern "C" {
#endif
+#include <iniparser.h>
+
#include "array.h"
#include "dumper.h"
#include "cras_expr.h"
@@ -71,7 +71,7 @@ struct ini {
};
/*
- * Creates a mock ini structure equivalent to:
+ * Creates a dummy ini structure equivalent to:
*
* [src]
* out0={tmp:0}
@@ -86,7 +86,7 @@ struct ini {
* The caller of this function is responsible to free the returned
* ini by calling cras_dsp_ini_free().
*/
-struct ini *create_mock_ini(const char *purpose, unsigned int num_channels);
+struct ini *create_dummy_ini(const char *purpose, unsigned int num_channels);
/* Reads the ini file into the ini structure */
struct ini *cras_dsp_ini_create(const char *ini_filename);
diff --git a/cras/src/server/cras_dsp_pipeline.c b/cras/src/server/cras_dsp_pipeline.c
index 9e492ac5..945e5c3e 100644
--- a/cras/src/server/cras_dsp_pipeline.c
+++ b/cras/src/server/cras_dsp_pipeline.c
@@ -144,8 +144,8 @@ struct pipeline {
int64_t total_samples;
};
-static struct instance *find_instance_by_plugin(const instance_array *instances,
- const struct plugin *plugin)
+static struct instance *find_instance_by_plugin(instance_array *instances,
+ struct plugin *plugin)
{
int i;
struct instance *instance;
@@ -161,9 +161,9 @@ static struct instance *find_instance_by_plugin(const instance_array *instances,
/* Finds out where the data sent to plugin:index come from. The issue
* we need to handle here is the previous plugin may be disabled, so
* we need to go upstream until we find the real origin */
-static int find_origin_port(struct ini *ini, const instance_array *instances,
- const struct plugin *plugin, int index,
- const struct plugin **origin, int *origin_index)
+static int find_origin_port(struct ini *ini, instance_array *instances,
+ struct plugin *plugin, int index,
+ struct plugin **origin, int *origin_index)
{
enum port_type type;
struct port *port;
@@ -226,7 +226,7 @@ static int find_origin_port(struct ini *ini, const instance_array *instances,
}
static struct audio_port *find_output_audio_port(instance_array *instances,
- const struct plugin *plugin,
+ struct plugin *plugin,
int index)
{
int i;
@@ -246,7 +246,7 @@ static struct audio_port *find_output_audio_port(instance_array *instances,
}
static struct control_port *find_output_control_port(instance_array *instances,
- const struct plugin *plugin,
+ struct plugin *plugin,
int index)
{
int i;
@@ -317,7 +317,7 @@ static int topological_sort(struct pipeline *pipeline,
ARRAY_ELEMENT_FOREACH (&plugin->ports, i, port) {
int need_connect = (port->flow_id != INVALID_FLOW_ID &&
port->direction == PORT_INPUT);
- const struct plugin *origin = NULL;
+ struct plugin *origin = NULL;
int origin_index = 0;
if (need_connect) {
@@ -435,7 +435,6 @@ struct pipeline *cras_dsp_pipeline_create(struct ini *ini,
if (rc < 0) {
syslog(LOG_ERR, "failed to construct pipeline");
- cras_dsp_pipeline_free(pipeline);
return NULL;
}
@@ -525,17 +524,6 @@ static int allocate_buffers(struct pipeline *pipeline)
peak_buf = MAX(peak_buf, need_buf);
}
}
- /*
- * cras_dsp_pipeline_create creates pipeline with source and sink and it
- * makes sure all ports could be accessed from some sources, which means
- * that there is at least one source with out > 0 and in == 0.
- * This will give us peak_buf > 0 in the previous calculation.
- */
- if (peak_buf <= 0) {
- syslog(LOG_ERR, "peak_buf = %d, which must be greater than 0.",
- peak_buf);
- return -1;
- }
/* then allocate the buffers */
pipeline->peak_buf = peak_buf;
@@ -982,10 +970,9 @@ void cras_dsp_pipeline_dump(struct dumper *d, struct pipeline *pipeline)
pipeline->min_time);
dumpf(d, " max processing time per block: %" PRId64 "ns\n",
pipeline->max_time);
- if (pipeline->total_samples)
- dumpf(d, " cpu load: %g%%\n",
- pipeline->total_time * 1e-9 / pipeline->total_samples *
- pipeline->sample_rate * 100);
+ dumpf(d, " cpu load: %g%%\n",
+ pipeline->total_time * 1e-9 / pipeline->total_samples *
+ pipeline->sample_rate * 100);
dumpf(d, " instances (%d):\n", ARRAY_COUNT(&pipeline->instances));
ARRAY_ELEMENT_FOREACH (&pipeline->instances, i, instance) {
struct dsp_module *module = instance->module;
diff --git a/cras/src/server/cras_empty_iodev.c b/cras/src/server/cras_empty_iodev.c
index 3471c756..574f5368 100644
--- a/cras/src/server/cras_empty_iodev.c
+++ b/cras/src/server/cras_empty_iodev.c
@@ -15,9 +15,9 @@
#include "cras_types.h"
#include "utlist.h"
-#define EMPTY_BUFFER_SIZE (32 * 1024)
-#define MAX_EMPTY_FRAME_SIZE 8
-#define EMPTY_FRAMES (EMPTY_BUFFER_SIZE / MAX_EMPTY_FRAME_SIZE)
+#define EMPTY_BUFFER_SIZE (16 * 1024)
+#define EMPTY_FRAME_SIZE 4
+#define EMPTY_FRAMES (EMPTY_BUFFER_SIZE / EMPTY_FRAME_SIZE)
static size_t empty_supported_rates[] = { 44100, 48000, 0 };
@@ -199,12 +199,11 @@ struct cras_iodev *empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,
iodev->update_active_node = update_active_node;
iodev->no_stream = cras_iodev_default_no_stream_playback;
- /* Create an empty ionode */
+ /* Create a dummy ionode */
node = (struct cras_ionode *)calloc(1, sizeof(*node));
node->dev = iodev;
node->type = node_type;
node->volume = 100;
- node->ui_gain_scaler = 1.0f;
strcpy(node->name, "(default)");
cras_iodev_add_node(iodev, node);
cras_iodev_set_active_node(iodev, node);
@@ -231,12 +230,6 @@ struct cras_iodev *empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,
iodev->info.idx = SILENT_PLAYBACK_DEVICE;
}
- /*
- * Record max supported channels into cras_iodev_info.
- * The value is the max of empty_supported_channel_counts.
- */
- iodev->info.max_supported_channels = 2;
-
return iodev;
}
diff --git a/cras/src/server/cras_fmt_conv.c b/cras/src/server/cras_fmt_conv.c
index 842529b9..35ab8ecf 100644
--- a/cras/src/server/cras_fmt_conv.c
+++ b/cras/src/server/cras_fmt_conv.c
@@ -9,7 +9,6 @@
#include <syslog.h>
#include <endian.h>
#include <limits.h>
-#include <math.h>
#include "cras_fmt_conv.h"
#include "cras_fmt_conv_ops.h"
@@ -59,35 +58,17 @@ static int is_channel_layout_equal(const struct cras_audio_format *a,
return 1;
}
-/*
- * Calculates the normalize_factor abs_sum(ci) from given coefficients.
- * Since sum(ci / abs_sum(ci)) <= 1, this could prevent sample overflow while
- * upmixing or downmixing.
- */
-static float normalize_factor(float *buf, size_t n)
+static void normalize_buf(float *buf, size_t size)
{
int i;
- float abs_sum = 0.0;
- for (i = 0; i < n; i++)
- abs_sum += fabs(buf[i]);
-
- return 1.0 / abs_sum;
-}
-
-/*
- * Normalize all channels with the same factor to maintain
- * the energy ratio between original channels.
- */
-static void normalize(float **mtx, size_t m, size_t n, float factor)
-{
- int i, j;
- for (i = 0; i < m; i++)
- for (j = 0; j < n; j++)
- mtx[i][j] *= factor;
+ float squre_sum = 0.0;
+ for (i = 0; i < size; i++)
+ squre_sum += buf[i] * buf[i];
+ for (i = 0; i < size; i++)
+ buf[i] /= squre_sum;
}
-/*
- * Populates the down mix matrix by rules:
+/* Populates the down mix matrix by rules:
* 1. Front/side left(right) channel will mix to left(right) of
* full scale.
* 2. Center and LFE will be split equally to left and right.
@@ -121,46 +102,9 @@ static void surround51_to_stereo_downmix_mtx(float **mtx,
mtx[STEREO_L][layout[CRAS_CH_LFE]] = 0.707;
mtx[STEREO_R][layout[CRAS_CH_LFE]] = 0.707;
}
- normalize(mtx, 2, 6, normalize_factor(mtx[STEREO_L], 6));
-}
-
-/* Populates the down mix matrix by rules:
- * 1. Front left(right) channel will mix to the front left(right) of
- * full scale.
- * 2. Rear and side left(right) channel will mix to the rear left(right) of
- * full scale.
- * 3. Center will be split equally to the front left and right.
- * 4. LFE will be split equally to the other channels.
- */
-static void surround51_to_quad_downmix_mtx(float **mtx,
- int8_t layout[CRAS_CH_MAX])
-{
- if (layout[CRAS_CH_FL] != -1 && layout[CRAS_CH_FR] != -1) {
- mtx[CRAS_CH_FL][layout[CRAS_CH_FL]] = 1.0;
- mtx[CRAS_CH_FR][layout[CRAS_CH_FR]] = 1.0;
- }
- if (layout[CRAS_CH_RL] != -1 && layout[CRAS_CH_RR] != -1) {
- mtx[CRAS_CH_RL][layout[CRAS_CH_RL]] = 1.0;
- mtx[CRAS_CH_RR][layout[CRAS_CH_RR]] = 1.0;
- }
- if (layout[CRAS_CH_SL] != -1 && layout[CRAS_CH_SR] != -1) {
- mtx[CRAS_CH_RL][layout[CRAS_CH_SL]] = 1.0;
- mtx[CRAS_CH_RR][layout[CRAS_CH_SR]] = 1.0;
- }
- if (layout[CRAS_CH_FC] != -1) {
- /* Split 1/2 power to the front L/R */
- mtx[CRAS_CH_FL][layout[CRAS_CH_FC]] = 0.707;
- mtx[CRAS_CH_FR][layout[CRAS_CH_FC]] = 0.707;
- }
- if (layout[CRAS_CH_LFE] != -1) {
- /* Split 1/4 power to the other channel */
- mtx[CRAS_CH_FL][layout[CRAS_CH_LFE]] = 0.5;
- mtx[CRAS_CH_FR][layout[CRAS_CH_LFE]] = 0.5;
- mtx[CRAS_CH_RL][layout[CRAS_CH_LFE]] = 0.5;
- mtx[CRAS_CH_RR][layout[CRAS_CH_LFE]] = 0.5;
- }
- normalize(mtx, 4, 6, normalize_factor(mtx[CRAS_CH_FL], 6));
+ normalize_buf(mtx[STEREO_L], 6);
+ normalize_buf(mtx[STEREO_R], 6);
}
static int is_supported_format(const struct cras_audio_format *fmt)
@@ -216,31 +160,12 @@ static size_t stereo_to_51(struct cras_fmt_conv *conv, const uint8_t *in,
return s16_stereo_to_51(left, right, center, in, in_frames, out);
}
-static size_t quad_to_51(struct cras_fmt_conv *conv, const uint8_t *in,
- size_t in_frames, uint8_t *out)
-{
- size_t fl, fr, rl, rr;
-
- fl = conv->out_fmt.channel_layout[CRAS_CH_FL];
- fr = conv->out_fmt.channel_layout[CRAS_CH_FR];
- rl = conv->out_fmt.channel_layout[CRAS_CH_RL];
- rr = conv->out_fmt.channel_layout[CRAS_CH_RR];
-
- return s16_quad_to_51(fl, fr, rl, rr, in, in_frames, out);
-}
-
static size_t _51_to_stereo(struct cras_fmt_conv *conv, const uint8_t *in,
size_t in_frames, uint8_t *out)
{
return s16_51_to_stereo(in, in_frames, out);
}
-static size_t _51_to_quad(struct cras_fmt_conv *conv, const uint8_t *in,
- size_t in_frames, uint8_t *out)
-{
- return s16_51_to_quad(in, in_frames, out);
-}
-
static size_t stereo_to_quad(struct cras_fmt_conv *conv, const uint8_t *in,
size_t in_frames, uint8_t *out)
{
@@ -281,21 +206,6 @@ static size_t default_all_to_all(struct cras_fmt_conv *conv, const uint8_t *in,
in_frames, out);
}
-// Fill min(in channels, out_channels), leave the rest 0s.
-static size_t default_some_to_some(struct cras_fmt_conv *conv,
- const uint8_t *in,
- size_t in_frames,
- uint8_t *out)
-{
- size_t num_in_ch, num_out_ch;
-
- num_in_ch = conv->in_fmt.num_channels;
- num_out_ch = conv->out_fmt.num_channels;
-
- return s16_some_to_some(&conv->out_fmt, num_in_ch, num_out_ch, in,
- in_frames, out);
-}
-
static size_t convert_channels(struct cras_fmt_conv *conv, const uint8_t *in,
size_t in_frames, uint8_t *out)
{
@@ -411,10 +321,7 @@ struct cras_fmt_conv *cras_fmt_conv_create(const struct cras_audio_format *in,
conv->channel_converter = quad_to_stereo;
} else if (in->num_channels == 2 && out->num_channels == 6) {
conv->channel_converter = stereo_to_51;
- } else if (in->num_channels == 4 && out->num_channels == 6) {
- conv->channel_converter = quad_to_51;
- } else if (in->num_channels == 6 &&
- (out->num_channels == 2 || out->num_channels == 4)) {
+ } else if (in->num_channels == 6 && out->num_channels == 2) {
int in_channel_layout_set = 0;
/* Checks if channel_layout is set in the incoming format */
@@ -435,44 +342,28 @@ struct cras_fmt_conv *cras_fmt_conv_create(const struct cras_audio_format *in,
return NULL;
}
conv->channel_converter = convert_channels;
- if (out->num_channels == 4) {
- surround51_to_quad_downmix_mtx(
- conv->ch_conv_mtx,
- conv->in_fmt.channel_layout);
- } else {
- surround51_to_stereo_downmix_mtx(
- conv->ch_conv_mtx,
- conv->in_fmt.channel_layout);
- }
+ surround51_to_stereo_downmix_mtx(
+ conv->ch_conv_mtx,
+ conv->in_fmt.channel_layout);
} else {
- if (out->num_channels == 4)
- conv->channel_converter = _51_to_quad;
- else
- conv->channel_converter = _51_to_stereo;
+ conv->channel_converter = _51_to_stereo;
}
- } else if (in->num_channels <= 8 && out->num_channels <= 8) {
- // For average channel counts mix from all to all.
- syslog(LOG_WARNING,
- "Using all_to_all map for %zu to %zu",
- in->num_channels, out->num_channels);
- conv->channel_converter = default_all_to_all;
} else {
syslog(LOG_WARNING,
- "Using some_to_some channel map for %zu to %zu",
+ "Using default channel map for %zu to %zu",
in->num_channels, out->num_channels);
- conv->channel_converter = default_some_to_some;
+ conv->channel_converter = default_all_to_all;
}
} else if (in->num_channels > 2 && !is_channel_layout_equal(in, out)) {
conv->num_converters++;
conv->ch_conv_mtx = cras_channel_conv_matrix_create(in, out);
if (conv->ch_conv_mtx == NULL) {
syslog(LOG_ERR,
- "Failed to create channel conversion matrix."
- "Fallback to default_all_to_all.");
- conv->channel_converter = default_all_to_all;
- } else {
- conv->channel_converter = convert_channels;
+ "Failed to create channel conversion matrix");
+ cras_fmt_conv_destroy(&conv);
+ return NULL;
}
+ conv->channel_converter = convert_channels;
}
/* Set up sample rate conversion. */
if (in->frame_rate != out->frame_rate) {
diff --git a/cras/src/server/cras_fmt_conv_ops.c b/cras/src/server/cras_fmt_conv_ops.c
index adc55215..bf479c91 100644
--- a/cras/src/server/cras_fmt_conv_ops.c
+++ b/cras/src/server/cras_fmt_conv_ops.c
@@ -223,44 +223,6 @@ size_t s16_stereo_to_51(size_t left, size_t right, size_t center,
}
/*
- * Channel converter: quad to 5.1 surround.
- *
- * Fit the front left/right of input to the front left/right of output
- * and rear left/right of input to the rear left/right of output
- * respectively and fill others with zero.
- */
-size_t s16_quad_to_51(size_t font_left, size_t front_right, size_t rear_left,
- size_t rear_right, const uint8_t *_in, size_t in_frames,
- uint8_t *_out)
-{
- size_t i;
- const int16_t *in = (const int16_t *)_in;
- int16_t *out = (int16_t *)_out;
-
- memset(out, 0, sizeof(*out) * 6 * in_frames);
-
- if (font_left != -1 && front_right != -1 && rear_left != -1 &&
- rear_right != -1)
- for (i = 0; i < in_frames; i++) {
- out[6 * i + font_left] = in[4 * i];
- out[6 * i + front_right] = in[4 * i + 1];
- out[6 * i + rear_left] = in[4 * i + 2];
- out[6 * i + rear_right] = in[4 * i + 3];
- }
- else
- /* Use default 5.1 channel mapping for the conversion.
- */
- for (i = 0; i < in_frames; i++) {
- out[6 * i] = in[4 * i];
- out[6 * i + 1] = in[4 * i + 1];
- out[6 * i + 4] = in[4 * i + 2];
- out[6 * i + 5] = in[4 * i + 3];
- }
-
- return in_frames;
-}
-
-/*
* Channel converter: 5.1 surround to stereo.
*
* The out buffer can have room for just stereo samples. This convert function
@@ -273,69 +235,20 @@ size_t s16_51_to_stereo(const uint8_t *_in, size_t in_frames, uint8_t *_out)
int16_t *out = (int16_t *)_out;
static const unsigned int left_idx = 0;
static const unsigned int right_idx = 1;
- static const unsigned int center_idx = 2;
- /* static const unsigned int lfe_idx = 3; */
- /* static const unsigned int left_surround_idx = 4; */
- /* static const unsigned int right_surround_idx = 5; */
-
+ /* static const unsigned int left_surround_idx = 2; */
+ /* static const unsigned int right_surround_idx = 3; */
+ static const unsigned int center_idx = 4;
+ /* static const unsigned int lfe_idx = 5; */
size_t i;
- int16_t half_center;
- /* Use the normalized_factor from the left channel = 1 / (|1| + |0.707|)
- * to prevent mixing overflow.
- */
- const float normalized_factor = 0.585;
+
for (i = 0; i < in_frames; i++) {
- half_center =
- in[6 * i + center_idx] * 0.707 * normalized_factor;
+ unsigned int half_center;
+
+ half_center = in[6 * i + center_idx] / 2;
out[2 * i + left_idx] =
- in[6 * i + left_idx] * normalized_factor + half_center;
+ s16_add_and_clip(in[6 * i + left_idx], half_center);
out[2 * i + right_idx] =
- in[6 * i + right_idx] * normalized_factor + half_center;
- }
- return in_frames;
-}
-
-/*
- * Channel converter: 5.1 surround to quad (front L/R, rear L/R).
- *
- * The out buffer can have room for just quad samples. This convert function
- * is used as the default behavior when channel layout is not set from the
- * client side.
- */
-size_t s16_51_to_quad(const uint8_t *_in, size_t in_frames, uint8_t *_out)
-{
- const int16_t *in = (const int16_t *)_in;
- int16_t *out = (int16_t *)_out;
- static const unsigned int l_quad = 0;
- static const unsigned int r_quad = 1;
- static const unsigned int rl_quad = 2;
- static const unsigned int rr_quad = 3;
-
- static const unsigned int l_51 = 0;
- static const unsigned int r_51 = 1;
- static const unsigned int center_51 = 2;
- static const unsigned int lfe_51 = 3;
- static const unsigned int rl_51 = 4;
- static const unsigned int rr_51 = 5;
-
- /* Use normalized_factor from the left channel = 1 / (|1| + |0.707| + |0.5|)
- * to prevent overflow. */
- const float normalized_factor = 0.453;
- size_t i;
- for (i = 0; i < in_frames; i++) {
- int16_t half_center;
- int16_t lfe;
-
- half_center = in[6 * i + center_51] * 0.707 * normalized_factor;
- lfe = in[6 * i + lfe_51] * 0.5 * normalized_factor;
- out[4 * i + l_quad] = normalized_factor * in[6 * i + l_51] +
- half_center + lfe;
- out[4 * i + r_quad] = normalized_factor * in[6 * i + r_51] +
- half_center + lfe;
- out[4 * i + rl_quad] =
- normalized_factor * in[6 * i + rl_51] + lfe;
- out[4 * i + rr_quad] =
- normalized_factor * in[6 * i + rr_51] + lfe;
+ s16_add_and_clip(in[6 * i + right_idx], half_center);
}
return in_frames;
}
@@ -418,50 +331,20 @@ size_t s16_default_all_to_all(struct cras_audio_format *out_fmt,
unsigned int in_ch, out_ch, i;
const int16_t *in = (const int16_t *)_in;
int16_t *out = (int16_t *)_out;
- int32_t sum;
- for (i = 0; i < in_frames; i++) {
- sum = 0;
+ memset(out, 0, in_frames * cras_get_format_bytes(out_fmt));
+ for (out_ch = 0; out_ch < num_out_ch; out_ch++) {
for (in_ch = 0; in_ch < num_in_ch; in_ch++) {
- sum += (int32_t)in[in_ch + i * num_in_ch];
- }
- /*
- * 1. Divide `int32_t` by `size_t` without an explicit
- * conversion will generate corrupted results.
- * 2. After the division, `sum` should be in the range of
- * int16_t. No clipping is needed.
- */
- sum /= (int32_t)num_in_ch;
- for (out_ch = 0; out_ch < num_out_ch; out_ch++) {
- out[out_ch + i * num_out_ch] = (int16_t)sum;
+ for (i = 0; i < in_frames; i++) {
+ out[out_ch + i * num_out_ch] +=
+ in[in_ch + i * num_in_ch] / num_in_ch;
+ }
}
}
return in_frames;
}
/*
- * Copies the input channels across output channels. Drops input channels that
- * don't fit. Ignores output channels greater than the number of input channels.
- */
-size_t s16_some_to_some(const struct cras_audio_format *out_fmt,
- const size_t num_in_ch, const size_t num_out_ch,
- const uint8_t *_in, const size_t frame_count,
- uint8_t *_out)
-{
- unsigned int i;
- const int16_t *in = (const int16_t *)_in;
- int16_t *out = (int16_t *)_out;
- const size_t num_copy_ch = MIN(num_in_ch, num_out_ch);
-
- memset(out, 0, frame_count * cras_get_format_bytes(out_fmt));
- for (i = 0; i < frame_count; i++, out += num_out_ch, in += num_in_ch) {
- memcpy(out, in, num_copy_ch * sizeof(int16_t));
- }
-
- return frame_count;
-}
-
-/*
* Multiplies buffer vector with coefficient vector.
*/
int16_t s16_multiply_buf_with_coef(float *coef, const int16_t *buf, size_t size)
diff --git a/cras/src/server/cras_fmt_conv_ops.h b/cras/src/server/cras_fmt_conv_ops.h
index 0af7564b..6943f23e 100644
--- a/cras/src/server/cras_fmt_conv_ops.h
+++ b/cras/src/server/cras_fmt_conv_ops.h
@@ -46,23 +46,11 @@ size_t s16_stereo_to_51(size_t left, size_t right, size_t center,
const uint8_t *in, size_t in_frames, uint8_t *out);
/*
- * Channel converter: quad to 5.1 surround.
- */
-size_t s16_quad_to_51(size_t font_left, size_t front_right, size_t rear_left,
- size_t rear_right, const uint8_t *in, size_t in_frames,
- uint8_t *out);
-
-/*
* Channel converter: 5.1 surround to stereo.
*/
size_t s16_51_to_stereo(const uint8_t *in, size_t in_frames, uint8_t *out);
/*
- * Channel converter: 5.1 surround to quad.
- */
-size_t s16_51_to_quad(const uint8_t *in, size_t in_frames, uint8_t *out);
-
-/*
* Channel converter: stereo to quad (front L/R, rear L/R).
*/
size_t s16_stereo_to_quad(size_t front_left, size_t front_right,
@@ -85,15 +73,6 @@ size_t s16_default_all_to_all(struct cras_audio_format *out_fmt,
uint8_t *out);
/*
- * Channel converter: N channels to M channels filling min(N,M) channels by
- * directly copying to the destination.
- */
-size_t s16_some_to_some(const struct cras_audio_format *out_fmt,
- const size_t num_in_ch, const size_t num_out_ch,
- const uint8_t *_in, const size_t frame_count,
- uint8_t *_out);
-
-/*
* Multiplies buffer vector with coefficient vector.
*/
int16_t s16_multiply_buf_with_coef(float *coef, const int16_t *buf,
diff --git a/cras/src/server/cras_hfp_ag_profile.c b/cras/src/server/cras_hfp_ag_profile.c
index b5fcecc3..63201914 100644
--- a/cras/src/server/cras_hfp_ag_profile.c
+++ b/cras/src/server/cras_hfp_ag_profile.c
@@ -21,11 +21,10 @@
#include "cras_system_state.h"
#include "cras_iodev_list.h"
#include "utlist.h"
-#include "packet_status_logger.h"
#define HFP_AG_PROFILE_NAME "Hands-Free Voice gateway"
#define HFP_AG_PROFILE_PATH "/org/chromium/Cras/Bluetooth/HFPAG"
-#define HFP_VERSION 0x0107
+#define HFP_VERSION_1_5 0x0105
#define HSP_AG_PROFILE_NAME "Headset Voice gateway"
#define HSP_AG_PROFILE_PATH "/org/chromium/Cras/Bluetooth/HSPAG"
#define HSP_VERSION_1_2 0x0102
@@ -72,12 +71,6 @@
" </attribute>" \
"</record>"
-/* The supported features value in +BSRF command response of HFP AG in CRAS */
-#define BSRF_SUPPORTED_FEATURES (AG_ENHANCED_CALL_STATUS | AG_HF_INDICATORS)
-
-/* The "SupportedFeatures" attribute value of HFP AG service record in CRAS. */
-#define SDP_SUPPORTED_FEATURES FEATURES_AG_WIDE_BAND_SPEECH
-
/* Object representing the audio gateway role for HFP/HSP.
* Members:
* idev - The input iodev for HFP/HSP.
@@ -103,7 +96,6 @@ struct audio_gateway {
};
static struct audio_gateway *connected_ags;
-static struct packet_status_logger wbs_logger;
static int need_go_sco_pcm(struct cras_bt_device *device)
{
@@ -115,9 +107,6 @@ static void destroy_audio_gateway(struct audio_gateway *ag)
{
DL_DELETE(connected_ags, ag);
- cras_server_metrics_hfp_battery_indicator(
- hfp_slc_get_hf_supports_battery_indicator(ag->slc_handle));
-
if (need_go_sco_pcm(ag->device)) {
if (ag->idev)
hfp_alsa_iodev_destroy(ag->idev);
@@ -175,14 +164,6 @@ static int cras_hfp_ag_slc_initialized(struct hfp_slc_handle *handle)
cras_server_metrics_hfp_wideband_support(
hfp_slc_get_hf_codec_negotiation_supported(handle));
- /* Log the final selected codec given that codec negotiation is
- * supported.
- */
- if (hfp_slc_get_hf_codec_negotiation_supported(handle) &&
- hfp_slc_get_ag_codec_negotiation_supported(handle))
- cras_server_metrics_hfp_wideband_selected_codec(
- hfp_slc_get_selected_codec(handle));
-
/* Defer the starting of audio gateway to bt_device. */
return cras_bt_device_audio_gateway_initialized(ag->device);
}
@@ -268,8 +249,8 @@ static int cras_hfp_ag_new_connection(DBusConnection *conn,
* TODO(hychao): AND the two conditions to let bluetooth daemon
* control whether to turn on WBS feature.
*/
- ag_features = BSRF_SUPPORTED_FEATURES;
- if (cras_system_get_bt_wbs_enabled() && adapter &&
+ ag_features = profile->features;
+ if (cras_system_get_bt_wbs_enabled() &&
cras_bt_adapter_wbs_supported(adapter))
ag_features |= AG_CODEC_NEGOTIATION;
@@ -289,10 +270,10 @@ static void cras_hfp_ag_request_disconnection(struct cras_bt_profile *profile,
DL_FOREACH (connected_ags, ag) {
if (ag->slc_handle && ag->device == device) {
+ destroy_audio_gateway(ag);
cras_bt_device_notify_profile_dropped(
ag->device,
CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
- destroy_audio_gateway(ag);
}
}
}
@@ -305,9 +286,9 @@ static struct cras_bt_profile cras_hfp_ag_profile = {
.name = HFP_AG_PROFILE_NAME,
.object_path = HFP_AG_PROFILE_PATH,
.uuid = HFP_AG_UUID,
- .version = HFP_VERSION,
+ .version = HFP_VERSION_1_5,
.role = NULL,
- .features = SDP_SUPPORTED_FEATURES,
+ .features = CRAS_AG_SUPPORTED_FEATURES & 0x1F,
.record = NULL,
.release = cras_hfp_ag_release,
.new_connection = cras_hfp_ag_new_connection,
@@ -344,9 +325,8 @@ static int cras_hsp_ag_new_connection(DBusConnection *conn,
ag->device = device;
ag->conn = conn;
ag->profile = cras_bt_device_profile_from_uuid(profile->uuid);
- ag->slc_handle =
- hfp_slc_create(rfcomm_fd, 1, BSRF_SUPPORTED_FEATURES, device,
- NULL, cras_hfp_ag_slc_disconnected);
+ ag->slc_handle = hfp_slc_create(rfcomm_fd, 1, profile->features, device,
+ NULL, cras_hfp_ag_slc_disconnected);
DL_APPEND(connected_ags, ag);
cras_hfp_ag_slc_initialized(ag->slc_handle);
return 0;
@@ -361,9 +341,9 @@ static void cras_hsp_ag_request_disconnection(struct cras_bt_profile *profile,
DL_FOREACH (connected_ags, ag) {
if (ag->slc_handle && ag->device == device) {
+ destroy_audio_gateway(ag);
cras_bt_device_notify_profile_dropped(
ag->device, CRAS_BT_DEVICE_PROFILE_HSP_HEADSET);
- destroy_audio_gateway(ag);
}
}
}
@@ -411,8 +391,8 @@ int cras_hfp_ag_start(struct cras_bt_device *device)
ag->odev = hfp_alsa_iodev_create(out_aio, ag->device,
ag->slc_handle, ag->profile);
} else {
- ag->info = hfp_info_create();
- hfp_info_set_wbs_logger(ag->info, &wbs_logger);
+ ag->info = hfp_info_create(
+ hfp_slc_get_selected_codec(ag->slc_handle));
ag->idev =
hfp_iodev_create(CRAS_STREAM_INPUT, ag->device,
ag->slc_handle, ag->profile, ag->info);
@@ -455,11 +435,6 @@ struct hfp_slc_handle *cras_hfp_ag_get_slc(struct cras_bt_device *device)
return NULL;
}
-struct packet_status_logger *cras_hfp_ag_get_wbs_logger()
-{
- return &wbs_logger;
-}
-
int cras_hsp_ag_profile_create(DBusConnection *conn)
{
return cras_bt_add_profile(conn, &cras_hsp_ag_profile);
diff --git a/cras/src/server/cras_hfp_ag_profile.h b/cras/src/server/cras_hfp_ag_profile.h
index 3de56184..4c1d49d2 100644
--- a/cras/src/server/cras_hfp_ag_profile.h
+++ b/cras/src/server/cras_hfp_ag_profile.h
@@ -7,22 +7,12 @@
#define CRAS_HFP_AG_PROFILE_H_
#include <dbus/dbus.h>
-#include <stdbool.h>
#include "cras_bt_device.h"
#include "cras_hfp_slc.h"
-/*
- * For service record profile, 'SupportedFearues' attribute bit mapping
- * for HFP AG. Bits 0 to 4 are identical to the unsolicited result code
- * of +BRSF command.
- */
-#define FEATURES_AG_THREE_WAY_CALLING 0x0001
-#define FEATURES_AG_EC_ANDOR_NR 0x0002
-#define FEATURES_AG_VOICE_RECOGNITION 0x0004
-#define FEATURES_AG_INBAND_RINGTONE 0x0008
-#define FEATURES_AG_ATTACH_NUMBER_TO_VOICETAG 0x0010
-#define FEATURES_AG_WIDE_BAND_SPEECH 0x0020
+/* The bitmap of HFP AG feature supported by CRAS */
+#define CRAS_AG_SUPPORTED_FEATURES (AG_ENHANCED_CALL_STATUS)
struct hfp_slc_handle;
@@ -53,7 +43,4 @@ struct hfp_slc_handle *cras_hfp_ag_get_active_handle();
/* Gets the SLC handle for given cras_bt_device. */
struct hfp_slc_handle *cras_hfp_ag_get_slc(struct cras_bt_device *device);
-/* Gets the logger for WBS packet status. */
-struct packet_status_logger *cras_hfp_ag_get_wbs_logger();
-
#endif /* CRAS_HFP_AG_PROFILE_H_ */
diff --git a/cras/src/server/cras_hfp_alsa_iodev.c b/cras/src/server/cras_hfp_alsa_iodev.c
index c1b60b30..aecc47b9 100644
--- a/cras/src/server/cras_hfp_alsa_iodev.c
+++ b/cras/src/server/cras_hfp_alsa_iodev.c
@@ -12,6 +12,7 @@
#include "cras_iodev.h"
#include "cras_system_state.h"
#include "cras_util.h"
+#include "sfh.h"
#include "utlist.h"
#include "cras_bt_device.h"
@@ -32,15 +33,6 @@ struct hfp_alsa_io {
struct cras_iodev *aio;
};
-static int hfp_alsa_get_valid_frames(struct cras_iodev *iodev,
- struct timespec *hw_tstamp)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- return aio->get_valid_frames(aio, hw_tstamp);
-}
-
static int hfp_alsa_open_dev(struct cras_iodev *iodev)
{
struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
@@ -51,7 +43,41 @@ static int hfp_alsa_open_dev(struct cras_iodev *iodev)
static int hfp_alsa_update_supported_formats(struct cras_iodev *iodev)
{
+ struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
+ struct cras_iodev *aio = hfp_alsa_io->aio;
+ int rc, i;
+
/* 16 bit, mono, 8kHz (narrow band speech); */
+ rc = aio->update_supported_formats(aio);
+ if (rc)
+ return rc;
+
+ for (i = 0; aio->supported_rates[i]; ++i)
+ if (aio->supported_rates[i] == 8000)
+ break;
+ if (aio->supported_rates[i] != 8000)
+ return -EINVAL;
+
+ for (i = 0; aio->supported_channel_counts[i]; ++i)
+ if (aio->supported_channel_counts[i] == 1)
+ break;
+ if (aio->supported_channel_counts[i] != 1)
+ return -EINVAL;
+
+ for (i = 0; aio->supported_formats[i]; ++i)
+ if (aio->supported_formats[i] == SND_PCM_FORMAT_S16_LE)
+ break;
+ if (aio->supported_formats[i] != SND_PCM_FORMAT_S16_LE)
+ return -EINVAL;
+
+ free(aio->format);
+ aio->format = malloc(sizeof(struct cras_audio_format));
+ if (!aio->format)
+ return -ENOMEM;
+ aio->format->format = SND_PCM_FORMAT_S16_LE;
+ aio->format->frame_rate = 8000;
+ aio->format->num_channels = 1;
+
free(iodev->supported_rates);
iodev->supported_rates = malloc(2 * sizeof(*iodev->supported_rates));
if (!iodev->supported_rates)
@@ -84,15 +110,6 @@ static int hfp_alsa_configure_dev(struct cras_iodev *iodev)
struct cras_iodev *aio = hfp_alsa_io->aio;
int rc;
- /* Fill back the format iodev is using. */
- if (aio->format == NULL) {
- aio->format = (struct cras_audio_format *)malloc(
- sizeof(*aio->format));
- if (!aio->format)
- return -ENOMEM;
- *aio->format = *iodev->format;
- }
-
rc = aio->configure_dev(aio);
if (rc) {
syslog(LOG_ERR, "Failed to configure aio: %d\n", rc);
@@ -118,7 +135,6 @@ static int hfp_alsa_close_dev(struct cras_iodev *iodev)
struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
struct cras_iodev *aio = hfp_alsa_io->aio;
- hfp_set_call_status(hfp_alsa_io->slc, 0);
cras_bt_device_put_sco(hfp_alsa_io->device);
cras_iodev_free_format(iodev);
return aio->close_dev(aio);
@@ -218,21 +234,6 @@ static int hfp_alsa_is_free_running(const struct cras_iodev *iodev)
return aio->is_free_running(aio);
}
-static int hfp_alsa_output_underrun(struct cras_iodev *iodev)
-{
- struct hfp_alsa_io *hfp_alsa_io = (struct hfp_alsa_io *)iodev;
- struct cras_iodev *aio = hfp_alsa_io->aio;
-
- /*
- * Copy iodev->min_cb_level and iodev->max_cb_level from the parent
- * (i.e. hfp_alsa_iodev). output_underrun() of alsa_io will use them.
- */
- aio->min_cb_level = iodev->min_cb_level;
- aio->max_cb_level = iodev->max_cb_level;
-
- return aio->output_underrun(aio);
-}
-
struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
struct cras_bt_device *device,
struct hfp_slc_handle *slc,
@@ -258,9 +259,13 @@ struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
name = cras_bt_device_name(device);
if (!name)
name = cras_bt_device_object_path(device);
- snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
+ snprintf(iodev->info.name, sizeof(iodev->info.name), "%s.HFP_PCM",
+ name);
iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
- iodev->info.stable_id = cras_bt_device_get_stable_id(device);
+ iodev->info.stable_id =
+ SuperFastHash(cras_bt_device_object_path(device),
+ strlen(cras_bt_device_object_path(device)),
+ strlen(cras_bt_device_object_path(device)));
iodev->open_dev = hfp_alsa_open_dev;
iodev->update_supported_formats = hfp_alsa_update_supported_formats;
@@ -276,10 +281,8 @@ struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
iodev->update_active_node = hfp_alsa_update_active_node;
iodev->start = hfp_alsa_start;
iodev->set_volume = hfp_alsa_set_volume;
- iodev->get_valid_frames = hfp_alsa_get_valid_frames;
iodev->no_stream = hfp_alsa_no_stream;
iodev->is_free_running = hfp_alsa_is_free_running;
- iodev->output_underrun = hfp_alsa_output_underrun;
iodev->min_buffer_level = aio->min_buffer_level;
@@ -288,28 +291,13 @@ struct cras_iodev *hfp_alsa_iodev_create(struct cras_iodev *aio,
strcpy(node->name, iodev->info.name);
node->plugged = 1;
- /* If headset mic uses legacy narrow band, i.e CVSD codec, report a
- * different node type so UI can set different plug priority. */
node->type = CRAS_NODE_TYPE_BLUETOOTH;
- if ((hfp_slc_get_selected_codec(hfp_alsa_io->slc) ==
- HFP_CODEC_ID_CVSD) &&
- (iodev->direction == CRAS_STREAM_INPUT))
- node->type = CRAS_NODE_TYPE_BLUETOOTH_NB_MIC;
node->volume = 100;
gettimeofday(&node->plugged_time, NULL);
- /* Prepare active node before append, so bt_io can extract correct
- * info from hfp_alsa iodev and node. */
+ cras_bt_device_append_iodev(device, iodev, profile);
cras_iodev_add_node(iodev, node);
cras_iodev_set_active_node(iodev, node);
- cras_bt_device_append_iodev(device, iodev, profile);
-
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels = 1;
-
- /* Specifically disable EWMA calculation on this and the child iodev. */
- ewma_power_disable(&iodev->ewma);
- ewma_power_disable(&aio->ewma);
return iodev;
}
diff --git a/cras/src/server/cras_hfp_info.c b/cras/src/server/cras_hfp_info.c
index fc407b29..02bc8b4c 100644
--- a/cras/src/server/cras_hfp_info.c
+++ b/cras/src/server/cras_hfp_info.c
@@ -10,7 +10,6 @@
#include <syslog.h>
#include "audio_thread.h"
-#include "bluetooth.h"
#include "byte_buffer.h"
#include "cras_hfp_info.h"
#include "cras_hfp_slc.h"
@@ -19,7 +18,6 @@
#include "cras_sbc_codec.h"
#include "cras_server_metrics.h"
#include "utlist.h"
-#include "packet_status_logger.h"
/* The max buffer size. Note that the actual used size must set to multiple
* of SCO packet size, and the packet size does not necessarily be equal to
@@ -41,21 +39,12 @@
/* For one mSBC 1 compressed wideband audio channel the HCI packets will
* be 3 octets of HCI header + 60 octets of data. */
#define MSBC_PKT_SIZE 60
+#define WRITE_BUF_SIZE_BYTES MSBC_PKT_SIZE
+#define HCI_SCO_HDR_SIZE_BYTES 3
+#define HCI_SCO_PKT_SIZE (MSBC_PKT_SIZE + HCI_SCO_HDR_SIZE_BYTES)
#define H2_HEADER_0 0x01
-/* Supported HCI SCO packet sizes. The wideband speech mSBC frame parsing
- * code ties to limited packet size values. Specifically list them out
- * to check against when setting packet size.
- *
- * Temp buffer size should be set to least common multiple of HCI SCO packet
- * size and MSBC_PKT_SIZE for optimizing buffer copy.
- * To add a new supported packet size value, add corresponding entry to the
- * lists, test the read/write msbc code, and fix the code if needed.
- */
-static const size_t wbs_supported_packet_size[] = { 60, 24, 0 };
-static const size_t wbs_hci_sco_buffer_size[] = { 60, 120, 0 };
-
/* Second octet of H2 header is composed by 4 bits fixed 0x8 and 4 bits
* sequence number 0000, 0011, 1100, 1111. */
static const uint8_t h2_header_frames_count[] = { 0x08, 0x38, 0xc8, 0xf8 };
@@ -81,20 +70,11 @@ static const uint8_t h2_header_frames_count[] = { 0x08, 0x38, 0xc8, 0xf8 };
* read_cb - Callback to call when SCO socket can read. It returns the
* number of PCM bytes read.
* write_cb - Callback to call when SCO socket can write.
- * write_buf - Temp buffer for writeing HCI SCO packet in wideband.
- * read_buf - Temp buffer for reading HCI SCO packet in wideband.
+ * hci_sco_buf - Buffer to read one HCI SCO packet.
* input_format_bytes - The audio format bytes for input device. 0 means
* there is no input device for the hfp_info.
* output_format_bytes - The audio format bytes for output device. 0 means
* there is no output device for the hfp_info.
- * write_wp - Write pointer of write_buf.
- * write_rp - Read pointer of write_buf.
- * read_wp - Write pointer of read_buf.
- * read_rp - Read pointer of read_buf.
- * read_align_cb - Callback used to align mSBC frame reading with read buf.
- * msbc_read_current_corrupted - Flag to mark if the current mSBC frame
- * read is corrupted.
- * wbs_logger - The logger for packet status in WBS.
*/
struct hfp_info {
int fd;
@@ -111,17 +91,10 @@ struct hfp_info {
unsigned int msbc_num_lost_frames;
int (*read_cb)(struct hfp_info *info);
int (*write_cb)(struct hfp_info *info);
- uint8_t *write_buf;
- uint8_t *read_buf;
+ uint8_t write_buf[WRITE_BUF_SIZE_BYTES];
+ uint8_t hci_sco_buf[HCI_SCO_PKT_SIZE];
size_t input_format_bytes;
size_t output_format_bytes;
- size_t write_wp;
- size_t write_rp;
- size_t read_wp;
- size_t read_rp;
- int (*read_align_cb)(uint8_t *buf);
- bool msbc_read_current_corrupted;
- struct packet_status_logger *wbs_logger;
};
int hfp_info_add_iodev(struct hfp_info *info,
@@ -266,66 +239,43 @@ int hfp_write_msbc(struct hfp_info *info)
size_t encoded;
int err;
int pcm_encoded;
- unsigned int pcm_avail, to_write;
+ unsigned int pcm_avail;
uint8_t *samples;
uint8_t *wp;
- if (info->write_rp + info->packet_size <= info->write_wp)
- goto msbc_send_again;
-
- /* Make sure there are MSBC_CODE_SIZE bytes to encode. */
samples = buf_read_pointer_size(info->playback_buf, &pcm_avail);
- if (pcm_avail < MSBC_CODE_SIZE) {
- to_write = MSBC_CODE_SIZE - pcm_avail;
- /*
- * Size of playback_buf is multiple of MSBC_CODE_SIZE so we
- * are safe to prepare the buffer by appending some zero bytes.
- */
- wp = buf_write_pointer_size(info->playback_buf, &pcm_avail);
- memset(wp, 0, to_write);
- buf_increment_write(info->playback_buf, to_write);
-
- samples = buf_read_pointer_size(info->playback_buf, &pcm_avail);
- if (pcm_avail < MSBC_CODE_SIZE)
- return -EINVAL;
- }
-
- /* Encode the next MSBC_CODE_SIZE of bytes. */
- wp = info->write_buf + info->write_wp;
- wp[0] = H2_HEADER_0;
- wp[1] = h2_header_frames_count[info->msbc_num_out_frames % 4];
- pcm_encoded = info->msbc_write->encode(
- info->msbc_write, samples, pcm_avail, wp + MSBC_H2_HEADER_LEN,
- MSBC_PKT_SIZE - MSBC_H2_HEADER_LEN, &encoded);
- if (pcm_encoded < 0) {
- syslog(LOG_ERR, "msbc encoding err: %s", strerror(pcm_encoded));
- return pcm_encoded;
+ wp = info->write_buf;
+ if (pcm_avail >= MSBC_CODE_SIZE) {
+ /* Encode more */
+ wp[0] = H2_HEADER_0;
+ wp[1] = h2_header_frames_count[info->msbc_num_out_frames % 4];
+ pcm_encoded = info->msbc_write->encode(
+ info->msbc_write, samples, pcm_avail,
+ wp + MSBC_H2_HEADER_LEN,
+ WRITE_BUF_SIZE_BYTES - MSBC_H2_HEADER_LEN, &encoded);
+ if (pcm_encoded < 0) {
+ syslog(LOG_ERR, "msbc encoding err: %s",
+ strerror(pcm_encoded));
+ return pcm_encoded;
+ }
+ buf_increment_read(info->playback_buf, pcm_encoded);
+ pcm_avail -= pcm_encoded;
+ } else {
+ memset(wp, 0, WRITE_BUF_SIZE_BYTES);
}
- buf_increment_read(info->playback_buf, pcm_encoded);
- pcm_avail -= pcm_encoded;
- info->write_wp += MSBC_PKT_SIZE;
- info->msbc_num_out_frames++;
-
- if (info->write_rp + info->packet_size > info->write_wp)
- return 0;
msbc_send_again:
- err = send(info->fd, info->write_buf + info->write_rp,
- info->packet_size, 0);
+ err = send(info->fd, info->write_buf, MSBC_PKT_SIZE, 0);
if (err < 0) {
if (errno == EINTR)
goto msbc_send_again;
return err;
}
- if (err != (int)info->packet_size) {
+ if (err != MSBC_PKT_SIZE) {
syslog(LOG_ERR, "Partially write %d bytes for mSBC", err);
return -1;
}
- info->write_rp += info->packet_size;
- if (info->write_rp == info->write_wp) {
- info->write_rp = 0;
- info->write_wp = 0;
- }
+ info->msbc_num_out_frames++;
return err;
}
@@ -406,20 +356,6 @@ static const uint8_t *extract_msbc_frame(const uint8_t *input, int len,
return NULL;
}
-/* Log value 0 when packet is received. */
-static void log_wbs_packet_received(struct hfp_info *info)
-{
- if (info->wbs_logger)
- packet_status_logger_update(info->wbs_logger, 0);
-}
-
-/* Log value 1 when packet is lost. */
-static void log_wbs_packet_lost(struct hfp_info *info)
-{
- if (info->wbs_logger)
- packet_status_logger_update(info->wbs_logger, 1);
-}
-
/*
* Handle the case when mSBC frame is considered lost.
* Args:
@@ -436,8 +372,6 @@ static int handle_packet_loss(struct hfp_info *info)
info->msbc_num_in_frames++;
info->msbc_num_lost_frames++;
- log_wbs_packet_lost(info);
-
in_bytes = buf_write_pointer_size(info->capture_buf, &pcm_avail);
if (pcm_avail < MSBC_CODE_SIZE)
return 0;
@@ -452,16 +386,6 @@ static int handle_packet_loss(struct hfp_info *info)
return decoded;
}
-/* Checks if mSBC frame header aligns with the beginning of buffer. */
-static int msbc_frame_align(uint8_t *buf)
-{
- if ((buf[0] != H2_HEADER_0) || (buf[2] != MSBC_SYNC_WORD)) {
- syslog(LOG_DEBUG, "Waiting for valid mSBC frame head");
- return 0;
- }
- return 1;
-}
-
int hfp_read_msbc(struct hfp_info *info)
{
int err = 0;
@@ -473,23 +397,8 @@ int hfp_read_msbc(struct hfp_info *info)
const uint8_t *frame_head = NULL;
unsigned int seq;
- struct msghdr msg = { 0 };
- struct iovec iov;
- struct cmsghdr *cmsg;
- const unsigned int control_size = CMSG_SPACE(sizeof(int));
- char control[control_size];
- uint8_t pkt_status;
-
- memset(control, 0, sizeof(control));
recv_msbc_bytes:
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- iov.iov_base = info->read_buf + info->read_wp;
- iov.iov_len = info->packet_size;
- msg.msg_control = control;
- msg.msg_controllen = control_size;
-
- err = recvmsg(info->fd, &msg, 0);
+ err = recv(info->fd, info->hci_sco_buf, HCI_SCO_PKT_SIZE, 0);
if (err < 0) {
syslog(LOG_ERR, "HCI SCO packet read err %s", strerror(errno));
if (errno == EINTR)
@@ -500,78 +409,40 @@ recv_msbc_bytes:
* Treat return code 0 (socket shutdown) as error here. BT stack
* shall send signal to main thread for device disconnection.
*/
- if (err != (int)info->packet_size) {
+ if (err != HCI_SCO_PKT_SIZE) {
syslog(LOG_ERR, "Partially read %d bytes for mSBC packet", err);
return -1;
}
- /* Offset in input data breaks mSBC frame parsing. Discard this packet
- * until read alignment succeed. */
- if (info->read_align_cb) {
- if (!info->read_align_cb(info->read_buf))
- return 0;
- else
- info->read_align_cb = NULL;
- }
- info->read_wp += err;
-
- pkt_status = 0;
- for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
- cmsg = CMSG_NXTHDR(&msg, cmsg)) {
- if (cmsg->cmsg_level == SOL_BLUETOOTH &&
- cmsg->cmsg_type == BT_SCM_PKT_STATUS) {
- size_t len = cmsg->cmsg_len - sizeof(*cmsg);
- memcpy(&pkt_status, CMSG_DATA(cmsg), len);
- }
- }
-
/*
* HCI SCO packet status flag:
* 0x00 - correctly received data.
* 0x01 - possibly invalid data.
* 0x10 - No data received.
* 0x11 - Data partially lost.
- *
- * If the latest SCO packet read doesn't cross the boundary of a mSBC
- * frame, the packet status flag can be used to derive if the current
- * mSBC frame is corrupted.
*/
- if (info->read_rp + MSBC_PKT_SIZE >= info->read_wp)
- info->msbc_read_current_corrupted |= (pkt_status > 0);
-
- /* Read buffer not enough to parse another mSBC frame. */
- if (info->read_rp + MSBC_PKT_SIZE > info->read_wp)
- return 0;
-
- if (info->msbc_read_current_corrupted) {
- syslog(LOG_DEBUG, "mSBC frame corrputed from packet status");
- info->msbc_read_current_corrupted = 0;
- frame_head = NULL;
- } else {
- frame_head =
- extract_msbc_frame(info->read_buf + info->read_rp,
- info->read_wp - info->read_rp, &seq);
- if (!frame_head)
- syslog(LOG_DEBUG, "Failed to extract msbc frame");
+ err = (info->hci_sco_buf[1] >> 4);
+ if (err) {
+ syslog(LOG_ERR, "HCI SCO status flag %u", err);
+ return handle_packet_loss(info);
}
- /*
- * Done with parsing the raw bytes just read. If mSBC frame head not
- * found, we shall handle it as packet loss.
+ /* There is chance that erroneous data reporting gives us false positive.
+ * If mSBC frame extraction fails, we shall handle it as packet loss.
*/
- info->read_rp += MSBC_PKT_SIZE;
- if (info->read_rp == info->read_wp) {
- info->read_rp = 0;
- info->read_wp = 0;
- }
- if (!frame_head)
+ frame_head =
+ extract_msbc_frame(info->hci_sco_buf + HCI_SCO_HDR_SIZE_BYTES,
+ MSBC_PKT_SIZE, &seq);
+ if (!frame_head) {
+ syslog(LOG_ERR, "Failed to extract msbc frame");
return handle_packet_loss(info);
+ }
/*
* Consider packet loss when found discontinuity in sequence number.
*/
while (seq != (info->msbc_num_in_frames % 4)) {
- syslog(LOG_DEBUG, "SCO packet seq unmatch");
+ syslog(LOG_ERR, "SCO packet seq unmatch");
err = handle_packet_loss(info);
if (err < 0)
return err;
@@ -599,7 +470,6 @@ recv_msbc_bytes:
pcm_read += err;
} else {
/* Good mSBC frame decoded. */
- log_wbs_packet_received(info);
buf_increment_write(info->capture_buf, pcm_decoded);
info->msbc_num_in_frames++;
cras_msbc_plc_handle_good_frames(info->msbc_plc, capture_buf,
@@ -661,31 +531,24 @@ recv_sample:
* 2. When input device not attached, ignore the data just read.
* 3. When output device attached, write one chunk of MTU bytes of data.
*/
-static int hfp_info_callback(void *arg, int revents)
+static int hfp_info_callback(void *arg)
{
struct hfp_info *info = (struct hfp_info *)arg;
- int err = 0;
+ int err;
if (!info->started)
return 0;
- /* Allow last read before handling error or hang-up events. */
- if (revents & POLLIN) {
- err = info->read_cb(info);
- if (err < 0) {
- syslog(LOG_ERR, "Read error");
- goto read_write_error;
- }
+ err = info->read_cb(info);
+ if (err < 0) {
+ syslog(LOG_ERR, "Read error");
+ goto read_write_error;
}
+
/* Ignore the bytes just read if input dev not in present */
if (!info->input_format_bytes)
buf_increment_read(info->capture_buf, err);
- if (revents & (POLLERR | POLLHUP)) {
- syslog(LOG_ERR, "Error polling SCO socket, revent %d", revents);
- goto read_write_error;
- }
-
/* Without output stream's presence, we shall still send zero packets
* to HF. This is required for some HF devices to start sending non-zero
* data to AG.
@@ -715,7 +578,7 @@ read_write_error:
return 0;
}
-struct hfp_info *hfp_info_create()
+struct hfp_info *hfp_info_create(int codec)
{
struct hfp_info *info;
info = (struct hfp_info *)calloc(1, sizeof(*info));
@@ -730,6 +593,17 @@ struct hfp_info *hfp_info_create()
if (!info->playback_buf)
goto error;
+ if (codec == HFP_CODEC_ID_MSBC) {
+ info->write_cb = hfp_write_msbc;
+ info->read_cb = hfp_read_msbc;
+ info->msbc_read = cras_msbc_codec_create();
+ info->msbc_write = cras_msbc_codec_create();
+ info->msbc_plc = cras_msbc_plc_create();
+ } else {
+ info->write_cb = hfp_write;
+ info->read_cb = hfp_read;
+ }
+
return info;
error:
@@ -743,18 +617,12 @@ error:
return NULL;
}
-void hfp_info_set_wbs_logger(struct hfp_info *info,
- struct packet_status_logger *wbs_logger)
-{
- info->wbs_logger = wbs_logger;
-}
-
int hfp_info_running(struct hfp_info *info)
{
return info->started;
}
-int hfp_info_start(int fd, unsigned int mtu, int codec, struct hfp_info *info)
+int hfp_info_start(int fd, unsigned int mtu, struct hfp_info *info)
{
info->fd = fd;
info->mtu = mtu;
@@ -764,51 +632,12 @@ int hfp_info_start(int fd, unsigned int mtu, int codec, struct hfp_info *info)
buf_reset(info->playback_buf);
buf_reset(info->capture_buf);
- if (codec == HFP_CODEC_ID_MSBC) {
- int i;
- for (i = 0; wbs_supported_packet_size[i] != 0; i++) {
- if (info->packet_size == wbs_supported_packet_size[i])
- break;
- }
- /* In case of unsupported value, error log and fallback to
- * MSBC_PKT_SIZE(60). */
- if (wbs_supported_packet_size[i] == 0) {
- syslog(LOG_ERR, "Unsupported packet size %u",
- info->packet_size);
- i = 0;
- }
- info->packet_size = wbs_supported_packet_size[i];
- info->write_buf = (uint8_t *)malloc(wbs_hci_sco_buffer_size[i]);
- info->read_buf = (uint8_t *)malloc(wbs_hci_sco_buffer_size[i]);
-
- info->write_cb = hfp_write_msbc;
- info->read_cb = hfp_read_msbc;
- info->msbc_read = cras_msbc_codec_create();
- info->msbc_write = cras_msbc_codec_create();
- info->msbc_plc = cras_msbc_plc_create();
-
- packet_status_logger_init(info->wbs_logger);
- } else {
- info->write_cb = hfp_write;
- info->read_cb = hfp_read;
- }
-
- audio_thread_add_events_callback(info->fd, hfp_info_callback, info,
- POLLIN | POLLERR | POLLHUP);
+ audio_thread_add_callback(info->fd, hfp_info_callback, info);
info->started = 1;
info->msbc_num_out_frames = 0;
info->msbc_num_in_frames = 0;
info->msbc_num_lost_frames = 0;
- info->write_rp = 0;
- info->write_wp = 0;
- info->read_rp = 0;
- info->read_wp = 0;
-
- /* Mark as aligned if packet size equals to MSBC_PKT_SIZE. */
- info->read_align_cb =
- (info->packet_size == MSBC_PKT_SIZE) ? NULL : msbc_frame_align;
- info->msbc_read_current_corrupted = 0;
return 0;
}
@@ -825,28 +654,6 @@ int hfp_info_stop(struct hfp_info *info)
info->fd = 0;
info->started = 0;
- /* Unset the write/read callbacks. */
- info->write_cb = NULL;
- info->read_cb = NULL;
-
- if (info->write_buf)
- free(info->write_buf);
- if (info->read_buf)
- free(info->read_buf);
-
- if (info->msbc_read) {
- cras_sbc_codec_destroy(info->msbc_read);
- info->msbc_read = NULL;
- }
- if (info->msbc_write) {
- cras_sbc_codec_destroy(info->msbc_write);
- info->msbc_write = NULL;
- }
- if (info->msbc_plc) {
- cras_msbc_plc_destroy(info->msbc_plc);
- info->msbc_plc = NULL;
- }
-
if (info->msbc_num_in_frames) {
cras_server_metrics_hfp_packet_loss(
(float)info->msbc_num_lost_frames /
@@ -864,5 +671,12 @@ void hfp_info_destroy(struct hfp_info *info)
if (info->playback_buf)
byte_buffer_destroy(&info->playback_buf);
+ if (info->msbc_read)
+ cras_sbc_codec_destroy(info->msbc_read);
+ if (info->msbc_write)
+ cras_sbc_codec_destroy(info->msbc_write);
+ if (info->msbc_plc)
+ cras_msbc_plc_destroy(info->msbc_plc);
+
free(info);
}
diff --git a/cras/src/server/cras_hfp_info.h b/cras/src/server/cras_hfp_info.h
index 3472aeab..334278e5 100644
--- a/cras/src/server/cras_hfp_info.h
+++ b/cras/src/server/cras_hfp_info.h
@@ -24,25 +24,21 @@ struct hfp_packet_size_changed_callback {
struct hfp_info;
/* Creates an hfp_info instance.
+ * Args:
+ * codec - 1 for CVSD, 2 for mSBC per HFP 1.7 specification.
*/
-struct hfp_info *hfp_info_create();
+struct hfp_info *hfp_info_create(int codec);
/* Destroys given hfp_info instance. */
void hfp_info_destroy(struct hfp_info *info);
-/* Sets the wbs_logger to hfp_info instance. */
-void hfp_info_set_wbs_logger(struct hfp_info *info,
- struct packet_status_logger *wbs_logger);
-
/* Checks if given hfp_info is running. */
int hfp_info_running(struct hfp_info *info);
/* Starts the hfp_info to transmit and reveice samples to and from the file
* descriptor of a SCO socket. This should be called from main thread.
- * Args:
- * codec - 1 for CVSD, 2 for mSBC per HFP 1.7 specification.
*/
-int hfp_info_start(int fd, unsigned int mtu, int codec, struct hfp_info *info);
+int hfp_info_start(int fd, unsigned int mtu, struct hfp_info *info);
/* Stops given hfp_info. This implies sample transmission will
* stop and socket be closed. This should be called from main thread.
diff --git a/cras/src/server/cras_hfp_iodev.c b/cras/src/server/cras_hfp_iodev.c
index 6a4ced04..08e26d6d 100644
--- a/cras/src/server/cras_hfp_iodev.c
+++ b/cras/src/server/cras_hfp_iodev.c
@@ -17,6 +17,7 @@
#include "cras_iodev.h"
#include "cras_system_state.h"
#include "cras_util.h"
+#include "sfh.h"
#include "utlist.h"
/* Implementation of bluetooth hands-free profile iodev.
@@ -43,10 +44,12 @@ static int update_supported_formats(struct cras_iodev *iodev)
{
struct hfp_io *hfpio = (struct hfp_io *)iodev;
+ /* 16 bit, mono, 8kHz for narrowband and 16KHz for wideband */
+ iodev->format->format = SND_PCM_FORMAT_S16_LE;
+
free(iodev->supported_rates);
iodev->supported_rates = (size_t *)malloc(2 * sizeof(size_t));
- /* 16 bit, mono, 8kHz for narrowband and 16KHz for wideband */
iodev->supported_rates[0] =
(hfp_slc_get_selected_codec(hfpio->slc) == HFP_CODEC_ID_MSBC) ?
16000 :
@@ -122,12 +125,6 @@ static int frames_queued(const struct cras_iodev *iodev,
return hfp_buf_queued(hfpio->info, iodev->direction);
}
-static int output_underrun(struct cras_iodev *iodev)
-{
- /* Handle it the same way as cras_iodev_output_underrun(). */
- return cras_iodev_fill_odev_zeros(iodev, iodev->min_cb_level);
-}
-
static int configure_dev(struct cras_iodev *iodev)
{
struct hfp_io *hfpio = (struct hfp_io *)iodev;
@@ -136,18 +133,12 @@ static int configure_dev(struct cras_iodev *iodev)
/* Assert format is set before opening device. */
if (iodev->format == NULL)
return -EINVAL;
-
iodev->format->format = SND_PCM_FORMAT_S16_LE;
cras_iodev_init_audio_area(iodev, iodev->format->num_channels);
if (hfp_info_running(hfpio->info))
goto add_dev;
- /*
- * Might require a codec negotiation before building the sco connection.
- */
- hfp_slc_codec_connection_setup(hfpio->slc);
-
sk = cras_bt_device_sco_connect(hfpio->device,
hfp_slc_get_selected_codec(hfpio->slc));
if (sk < 0)
@@ -157,8 +148,7 @@ static int configure_dev(struct cras_iodev *iodev)
hfpio->device, sk, hfp_slc_get_selected_codec(hfpio->slc));
/* Start hfp_info */
- err = hfp_info_start(sk, mtu, hfp_slc_get_selected_codec(hfpio->slc),
- hfpio->info);
+ err = hfp_info_start(sk, mtu, hfpio->info);
if (err)
goto error;
@@ -260,12 +250,6 @@ static void update_active_node(struct cras_iodev *iodev, unsigned node_idx,
{
}
-int hfp_iodev_is_hsp(struct cras_iodev *iodev)
-{
- struct hfp_io *hfpio = (struct hfp_io *)iodev;
- return hfp_slc_is_hsp(hfpio->slc);
-}
-
void hfp_free_resources(struct hfp_io *hfpio)
{
struct cras_ionode *node;
@@ -308,7 +292,10 @@ struct cras_iodev *hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,
snprintf(iodev->info.name, sizeof(iodev->info.name), "%s", name);
iodev->info.name[ARRAY_SIZE(iodev->info.name) - 1] = 0;
- iodev->info.stable_id = cras_bt_device_get_stable_id(device);
+ iodev->info.stable_id =
+ SuperFastHash(cras_bt_device_object_path(device),
+ strlen(cras_bt_device_object_path(device)),
+ strlen(cras_bt_device_object_path(device)));
iodev->configure_dev = configure_dev;
iodev->frames_queued = frames_queued;
@@ -321,36 +308,22 @@ struct cras_iodev *hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,
iodev->update_supported_formats = update_supported_formats;
iodev->update_active_node = update_active_node;
iodev->set_volume = set_hfp_volume;
- iodev->output_underrun = output_underrun;
node = (struct cras_ionode *)calloc(1, sizeof(*node));
node->dev = iodev;
strcpy(node->name, iodev->info.name);
node->plugged = 1;
- /* If headset mic doesn't support the wideband speech, report a
- * different node type so UI can set different plug priority. */
node->type = CRAS_NODE_TYPE_BLUETOOTH;
- if (!hfp_slc_get_wideband_speech_supported(hfpio->slc) &&
- (dir == CRAS_STREAM_INPUT))
- node->type = CRAS_NODE_TYPE_BLUETOOTH_NB_MIC;
-
node->volume = 100;
gettimeofday(&node->plugged_time, NULL);
- /* Prepare active node before append, so bt_io can extract correct
- * info from HFP iodev and node. */
+ cras_bt_device_append_iodev(device, iodev, profile);
cras_iodev_add_node(iodev, node);
cras_iodev_set_active_node(iodev, node);
- cras_bt_device_append_iodev(device, iodev, profile);
hfpio->info = info;
- /* Record max supported channels into cras_iodev_info. */
- iodev->info.max_supported_channels = 1;
-
- ewma_power_disable(&iodev->ewma);
-
return iodev;
error:
diff --git a/cras/src/server/cras_hfp_iodev.h b/cras/src/server/cras_hfp_iodev.h
index b50aa259..b2762bef 100644
--- a/cras/src/server/cras_hfp_iodev.h
+++ b/cras/src/server/cras_hfp_iodev.h
@@ -23,11 +23,4 @@ struct cras_iodev *hfp_iodev_create(enum CRAS_STREAM_DIRECTION dir,
void hfp_iodev_destroy(struct cras_iodev *iodev);
-/*
- * Returns if the iodev is running for a HSP connection. Note that
- * hfp_iodev is implemented for both HFP and HSP connection. And this
- * function allows caller to test if it falls to the rare case - HSP.
- */
-int hfp_iodev_is_hsp(struct cras_iodev *iodev);
-
#endif /* CRAS_HFP_IODEV_H_ */
diff --git a/cras/src/server/cras_hfp_slc.c b/cras/src/server/cras_hfp_slc.c
index 28f73edc..6b30a0b3 100644
--- a/cras/src/server/cras_hfp_slc.c
+++ b/cras/src/server/cras_hfp_slc.c
@@ -10,38 +10,28 @@
#include "cras_bt_device.h"
#include "cras_bt_log.h"
-#include "cras_observer.h"
#include "cras_telephony.h"
#include "cras_hfp_slc.h"
-#include "cras_server_metrics.h"
#include "cras_system_state.h"
#include "cras_tm.h"
-#include "cras_util.h"
/* Message start and end with "\r\n". refer to spec 4.33. */
#define AT_CMD(cmd) "\r\n" cmd "\r\n"
-/* The timeout between event reporting and HF indicator commands */
-#define HF_INDICATORS_TIMEOUT_MS 2000
-/* The sleep time before reading and processing the following AT commands during
- * codec connection setup.
- */
-#define CODEC_CONN_SLEEP_TIME_US 2000
+/* The timeout between service level initialized and codec negotiation
+ * completed. */
+#define CODEC_NEGOTIATION_TIMEOUT_MS 500
#define SLC_BUF_SIZE_BYTES 256
/* Indicator update command response and indicator indices.
- * Note that indicator index starts from '1', index 0 is used for CRAS to record
- * if the event report has been enabled or not.
+ * Note that indicator index starts from '1'.
*/
-#define CRAS_INDICATOR_ENABLE_INDEX 0
#define BATTERY_IND_INDEX 1
#define SIGNAL_IND_INDEX 2
#define SERVICE_IND_INDEX 3
#define CALL_IND_INDEX 4
#define CALLSETUP_IND_INDEX 5
#define CALLHELD_IND_INDEX 6
-#define ROAM_IND_INDEX 7
-#define INDICATOR_IND_MAX 8
#define INDICATOR_UPDATE_RSP \
"+CIND: " \
"(\"battchg\",(0-5))," \
@@ -69,19 +59,19 @@
* signal - Current signal strength of AG stored in SLC.
* service - Current service availability of AG stored in SLC.
* callheld - Current callheld status of AG stored in SLC.
- * ind_event_reports - Activate statuses of indicator events reporting.
+ * ind_event_report - Activate status of indicator events reporting.
* ag_supported_features - Supported AG features bitmap.
- * hf_supported_features - Bit map of HF supported features.
- * hf_supports_battery_indicator - Bit map of battery indicator support of
- * connected HF.
- * hf_battery - Current battery level of HF reported by the HF. The data
- * range should be 0 ~ 100. Use -1 for no battery level reported.
+ * hf_codec_supported - Flags to indicate if codec is supported in HF.
+ * hf_supports_codec_negotiation - If the connected HF supports codec
+ * negotiation.
* preferred_codec - CVSD or mSBC based on the situation and strategy. This
- * needs not to be equal to selected_codec because codec negotiation
+ * need not to be equal to selected_codec because codec negotiation
* process may fail.
* selected_codec - The codec id defaults to HFP_CODEC_UNUSED and changes
* only if codec negotiation is supported and the negotiation flow
* has completed.
+ * pending_codec_negotiation - True if codec negotiation process has started
+ * but haven't got reply from HF.
* telephony - A reference of current telephony handle.
* device - The associated bt device.
*/
@@ -98,14 +88,13 @@ struct hfp_slc_handle {
int signal;
int service;
int callheld;
- int ind_event_reports[INDICATOR_IND_MAX];
+ int ind_event_report;
int ag_supported_features;
bool hf_codec_supported[HFP_MAX_CODECS];
- int hf_supported_features;
- int hf_supports_battery_indicator;
- int hf_battery;
+ int hf_supports_codec_negotiation;
int preferred_codec;
int selected_codec;
+ int pending_codec_negotiation;
struct cras_bt_device *device;
struct cras_timer *timer;
@@ -144,9 +133,7 @@ static int hfp_send_ind_event_report(struct hfp_slc_handle *handle,
{
char cmd[64];
- if (handle->is_hsp ||
- !handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] ||
- !handle->ind_event_reports[ind_index])
+ if (handle->is_hsp || !handle->ind_event_report)
return 0;
snprintf(cmd, 64, AT_CMD("+CIEV: %d,%d"), ind_index, value);
@@ -194,10 +181,6 @@ static int call_waiting_notify(struct hfp_slc_handle *handle, const char *buf)
*/
static int cli_notification(struct hfp_slc_handle *handle, const char *cmd)
{
- if (strlen(cmd) < 9) {
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
handle->cli_active = (cmd[8] == '1');
return hfp_send(handle, AT_CMD("OK"));
}
@@ -211,8 +194,6 @@ static int dial_number(struct hfp_slc_handle *handle, const char *cmd)
int rc, cmd_len;
cmd_len = strlen(cmd);
- if (cmd_len < 4)
- goto error_out;
if (cmd[3] == '>') {
/* Handle memory dial. Extract memory location from command
@@ -233,10 +214,6 @@ static int dial_number(struct hfp_slc_handle *handle, const char *cmd)
handle->telephony->callsetup = 2;
return hfp_send_ind_event_report(handle, CALLSETUP_IND_INDEX, 2);
-
-error_out:
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
}
/* AT+VTS command to generate a DTMF code. Mandatory per spec 4.27. */
@@ -263,23 +240,36 @@ static void initialize_slc_handle(struct cras_timer *timer, void *arg)
if (timer)
handle->timer = NULL;
+ /*
+ * Catch the case if mSBC codec negotiation never complete or even
+ * failed. AG side falls back to use codec CVSD and also tells
+ * HF to select CVSD again.
+ */
+ if ((handle->selected_codec == HFP_CODEC_UNUSED) &&
+ handle->hf_codec_supported[HFP_CODEC_ID_MSBC]) {
+ handle->preferred_codec = HFP_CODEC_ID_CVSD;
+ select_preferred_codec(handle);
+ }
+
+ /*
+ * Codec negotiation is considered to be ended at this point.
+ * The owner of init_cb may use hfp_slc_get_selected_codec() to
+ * query the final codec to use for this connection.
+ */
if (handle->init_cb) {
handle->init_cb(handle);
handle->init_cb = NULL;
}
}
-/* Handles the event that headset request to start a codec connection
- * procedure.
+/* Tasks to execute after receiving an AT command. This is useful because
+ * some HF replies to command X only after it sends command Y. We rely on
+ * this function to achieve reliable codec negotiation.
*/
-static int bluetooth_codec_connection(struct hfp_slc_handle *handle,
- const char *cmd)
+static void post_at_command_tasks(struct hfp_slc_handle *handle)
{
- /* Reset current selected codec to force a new codec connection
- * procedure when the next hfp_slc_codec_connection_setup is called.
- */
- handle->selected_codec = HFP_CODEC_UNUSED;
- return hfp_send(handle, AT_CMD("OK"));
+ if (handle->pending_codec_negotiation)
+ select_preferred_codec(handle);
}
/* Handles the event that headset request to select specific codec. */
@@ -288,136 +278,46 @@ static int bluetooth_codec_selection(struct hfp_slc_handle *handle,
{
char *tokens = strdup(cmd);
char *codec;
- int id, err;
+ int err;
+ handle->pending_codec_negotiation = 0;
strtok(tokens, "=");
codec = strtok(NULL, ",");
- if (!codec)
- goto bcs_cmd_cleanup;
- id = atoi(codec);
- if ((id <= HFP_CODEC_UNUSED) || (id >= HFP_MAX_CODECS)) {
- syslog(LOG_ERR, "%s: invalid codec id: '%s'", __func__, cmd);
- free(tokens);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
-
- if (id != handle->preferred_codec)
- syslog(LOG_WARNING, "%s: inconsistent codec id: '%s'", __func__,
- cmd);
- BTLOG(btlog, BT_CODEC_SELECTION, 1, id);
- handle->selected_codec = id;
+ if (codec) {
+ BTLOG(btlog, BT_CODEC_SELECTION, 1, atoi(codec));
+ handle->selected_codec = atoi(codec);
+ }
-bcs_cmd_cleanup:
- free(tokens);
err = hfp_send(handle, AT_CMD("OK"));
+ initialize_slc_handle(NULL, (void *)handle);
+ free(tokens);
return err;
}
/*
- * AT+IPHONEACCEV command from HF to report state change.You can find details
- * of this command in the Accessory Design Guidelines for Apple Devices R11
- * section 16.1.
+ * Possibly choose mSBC code from the supported codecs. Otherwise just
+ * initialize the SLC so the default CVSD codec is used.
*/
-static int apple_accessory_state_change(struct hfp_slc_handle *handle,
- const char *cmd)
+static void choose_codec_and_init_slc(struct hfp_slc_handle *handle)
{
- char *tokens, *num, *key, *val;
- int i, level;
-
- /* AT+IPHONEACCEV=Number of key/value pairs,key1,val1,key2,val2,...
- * Number of key/value pairs: The number of parameters coming next.
- * key: the type of change being reported:
- * 1 = Battery Level
- * 2 = Dock State
- * val: the value of the change:
- * Battery Level: string value between '0' and '9'
- * Dock State: 0 = undocked, 1 = docked
- */
- tokens = strdup(cmd);
- strtok(tokens, "=");
- num = strtok(NULL, ",");
- if (!num) {
- free(tokens);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
-
- for (i = 0; i < atoi(num); i++) {
- key = strtok(NULL, ",");
- val = strtok(NULL, ",");
- if (!key || !val) {
- syslog(LOG_WARNING,
- "IPHONEACCEV: Expected %d kv pairs but got %d",
- atoi(num), i);
- break;
- }
+ if (handle->hf_supports_codec_negotiation &&
+ handle->hf_codec_supported[HFP_CODEC_ID_MSBC]) {
+ /* Sets preferred codec to mSBC, and schedule callback to
+ * select preferred codec until reply received or timeout.
+ */
+ handle->preferred_codec = HFP_CODEC_ID_MSBC;
+ handle->pending_codec_negotiation = 1;
- if (atoi(key) == 1) {
- level = atoi(val);
- if (level >= 0 && level < 10) {
- cras_server_metrics_hfp_battery_report(
- CRAS_HFP_BATTERY_INDICATOR_APPLE);
- level = (level + 1) * 10;
- if (handle->hf_battery != level) {
- handle->hf_battery = level;
- cras_observer_notify_bt_battery_changed(
- cras_bt_device_address(
- handle->device),
- (uint32_t)(level));
- }
- } else {
- syslog(LOG_ERR,
- "Get invalid battery status from cmd:%s",
- cmd);
- }
- }
+ /* Delay init to give headset some time to confirm
+ * codec selection. */
+ handle->timer =
+ cras_tm_create_timer(cras_system_state_get_tm(),
+ CODEC_NEGOTIATION_TIMEOUT_MS,
+ initialize_slc_handle, handle);
+ } else {
+ initialize_slc_handle(NULL, (void *)handle);
}
- free(tokens);
- return hfp_send(handle, AT_CMD("OK"));
-}
-
-/*
- * AT+XAPL command from HF to enable Apple custom features. You can find details
- * of it in the Accessory Design Guidelines for Apple Devices R11 section 15.1.
- */
-static int apple_supported_features(struct hfp_slc_handle *handle,
- const char *cmd)
-{
- char *tokens, *features;
- int apple_features, err;
- char buf[64];
-
- /* AT+XAPL=<vendorID>-<productID>-<version>,<features>
- * Parse <features>, the only token we care about.
- */
- tokens = strdup(cmd);
- strtok(tokens, "=");
-
- strtok(NULL, ",");
- features = strtok(NULL, ",");
- if (!features)
- goto error_out;
-
- apple_features = atoi(features);
-
- if (apple_features & APL_BATTERY)
- handle->hf_supports_battery_indicator |=
- CRAS_HFP_BATTERY_INDICATOR_APPLE;
-
- snprintf(buf, 64, AT_CMD("+XAPL=iPhone,%d"),
- CRAS_APL_SUPPORTED_FEATURES);
- err = hfp_send(handle, buf);
- if (err)
- goto error_out;
-
- err = hfp_send(handle, AT_CMD("OK"));
- free(tokens);
- return err;
-
-error_out:
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- free(tokens);
- return hfp_send(handle, AT_CMD("ERROR"));
}
/* Handles the event when headset reports its available codecs list. */
@@ -441,11 +341,6 @@ static int available_codecs(struct hfp_slc_handle *handle, const char *cmd)
id_str = strtok(NULL, ",");
}
- if (hfp_slc_get_wideband_speech_supported(handle))
- handle->preferred_codec = HFP_CODEC_ID_MSBC;
- else
- handle->preferred_codec = HFP_CODEC_ID_CVSD;
-
free(tokens);
return hfp_send(handle, AT_CMD("OK"));
}
@@ -482,8 +377,7 @@ static int event_reporting(struct hfp_slc_handle *handle, const char *cmd)
goto event_reporting_done;
}
if (atoi(mode) == FORWARD_UNSOLICIT_RESULT_CODE)
- handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] =
- atoi(tmp);
+ handle->ind_event_report = atoi(tmp);
err = hfp_send(handle, AT_CMD("OK"));
if (err) {
@@ -492,21 +386,13 @@ static int event_reporting(struct hfp_slc_handle *handle, const char *cmd)
}
/*
- * Wait for HF to retrieve information about HF indicators and consider
- * the Service Level Connection to be fully initialized, and thereby
- * established, if HF doesn't support HF indicators.
+ * Consider the Service Level Connection to be fully initialized,
+ * and thereby established, after successfully responded with OK.
+ * However we should postpone the initialize call after codec selection,
+ * otherwise iodev could be open immediately while the headset is still
+ * communicating about which of CVSD or mSBC codec to use.
*/
- if (hfp_slc_get_hf_hf_indicators_supported(handle))
- handle->timer =
- cras_tm_create_timer(cras_system_state_get_tm(),
- HF_INDICATORS_TIMEOUT_MS,
- initialize_slc_handle, handle);
- /*
- * Otherwise, regard the Service Level Connection to be fully
- * initialized and ready for the potential codec negotiation.
- */
- else
- initialize_slc_handle(NULL, (void *)handle);
+ choose_codec_and_init_slc(handle);
event_reporting_done:
free(tokens);
@@ -607,26 +493,6 @@ static int operator_selection(struct hfp_slc_handle *handle, const char *buf)
return hfp_send(handle, AT_CMD("OK"));
}
-/* The AT+CHLD command is used to control call hold, release, and multiparty
- * states.
- */
-static int call_hold(struct hfp_slc_handle *handle, const char *buf)
-{
- int rc;
-
- // Chrome OS doesn't yet support CHLD features but we need to reply
- // the query with an empty feature list rather than "ERROR" to increase
- // interoperability with certain devices (b/172413440).
- if (strlen(buf) > 8 && buf[7] == '=' && buf[8] == '?') {
- rc = hfp_send(handle, AT_CMD("+CHLD:"));
- if (rc)
- return rc;
- return hfp_send(handle, AT_CMD("OK"));
- }
-
- return hfp_send(handle, AT_CMD("ERROR"));
-}
-
/* AT+CIND command retrieves the supported indicator and its corresponding
* range and order index or read current status of indicators. Mandatory
* support per spec 4.2.
@@ -636,11 +502,6 @@ static int report_indicators(struct hfp_slc_handle *handle, const char *cmd)
int err;
char buf[64];
- if (strlen(cmd) < 8) {
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
-
if (cmd[7] == '=') {
/* Indicator update test command "AT+CIND=?" */
err = hfp_send(handle, AT_CMD(INDICATOR_UPDATE_RSP));
@@ -666,187 +527,16 @@ static int report_indicators(struct hfp_slc_handle *handle, const char *cmd)
}
/* AT+BIA command to change the subset of indicators that shall be
- * sent by the AG.
+ * sent by the AG. It is okay to ignore this command here since we
+ * don't do event reporting(CMER).
*/
static int indicator_activation(struct hfp_slc_handle *handle, const char *cmd)
{
- char *ptr;
- int idx = BATTERY_IND_INDEX;
-
- /* AT+BIA=[[<indrep 1>][,[<indrep 2>][,...[,[<indrep n>]]]]]
- * According to the spec:
- * - The indicator state can be omitted and the current reporting
- * states of the indicator shall not change.
- * Ex: AT+BIA=,1,,0
- * Only the 2nd and 4th indicators may be affected.
- * - HF can provide fewer indicators than AG and states not provided
- * shall not change.
- * Ex: CRAS supports 7 indicators and gets AT+BIA=1,0,1
- * Only the first three indicators may be affected.
- * - Call, Call Setup and Held Call are mandatory and should be always
- * on no matter what state HF set.
- */
- ptr = strchr(cmd, '=');
- while (ptr && idx < INDICATOR_IND_MAX) {
- if (idx != CALL_IND_INDEX && idx != CALLSETUP_IND_INDEX &&
- idx != CALLHELD_IND_INDEX) {
- if (*(ptr + 1) == '1')
- handle->ind_event_reports[idx] = 1;
- else if (*(ptr + 1) == '0')
- handle->ind_event_reports[idx] = 0;
- }
- ptr = strchr(ptr + 1, ',');
- idx++;
- }
+ /* AT+BIA=[[<indrep 1>][,[<indrep 2>][,...[,[<indrep n>]]]]] */
+ syslog(LOG_ERR, "Bluetooth indicator activation command %s", cmd);
return hfp_send(handle, AT_CMD("OK"));
}
-/* AT+BIND command to report, query and activate Generic Status Indicators.
- * It is sent by the HF if both AG and HF support the HF indicator feature.
- */
-static int indicator_support(struct hfp_slc_handle *handle, const char *cmd)
-{
- char *tokens, *key;
- int err, cmd_len;
-
- cmd_len = strlen(cmd);
- if (cmd_len < 8)
- goto error_out;
-
- if (cmd[7] == '=') {
- /* AT+BIND=? (Read AG supported indicators) */
- if (cmd_len > 8 && cmd[8] == '?') {
- /* +BIND: (<a>,<b>,<c>,...,<n>) (Response to AT+BIND=?)
- * <a> ... <n>: 0-65535, entered as decimal unsigned
- * integer values without leading zeros, referencing an
- * HF indicator assigned number.
- * 1 is for Enhanced Driver Status.
- * 2 is for Battery Level.
- * For the list of HF indicator assigned number, you can
- * check the Bluetooth SIG Assigned Numbers web page.
- */
- BTLOG(btlog, BT_HFP_HF_INDICATOR, 1, 0);
- /* "2" is for HF Battery Level that we support. We don't
- * support "1" but this is a workaround for Pixel Buds 2
- * which expects this exact combination for battery
- * reporting (HFP 1.7 standard) to work. This workaround
- * is fine since we don't enable Safety Drive with
- * +BIND: 1,1 (b/172680041).
- */
- err = hfp_send(handle, AT_CMD("+BIND: (1,2)"));
- if (err < 0)
- return err;
- }
- /* AT+BIND=<a>,<b>,...,<n>(List HF supported indicators) */
- else {
- tokens = strdup(cmd);
- strtok(tokens, "=");
- key = strtok(NULL, ",");
- while (key != NULL) {
- if (atoi(key) == 2)
- handle->hf_supports_battery_indicator |=
- CRAS_HFP_BATTERY_INDICATOR_HFP;
- key = strtok(NULL, ",");
- }
- free(tokens);
- }
- }
- /* AT+BIND? (Read AG enabled/disabled status of indicators) */
- else if (cmd[7] == '?') {
- /* +BIND: <a>,<state> (Unsolicited or Response to AT+BIND?)
- * This response enables the AG to notify the HF which HF
- * indicators are supported and their state, enabled or
- * disabled.
- * <a>: 1 or 2, referencing an HF indicator assigned number.
- * <state>: 0-1, entered as integer values, where
- * 0 = disabled, no value changes shall be sent for this
- * indicator
- * 1 = enabled, value changes may be sent for this indicator
- */
-
- /* We don't support Enhanced Driver Status, so explicitly
- * disable it (b/172680041).
- */
- err = hfp_send(handle, AT_CMD("+BIND: 1,0"));
- if (err < 0)
- return err;
-
- BTLOG(btlog, BT_HFP_HF_INDICATOR, 0, 0);
-
- err = hfp_send(handle, AT_CMD("+BIND: 2,1"));
- if (err < 0)
- return err;
-
- err = hfp_send(handle, AT_CMD("OK"));
- if (err)
- return err;
- /*
- * Consider the Service Level Connection to be fully initialized
- * and thereby established, after successfully responded with OK
- */
- initialize_slc_handle(NULL, (void *)handle);
- return 0;
- } else {
- goto error_out;
- }
- /* This OK reply is required after both +BIND AT commands. It also
- * covers the AT+BIND= <a>,<b>,...,<n> case.
- */
- return hfp_send(handle, AT_CMD("OK"));
-
-error_out:
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
-}
-
-/* AT+BIEV command reports updated values of enabled HF indicators to the AG.
- */
-static int indicator_state_change(struct hfp_slc_handle *handle,
- const char *cmd)
-{
- char *tokens, *key, *val;
- int level;
- /* AT+BIEV= <assigned number>,<value> (Update value of indicator)
- * CRAS only supports battery level, which is with assigned number 2.
- * Battery level should range from 0 to 100 defined by the spec.
- */
- tokens = strdup(cmd);
- strtok(tokens, "=");
- key = strtok(NULL, ",");
- if (!key)
- goto error_out;
-
- if (atoi(key) == 2) {
- val = strtok(NULL, ",");
- if (!val)
- goto error_out;
- level = atoi(val);
- if (level >= 0 && level <= 100) {
- cras_server_metrics_hfp_battery_report(
- CRAS_HFP_BATTERY_INDICATOR_HFP);
- if (handle->hf_battery != level) {
- handle->hf_battery = level;
- cras_observer_notify_bt_battery_changed(
- cras_bt_device_address(handle->device),
- (uint32_t)(level));
- }
- } else {
- syslog(LOG_ERR,
- "Get invalid battery status from cmd:%s", cmd);
- }
- } else {
- goto error_out;
- }
-
- free(tokens);
- return hfp_send(handle, AT_CMD("OK"));
-
-error_out:
- syslog(LOG_WARNING, "%s: invalid command: '%s'", __func__, cmd);
- free(tokens);
- return hfp_send(handle, AT_CMD("ERROR"));
-}
-
/* AT+VGM and AT+VGS command reports the current mic and speaker gain
* level respectively. Optional support per spec 4.28.
*/
@@ -855,21 +545,14 @@ static int signal_gain_setting(struct hfp_slc_handle *handle, const char *cmd)
int gain;
if (strlen(cmd) < 8) {
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
+ syslog(LOG_ERR, "Invalid gain setting command %s", cmd);
+ return -EINVAL;
}
/* Map 0 to the smallest non-zero scale 6/100, and 15 to
* 100/100 full. */
if (cmd[5] == 'S') {
gain = atoi(&cmd[7]);
- if (gain < 0 || gain > 15) {
- syslog(LOG_ERR,
- "signal_gain_setting: gain %d is not between 0 and 15",
- gain);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
- BTLOG(btlog, BT_HFP_UPDATE_SPEAKER_GAIN, gain, 0);
cras_bt_device_update_hardware_volume(handle->device,
(gain + 1) * 100 / 16);
}
@@ -891,24 +574,23 @@ static int subscriber_number(struct hfp_slc_handle *handle, const char *buf)
*/
static int supported_features(struct hfp_slc_handle *handle, const char *cmd)
{
- int err;
+ int err, hf_features;
char response[128];
char *tokens, *features;
- if (strlen(cmd) < 9) {
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
- }
+ if (strlen(cmd) < 9)
+ return -EINVAL;
+
+ handle->hf_supports_codec_negotiation = 0;
tokens = strdup(cmd);
strtok(tokens, "=");
features = strtok(NULL, ",");
- if (!features)
- goto error_out;
- handle->hf_supported_features = atoi(features);
- BTLOG(btlog, BT_HFP_SUPPORTED_FEATURES, 0,
- handle->hf_supported_features);
+ hf_features = atoi(features);
+ BTLOG(btlog, BT_HFP_SUPPORTED_FEATURES, 0, hf_features);
+ if (hf_features & HF_CODEC_NEGOTIATION)
+ handle->hf_supports_codec_negotiation = 1;
free(tokens);
/* AT+BRSF=<feature> command received, ignore the HF supported feature
@@ -924,11 +606,6 @@ static int supported_features(struct hfp_slc_handle *handle, const char *cmd)
return err;
return hfp_send(handle, AT_CMD("OK"));
-
-error_out:
- free(tokens);
- syslog(LOG_ERR, "%s: malformed command: '%s'", __func__, cmd);
- return hfp_send(handle, AT_CMD("ERROR"));
}
int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
@@ -937,7 +614,6 @@ int hfp_event_speaker_gain(struct hfp_slc_handle *handle, int gain)
/* Normailize gain value to 0-15 */
gain = gain * 15 / 100;
- BTLOG(btlog, BT_HFP_SET_SPEAKER_GAIN, gain, 0);
snprintf(command, 128, AT_CMD("+VGS=%d"), gain);
return hfp_send(handle, command);
@@ -956,75 +632,11 @@ static int terminate_call(struct hfp_slc_handle *handle, const char *cmd)
return cras_telephony_event_terminate_call();
}
-/* AT+XEVENT is defined by Android to support vendor specific features.
- * Currently, the only known supported case for CrOS is the battery event sent
- * by some Plantronics headsets.
- */
-static int vendor_specific_features(struct hfp_slc_handle *handle,
- const char *cmd)
-{
- char *tokens, *event, *level_str, *num_of_level_str;
- int level, num_of_level;
-
- tokens = strdup(cmd);
- strtok(tokens, "=");
- event = strtok(NULL, ",");
- if (!event)
- goto error_out;
-
- /* AT+XEVENT=BATTERY,Level,NumberOfLevel,MinutesOfTalkTime,IsCharging
- * Level: The charge level with a zero-based integer.
- * NumberOfLevel: How many charging levels there are.
- * MinuteOfTalkTime: The estimated number of talk minutes remaining.
- * IsCharging: A 0 or 1 value.
- *
- * We only support the battery level and thus only care about the first
- * 3 arguments.
- */
- if (!strncmp(event, "BATTERY", 7)) {
- level_str = strtok(NULL, ",");
- num_of_level_str = strtok(NULL, ",");
- if (!level_str || !num_of_level_str)
- goto error_out;
-
- level = atoi(level_str);
- num_of_level = atoi(num_of_level_str);
- if (level < 0 || num_of_level <= 1 || level >= num_of_level)
- goto error_out;
-
- level = (int64_t)level * 100 / (num_of_level - 1);
- if (handle->hf_battery != level) {
- handle->hf_supports_battery_indicator |=
- CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS;
- cras_server_metrics_hfp_battery_report(
- CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS);
- handle->hf_battery = level;
- cras_observer_notify_bt_battery_changed(
- cras_bt_device_address(handle->device),
- (uint32_t)(level));
- }
- }
-
- free(tokens);
- /* For Plantronic headsets, it is required to reply "OK" for the first
- * AT+XEVENT=USER-AGENT... command to tell the headset our support of
- * the xevent protocol. Otherwise, all following events including
- * BATTERY won't be sent.
- */
- return hfp_send(handle, AT_CMD("OK"));
-
-error_out:
- syslog(LOG_ERR, "%s: malformed vendor specific command: '%s'", __func__,
- cmd);
- free(tokens);
- return hfp_send(handle, AT_CMD("ERROR"));
-}
-
/* AT commands to support in order to conform HFP specification.
*
* An initialized service level connection is the pre-condition for all
* call related procedures. Note that for the call related commands,
- * we are good to just respond with a meaningless "OK".
+ * we are good to just respond with a dummy "OK".
*
* The procedure to establish a service level connection is described below:
*
@@ -1056,35 +668,27 @@ error_out:
* AT+CMER= -->
* <-- OK
*/
-static struct at_command at_commands[] = {
- { "ATA", answer_call },
- { "ATD", dial_number },
- { "AT+BAC", available_codecs },
- { "AT+BCC", bluetooth_codec_connection },
- { "AT+BCS", bluetooth_codec_selection },
- { "AT+BIA", indicator_activation },
- { "AT+BIEV", indicator_state_change },
- { "AT+BIND", indicator_support },
- { "AT+BLDN", last_dialed_number },
- { "AT+BRSF", supported_features },
- { "AT+CCWA", call_waiting_notify },
- { "AT+CHUP", terminate_call },
- { "AT+CIND", report_indicators },
- { "AT+CKPD", key_press },
- { "AT+CLCC", list_current_calls },
- { "AT+CLIP", cli_notification },
- { "AT+CMEE", extended_errors },
- { "AT+CMER", event_reporting },
- { "AT+CNUM", subscriber_number },
- { "AT+COPS", operator_selection },
- { "AT+IPHONEACCEV", apple_accessory_state_change },
- { "AT+VG", signal_gain_setting },
- { "AT+VTS", dtmf_tone },
- { "AT+XAPL", apple_supported_features },
- { "AT+XEVENT", vendor_specific_features },
- { "AT+CHLD", call_hold },
- { 0 }
-};
+static struct at_command at_commands[] = { { "ATA", answer_call },
+ { "ATD", dial_number },
+ { "AT+BAC", available_codecs },
+ { "AT+BCS",
+ bluetooth_codec_selection },
+ { "AT+BIA", indicator_activation },
+ { "AT+BLDN", last_dialed_number },
+ { "AT+BRSF", supported_features },
+ { "AT+CCWA", call_waiting_notify },
+ { "AT+CHUP", terminate_call },
+ { "AT+CIND", report_indicators },
+ { "AT+CKPD", key_press },
+ { "AT+CLCC", list_current_calls },
+ { "AT+CLIP", cli_notification },
+ { "AT+CMEE", extended_errors },
+ { "AT+CMER", event_reporting },
+ { "AT+CNUM", subscriber_number },
+ { "AT+COPS", operator_selection },
+ { "AT+VG", signal_gain_setting },
+ { "AT+VTS", dtmf_tone },
+ { 0 } };
static int handle_at_command(struct hfp_slc_handle *slc_handle, const char *cmd)
{
@@ -1098,23 +702,21 @@ static int handle_at_command(struct hfp_slc_handle *slc_handle, const char *cmd)
return hfp_send(slc_handle, AT_CMD("ERROR"));
}
-int handle_at_command_for_test(struct hfp_slc_handle *slc_handle,
- const char *cmd)
-{
- return handle_at_command(slc_handle, cmd);
-}
-
-static int process_at_commands(struct hfp_slc_handle *handle)
+static void slc_watch_callback(void *arg)
{
+ struct hfp_slc_handle *handle = (struct hfp_slc_handle *)arg;
ssize_t bytes_read;
int err;
bytes_read =
read(handle->rfcomm_fd, &handle->buf[handle->buf_write_idx],
SLC_BUF_SIZE_BYTES - handle->buf_write_idx - 1);
- if (bytes_read < 0)
- return bytes_read;
-
+ if (bytes_read < 0) {
+ syslog(LOG_ERR, "Error reading slc command %s",
+ strerror(errno));
+ handle->disconnect_cb(handle);
+ return;
+ }
handle->buf_write_idx += bytes_read;
handle->buf[handle->buf_write_idx] = '\0';
@@ -1128,7 +730,7 @@ static int process_at_commands(struct hfp_slc_handle *handle)
err = handle_at_command(handle,
&handle->buf[handle->buf_read_idx]);
if (err < 0)
- return 0;
+ return;
/* Shift the read index */
handle->buf_read_idx = 1 + end_char - handle->buf;
@@ -1151,21 +753,9 @@ static int process_at_commands(struct hfp_slc_handle *handle)
handle->buf_write_idx = 0;
}
}
- return bytes_read;
-}
-static void slc_watch_callback(void *arg, int revents)
-{
- struct hfp_slc_handle *handle = (struct hfp_slc_handle *)arg;
- int err;
+ post_at_command_tasks(handle);
- err = process_at_commands(handle);
- if (err < 0) {
- syslog(LOG_ERR, "Error reading slc command %s",
- strerror(errno));
- cras_system_rm_select_fd(handle->rfcomm_fd);
- handle->disconnect_cb(handle);
- }
return;
}
@@ -1178,10 +768,6 @@ struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
hfp_slc_disconnect_cb disconnect_cb)
{
struct hfp_slc_handle *handle;
- int i;
-
- if (!disconnect_cb)
- return NULL;
handle = (struct hfp_slc_handle *)calloc(1, sizeof(*handle));
if (!handle)
@@ -1190,7 +776,6 @@ struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
handle->rfcomm_fd = fd;
handle->is_hsp = is_hsp;
handle->ag_supported_features = ag_supported_features;
- handle->hf_supported_features = 0;
handle->device = device;
handle->init_cb = init_cb;
handle->disconnect_cb = disconnect_cb;
@@ -1198,16 +783,13 @@ struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
handle->battery = 5;
handle->signal = 5;
handle->service = 1;
- handle->ind_event_reports[CRAS_INDICATOR_ENABLE_INDEX] = 0;
- for (i = BATTERY_IND_INDEX; i < INDICATOR_IND_MAX; i++)
- handle->ind_event_reports[i] = 1;
+ handle->ind_event_report = 0;
handle->telephony = cras_telephony_get();
handle->preferred_codec = HFP_CODEC_ID_CVSD;
handle->selected_codec = HFP_CODEC_UNUSED;
- handle->hf_supports_battery_indicator = CRAS_HFP_BATTERY_INDICATOR_NONE;
- handle->hf_battery = -1;
- cras_system_add_select_fd(handle->rfcomm_fd, slc_watch_callback, handle,
- POLLIN | POLLERR | POLLHUP);
+
+ cras_system_add_select_fd(handle->rfcomm_fd, slc_watch_callback,
+ handle);
return handle;
}
@@ -1222,11 +804,6 @@ void hfp_slc_destroy(struct hfp_slc_handle *slc_handle)
free(slc_handle);
}
-int hfp_slc_is_hsp(struct hfp_slc_handle *handle)
-{
- return handle->is_hsp;
-}
-
int hfp_slc_get_selected_codec(struct hfp_slc_handle *handle)
{
/* If codec negotiation is not supported on HF, or the negotiation
@@ -1237,65 +814,6 @@ int hfp_slc_get_selected_codec(struct hfp_slc_handle *handle)
return handle->selected_codec;
}
-int hfp_slc_codec_connection_setup(struct hfp_slc_handle *handle)
-{
- /* The time we wait for codec selection response. */
- static struct timespec timeout = { 0, 100000000 };
- struct pollfd poll_fd;
- int rc = 0;
- struct timespec ts = timeout;
-
- /*
- * Codec negotiation is not required, if either AG or HF doesn't support
- * it or it has been done once.
- */
- if (!hfp_slc_get_hf_codec_negotiation_supported(handle) ||
- !hfp_slc_get_ag_codec_negotiation_supported(handle) ||
- handle->selected_codec == handle->preferred_codec)
- return 0;
-
-redo_codec_conn:
- select_preferred_codec(handle);
-
- poll_fd.fd = handle->rfcomm_fd;
- poll_fd.events = POLLIN;
-
- ts = timeout;
- while (rc <= 0) {
- rc = cras_poll(&poll_fd, 1, &ts, NULL);
- if (rc == -ETIMEDOUT) {
- /*
- * Catch the case that the first initial codec
- * negotiation timeout. At this point we're not sure
- * if HF is good with the preferred codec from AG.
- * Fallback to CVSD doesn't help because very likely
- * HF won't reply that either. The best thing we can
- * do is just leave a warning log.
- */
- if (handle->selected_codec == HFP_CODEC_UNUSED) {
- syslog(LOG_WARNING,
- "Proceed using codec %d without HF reply",
- handle->preferred_codec);
- }
- return rc;
- }
- }
-
- if (rc > 0) {
- do {
- usleep(CODEC_CONN_SLEEP_TIME_US);
- rc = process_at_commands(handle);
- } while (rc == -EAGAIN);
-
- if (rc <= 0)
- return rc;
- if (handle->selected_codec != handle->preferred_codec)
- goto redo_codec_conn;
- }
-
- return 0;
-}
-
int hfp_set_call_status(struct hfp_slc_handle *handle, int call)
{
int old_call = handle->telephony->call;
@@ -1372,29 +890,7 @@ int hfp_event_set_service(struct hfp_slc_handle *handle, int avail)
return hfp_send_ind_event_report(handle, SERVICE_IND_INDEX, avail);
}
-int hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle *handle)
-{
- return handle->ag_supported_features & AG_CODEC_NEGOTIATION;
-}
-
int hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle *handle)
{
- return handle->hf_supported_features & HF_CODEC_NEGOTIATION;
-}
-
-int hfp_slc_get_hf_hf_indicators_supported(struct hfp_slc_handle *handle)
-{
- return handle->hf_supported_features & HF_HF_INDICATORS;
-}
-
-bool hfp_slc_get_wideband_speech_supported(struct hfp_slc_handle *handle)
-{
- return hfp_slc_get_ag_codec_negotiation_supported(handle) &&
- hfp_slc_get_hf_codec_negotiation_supported(handle) &&
- handle->hf_codec_supported[HFP_CODEC_ID_MSBC];
-}
-
-int hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle *handle)
-{
- return handle->hf_supports_battery_indicator;
+ return handle->hf_supports_codec_negotiation;
}
diff --git a/cras/src/server/cras_hfp_slc.h b/cras/src/server/cras_hfp_slc.h
index 99335eab..fd3ee551 100644
--- a/cras/src/server/cras_hfp_slc.h
+++ b/cras/src/server/cras_hfp_slc.h
@@ -18,7 +18,7 @@ struct cras_bt_device;
#define HF_THREE_WAY_CALLING 0x0002
#define HF_CLI_PRESENTATION_CAP 0x0004
#define HF_VOICE_RECOGNITION 0x0008
-#define HF_REMOTE_VOLUME_CONTROL 0x0010
+#define HF_REMOVE_VOLUME_CTONTROL 0x0010
#define HF_ENHANCED_CALL_STATUS 0x0020
#define HF_ENHANCED_CALL_CONTROL 0x0040
#define HF_CODEC_NEGOTIATION 0x0080
@@ -38,32 +38,12 @@ struct cras_bt_device;
#define AG_HF_INDICATORS 0x0400
#define AG_ESCO_S4_T2_SETTINGS 0x0800
-/*
- * Apple specific bluetooth commands that extend accessory capabilities.
- * Per Accessory Design Guidelines for Apple devices, command AT+XAPL
- */
-
-#define APL_RESERVED 0x01
-#define APL_BATTERY 0x02
-#define APL_DOCKED_OR_POWERED 0x04
-#define APL_SIRI 0x08
-#define APL_NOISE_REDUCTION 0x10
-
-#define CRAS_APL_SUPPORTED_FEATURES (APL_BATTERY)
-
/* Codec ids for codec negotiation, per HFP 1.7.1 spec appendix B. */
#define HFP_CODEC_UNUSED 0
#define HFP_CODEC_ID_CVSD 1
#define HFP_CODEC_ID_MSBC 2
#define HFP_MAX_CODECS 3
-/* Hands-free HFP supported battery indicator bit definition.
- * This is currently only used for logging purpose. */
-#define CRAS_HFP_BATTERY_INDICATOR_NONE 0x0
-#define CRAS_HFP_BATTERY_INDICATOR_HFP 0x1
-#define CRAS_HFP_BATTERY_INDICATOR_APPLE 0x2
-#define CRAS_HFP_BATTERY_INDICATOR_PLANTRONICS 0x4
-
/* Callback to call when service level connection initialized. */
typedef int (*hfp_slc_init_cb)(struct hfp_slc_handle *handle);
@@ -91,11 +71,6 @@ struct hfp_slc_handle *hfp_slc_create(int fd, int is_hsp,
/* Destroys an hfp_slc_handle. */
void hfp_slc_destroy(struct hfp_slc_handle *handle);
-/* Returns true if this SLC is created for headset profile(HSP), false
- * means it's created for hands-free profile(HFP).
- */
-int hfp_slc_is_hsp(struct hfp_slc_handle *handle);
-
/* Sets the call status to notify handsfree device. */
int hfp_set_call_status(struct hfp_slc_handle *handle, int call);
@@ -133,24 +108,4 @@ int hfp_slc_get_selected_codec(struct hfp_slc_handle *handle);
/* Gets if the remote HF supports codec negotiation. */
int hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle *handle);
-/* Gets if the remote HF supports HF indicator. */
-int hfp_slc_get_hf_hf_indicators_supported(struct hfp_slc_handle *handle);
-
-/* Gets if the HF side supports wideband speech. */
-bool hfp_slc_get_wideband_speech_supported(struct hfp_slc_handle *handle);
-
-/* Gets if the AG side supports codec negotiation. */
-int hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle *handle);
-
-/* Gets an enum representing which spec the HF supports battery indicator.
- * Apple, HFP, none, or both. */
-int hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle *handle);
-
-/* Init the codec negotiation process if needed. */
-int hfp_slc_codec_connection_setup(struct hfp_slc_handle *handle);
-
-// Expose internal AT command handling for fuzzing.
-int handle_at_command_for_test(struct hfp_slc_handle *slc_handle,
- const char *cmd);
-
#endif /* CRAS_HFP_SLC_H_ */
diff --git a/cras/src/server/cras_iodev.c b/cras/src/server/cras_iodev.c
index 651cef71..cf6b71ef 100644
--- a/cras/src/server/cras_iodev.c
+++ b/cras/src/server/cras_iodev.c
@@ -21,7 +21,6 @@
#include "cras_dsp_pipeline.h"
#include "cras_fmt_conv.h"
#include "cras_iodev.h"
-#include "cras_main_thread_log.h"
#include "cras_iodev_list.h"
#include "cras_mix.h"
#include "cras_ramp.h"
@@ -38,8 +37,6 @@
static const float RAMP_UNMUTE_DURATION_SECS = 0.5;
static const float RAMP_NEW_STREAM_DURATION_SECS = 0.01;
static const float RAMP_MUTE_DURATION_SECS = 0.1;
-static const float RAMP_RESUME_MUTE_DURATION_SECS = 1;
-static const float RAMP_SWITCH_MUTE_DURATION_SECS = 0.5;
static const float RAMP_VOLUME_CHANGE_DURATION_SECS = 0.1;
/*
@@ -84,7 +81,7 @@ static int default_no_stream_playback(struct cras_iodev *odev)
/* If underrun happened, handle underrun and get hw_level again. */
if (hw_level == 0) {
- rc = cras_iodev_output_underrun(odev, hw_level, 0);
+ rc = cras_iodev_output_underrun(odev);
if (rc < 0)
return rc;
@@ -239,7 +236,7 @@ int cras_iodev_is_zero_volume(const struct cras_iodev *odev)
* | ---------------- | device from
* | | S1 Open | | audio_thread and
* | ---------------- | closes device
- * | Device with empty start | |
+ * | Device with dummy start | |
* | ops transits into | Sample is ready |
* | no stream state right V |
* | after open. ---------------- |
@@ -264,9 +261,10 @@ static int cras_iodev_output_event_sample_ready(struct cras_iodev *odev)
/* Starts ramping up if device should not be muted.
* Both mute and volume are taken into consideration.
*/
- if (odev->ramp && !output_should_mute(odev)) {
- cras_iodev_start_ramp(odev, odev->initial_ramp_request);
- }
+ if (odev->ramp && !output_should_mute(odev))
+ cras_iodev_start_ramp(
+ odev,
+ CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK);
}
if (odev->state == CRAS_IODEV_STATE_OPEN) {
@@ -449,17 +447,6 @@ int cras_iodev_set_format(struct cras_iodev *iodev,
snd_pcm_format_t actual_format;
int rc;
- /* Update supported formats on iodev before negotiating the final value
- * with what stream requested.
- */
- if (iodev->update_supported_formats) {
- rc = iodev->update_supported_formats(iodev);
- if (rc) {
- syslog(LOG_ERR, "Failed to update formats");
- return rc;
- }
- }
-
/* If this device isn't already using a format, try to match the one
* requested in "fmt". */
if (iodev->format == NULL) {
@@ -468,6 +455,14 @@ int cras_iodev_set_format(struct cras_iodev *iodev,
return -ENOMEM;
*iodev->format = *fmt;
+ if (iodev->update_supported_formats) {
+ rc = iodev->update_supported_formats(iodev);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to update formats");
+ goto error;
+ }
+ }
+
/* Finds the actual rate of device before allocating DSP
* because DSP needs to use the rate of device, not rate of
* stream. */
@@ -527,8 +522,8 @@ static void add_ext_dsp_module_to_pipeline(struct cras_iodev *iodev)
if (!pipeline) {
cras_iodev_alloc_dsp(iodev);
- cras_dsp_load_mock_pipeline(iodev->dsp_context,
- iodev->format->num_channels);
+ cras_dsp_load_dummy_pipeline(iodev->dsp_context,
+ iodev->format->num_channels);
pipeline = cras_dsp_get_pipeline(iodev->dsp_context);
}
/* dsp_context mutex locked. Now it's safe to modify dsp
@@ -686,16 +681,10 @@ void cras_iodev_set_node_plugged(struct cras_ionode *node, int plugged)
if (node->plugged == plugged)
return;
node->plugged = plugged;
- MAINLOG(main_log, MAIN_THREAD_NODE_PLUGGED, node->dev->info.idx,
- plugged, 0);
if (plugged) {
gettimeofday(&node->plugged_time, NULL);
} else if (node == node->dev->active_node) {
- /*
- * Remove normal and pinned streams, when node unplugged.
- * TODO(hychao): clean this up, per crbug.com/1006646
- */
- cras_iodev_list_disable_dev(node->dev, true);
+ cras_iodev_list_disable_dev(node->dev, false);
}
cras_iodev_list_notify_nodes_changed();
}
@@ -719,30 +708,6 @@ void cras_iodev_set_active_node(struct cras_iodev *iodev,
cras_iodev_list_notify_active_node_changed(iodev->direction);
}
-bool cras_iodev_is_aec_use_case(const struct cras_ionode *node)
-{
- if ((node->type == CRAS_NODE_TYPE_INTERNAL_SPEAKER) ||
- (node->type == CRAS_NODE_TYPE_ECHO_REFERENCE))
- return true;
-
- if (node->type == CRAS_NODE_TYPE_MIC)
- return (node->position == NODE_POSITION_INTERNAL) ||
- (node->position == NODE_POSITION_FRONT);
-
- return false;
-}
-
-bool cras_iodev_is_on_internal_card(const struct cras_ionode *node)
-{
- if (node->type == CRAS_NODE_TYPE_INTERNAL_SPEAKER)
- return true;
- if (node->type == CRAS_NODE_TYPE_HEADPHONE)
- return true;
- if (node->type == CRAS_NODE_TYPE_MIC)
- return true;
- return false;
-}
-
float cras_iodev_get_software_volume_scaler(struct cras_iodev *iodev)
{
unsigned int volume;
@@ -757,10 +722,13 @@ float cras_iodev_get_software_volume_scaler(struct cras_iodev *iodev)
float cras_iodev_get_software_gain_scaler(const struct cras_iodev *iodev)
{
- if (cras_iodev_software_volume_needed(iodev))
- return convert_softvol_scaler_from_dB(
- iodev->active_node->capture_gain);
- return 1.0f;
+ float scaler = 1.0f;
+ if (cras_iodev_software_volume_needed(iodev)) {
+ long gain = cras_iodev_adjust_active_node_gain(
+ iodev, cras_system_get_capture_gain());
+ scaler = convert_softvol_scaler_from_dB(gain);
+ }
+ return scaler;
}
int cras_iodev_get_valid_frames(struct cras_iodev *odev,
@@ -957,24 +925,19 @@ int cras_iodev_open(struct cras_iodev *iodev, unsigned int cb_level,
iodev->min_cb_level = MIN(iodev->buffer_size / 2, cb_level);
iodev->max_cb_level = 0;
iodev->largest_cb_level = 0;
- iodev->num_underruns = 0;
iodev->reset_request_pending = 0;
iodev->state = CRAS_IODEV_STATE_OPEN;
iodev->highest_hw_level = 0;
iodev->input_dsp_offset = 0;
- ewma_power_init(&iodev->ewma, iodev->format->frame_rate);
-
if (iodev->direction == CRAS_STREAM_OUTPUT) {
/* If device supports start ops, device can be in open state.
* Otherwise, device starts running right after opening. */
- if (iodev->start) {
+ if (iodev->start)
iodev->state = CRAS_IODEV_STATE_OPEN;
- } else {
+ else
iodev->state = CRAS_IODEV_STATE_NO_STREAM_RUN;
- cras_iodev_fill_odev_zeros(iodev, iodev->min_cb_level);
- }
} else {
iodev->input_data = input_data_create(iodev);
/* If this is the echo reference dev, its ext_dsp_module will
@@ -993,8 +956,8 @@ int cras_iodev_open(struct cras_iodev *iodev, unsigned int cb_level,
/*
* The device specific gain scaler to be used in audio thread.
* It's expected to stick to 1.0f if device has hardware gain
- * control. For alsa device, this gain value will be configured
- * based on UCM labels IntrinsicSensitivity.
+ * control. For alsa device, this gain value can be configured
+ * through UCM labels DefaultNodeGain.
*/
iodev->software_gain_scaler =
cras_iodev_get_software_gain_scaler(iodev);
@@ -1019,11 +982,7 @@ int cras_iodev_close(struct cras_iodev *iodev)
if (!cras_iodev_is_open(iodev))
return 0;
- if (iodev->active_node) {
- cras_server_metrics_device_runtime(iodev);
- cras_server_metrics_device_gain(iodev);
- cras_server_metrics_device_volume(iodev);
- }
+ cras_server_metrics_device_runtime(iodev);
if (iodev->input_data) {
if (iodev->ext_dsp_module == &iodev->input_data->ext)
@@ -1033,8 +992,7 @@ int cras_iodev_close(struct cras_iodev *iodev)
rc = iodev->close_dev(iodev);
if (rc)
- syslog(LOG_ERR, "Error closing dev %s, rc %d", iodev->info.name,
- rc);
+ return rc;
iodev->state = CRAS_IODEV_STATE_CLOSE;
if (iodev->ramp)
cras_ramp_reset(iodev->ramp);
@@ -1092,17 +1050,13 @@ int cras_iodev_put_output_buffer(struct cras_iodev *iodev, uint8_t *frames,
/* Calculate whether the final output was non-empty, if requested. */
if (is_non_empty) {
- const size_t bytes = nframes * cras_get_format_bytes(fmt);
-
- /*
- * Speed up checking frames are all zeros using memcmp.
- * frames contains all zeros if both conditions are met:
- * - frames[0] is 0.
- * - frames[i] == frames[i+1] for i in [0, 1, ..., bytes - 2].
- */
- *is_non_empty = bytes ? (*frames || memcmp(frames, frames + 1,
- bytes - 1)) :
- 0;
+ unsigned int i;
+ for (i = 0; i < nframes * cras_get_format_bytes(fmt); i++) {
+ if (frames[i]) {
+ *is_non_empty = 1;
+ break;
+ }
+ }
}
DL_FOREACH (iodev->loopbacks, loopback) {
@@ -1111,9 +1065,6 @@ int cras_iodev_put_output_buffer(struct cras_iodev *iodev, uint8_t *frames,
loopback->cb_data);
}
- ewma_power_calculate(&iodev->ewma, (int16_t *)frames,
- iodev->format->num_channels, nframes);
-
rc = apply_dsp(iodev, frames, nframes);
if (rc)
return rc;
@@ -1217,11 +1168,6 @@ int cras_iodev_get_input_buffer(struct cras_iodev *iodev, unsigned int *frames)
*frames - iodev->input_dsp_offset);
if (rc)
return rc;
- ewma_power_calculate_area(
- &iodev->ewma,
- (int16_t *)(hw_buffer +
- iodev->input_dsp_offset * frame_bytes),
- data->area, *frames - iodev->input_dsp_offset);
}
if (cras_system_get_capture_mute())
@@ -1297,6 +1243,9 @@ int cras_iodev_frames_queued(struct cras_iodev *iodev,
int rc;
rc = iodev->frames_queued(iodev, hw_tstamp);
+ if (rc == -EPIPE)
+ cras_audio_thread_event_severe_underrun();
+
if (rc < 0)
return rc;
@@ -1346,7 +1295,7 @@ int cras_iodev_fill_odev_zeros(struct cras_iodev *odev, unsigned int frames)
/* This assumes consecutive channel areas. */
buf = area->channels[0].buf;
- memset(buf, 0, (size_t)frames_written * (size_t)frame_bytes);
+ memset(buf, 0, frames_written * frame_bytes);
cras_iodev_put_output_buffer(odev, buf, frames_written, NULL,
NULL);
frames -= frames_written;
@@ -1355,12 +1304,8 @@ int cras_iodev_fill_odev_zeros(struct cras_iodev *odev, unsigned int frames)
return 0;
}
-int cras_iodev_output_underrun(struct cras_iodev *odev, unsigned int hw_level,
- unsigned int frames_written)
+int cras_iodev_output_underrun(struct cras_iodev *odev)
{
- ATLOG(atlog, AUDIO_THREAD_UNDERRUN, odev->info.idx, hw_level,
- frames_written);
- odev->num_underruns++;
cras_audio_thread_event_underrun();
if (odev->output_underrun)
return odev->output_underrun(odev);
@@ -1381,10 +1326,9 @@ int cras_iodev_odev_should_wake(const struct cras_iodev *odev)
odev->state == CRAS_IODEV_STATE_NO_STREAM_RUN);
}
-unsigned int
-cras_iodev_default_frames_to_play_in_sleep(struct cras_iodev *odev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp)
+unsigned int cras_iodev_frames_to_play_in_sleep(struct cras_iodev *odev,
+ unsigned int *hw_level,
+ struct timespec *hw_tstamp)
{
int rc = cras_iodev_frames_queued(odev, hw_tstamp);
unsigned int level = (rc < 0) ? 0 : rc;
@@ -1427,19 +1371,6 @@ cras_iodev_default_frames_to_play_in_sleep(struct cras_iodev *odev,
return 0;
}
-unsigned int cras_iodev_frames_to_play_in_sleep(struct cras_iodev *odev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp)
-{
- /* Use odev's own implementation, if not supported then fall back
- * to default behavior below. */
- if (odev->frames_to_play_in_sleep)
- return odev->frames_to_play_in_sleep(odev, hw_level, hw_tstamp);
- else
- return cras_iodev_default_frames_to_play_in_sleep(
- odev, hw_level, hw_tstamp);
-}
-
int cras_iodev_default_no_stream_playback(struct cras_iodev *odev, int enable)
{
if (enable)
@@ -1472,7 +1403,9 @@ int cras_iodev_prepare_output_before_write_samples(struct cras_iodev *odev)
unsigned int cras_iodev_get_num_underruns(const struct cras_iodev *iodev)
{
- return iodev->num_underruns;
+ if (iodev->get_num_underruns)
+ return iodev->get_num_underruns(iodev);
+ return 0;
}
unsigned int cras_iodev_get_num_severe_underruns(const struct cras_iodev *iodev)
@@ -1500,7 +1433,7 @@ int cras_iodev_reset_request(struct cras_iodev *iodev)
return cras_device_monitor_reset_device(iodev->info.idx);
}
-static void ramp_down_mute_callback(void *data)
+static void ramp_mute_callback(void *data)
{
struct cras_iodev *odev = (struct cras_iodev *)data;
cras_device_monitor_set_device_mute_state(odev->info.idx);
@@ -1536,23 +1469,9 @@ int cras_iodev_start_ramp(struct cras_iodev *odev,
from = 1.0;
to = 0.0;
duration_secs = RAMP_MUTE_DURATION_SECS;
- cb = ramp_down_mute_callback;
+ cb = ramp_mute_callback;
cb_data = (void *)odev;
break;
- case CRAS_IODEV_RAMP_REQUEST_RESUME_MUTE:
- from = 0;
- to = 0;
- duration_secs = RAMP_RESUME_MUTE_DURATION_SECS;
- odev->initial_ramp_request =
- CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
- break;
- case CRAS_IODEV_RAMP_REQUEST_SWITCH_MUTE:
- from = 0;
- to = 0;
- duration_secs = RAMP_SWITCH_MUTE_DURATION_SECS;
- odev->initial_ramp_request =
- CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
- break;
default:
return -EINVAL;
}
@@ -1622,22 +1541,6 @@ int cras_iodev_set_mute(struct cras_iodev *iodev)
void cras_iodev_update_highest_hw_level(struct cras_iodev *iodev,
unsigned int hw_level)
{
- /*
- * If the hw_level is unreasonably high and reach to the device's
- * buffer size, regard it as a device overrun.
- * In the normal status, the hw_level for should be between 1 to 2
- * largest_cb_level for an output device and 0 to 1 largest_cb_level
- * for an input device. Therefore, larger than 3 can be considered
- * unreasonable.
- */
- if (hw_level == iodev->buffer_size &&
- iodev->largest_cb_level * 3 < iodev->buffer_size) {
- ATLOG(atlog, AUDIO_THREAD_DEV_OVERRUN, iodev->info.idx,
- hw_level, 0);
- /* Only log the event when the first time it happens. */
- if (iodev->highest_hw_level != hw_level)
- cras_audio_thread_event_dev_overrun();
- }
iodev->highest_hw_level = MAX(iodev->highest_hw_level, hw_level);
}
@@ -1652,8 +1555,7 @@ void cras_iodev_update_highest_hw_level(struct cras_iodev *iodev,
static int cras_iodev_drop_frames(struct cras_iodev *iodev, unsigned int frames)
{
struct timespec hw_tstamp;
- int i, rc;
- unsigned int target_frames, dropped_frames = 0;
+ int rc;
if (iodev->direction != CRAS_STREAM_INPUT)
return -EINVAL;
@@ -1662,33 +1564,23 @@ static int cras_iodev_drop_frames(struct cras_iodev *iodev, unsigned int frames)
if (rc < 0)
return rc;
- target_frames = MIN(frames, rc);
+ frames = MIN(frames, rc);
+
+ rc = iodev->get_buffer(iodev, &iodev->input_data->area, &frames);
+ if (rc < 0)
+ return rc;
+
+ rc = iodev->put_buffer(iodev, frames);
+ if (rc < 0)
+ return rc;
/*
- * Loop reading the buffer, at most twice. This is to cover when
- * circular buffer is at the end and returns partial of the target
- * frames.
+ * Tell rate estimator that some frames have been dropped to avoid calculating
+ * the wrong rate.
*/
- for (i = 0; (dropped_frames < target_frames) && (i < 2); i++) {
- frames = target_frames - dropped_frames;
- rc = iodev->get_buffer(iodev, &iodev->input_data->area,
- &frames);
- if (rc < 0)
- return rc;
-
- rc = iodev->put_buffer(iodev, frames);
- if (rc < 0)
- return rc;
- dropped_frames += frames;
- /*
- * Tell rate estimator that some frames have been dropped to
- * avoid calculating the wrong rate.
- */
- rate_estimator_add_frames(iodev->rate_est, -frames);
- }
+ rate_estimator_add_frames(iodev->rate_est, -frames);
- ATLOG(atlog, AUDIO_THREAD_DEV_DROP_FRAMES, iodev->info.idx,
- dropped_frames, 0);
+ ATLOG(atlog, AUDIO_THREAD_DEV_DROP_FRAMES, iodev->info.idx, frames, 0);
return frames;
}
@@ -1707,13 +1599,3 @@ int cras_iodev_drop_frames_by_time(struct cras_iodev *iodev, struct timespec ts)
return rc;
}
-
-bool cras_iodev_support_noise_cancellation(const struct cras_iodev *iodev)
-{
- if (iodev->direction != CRAS_STREAM_INPUT)
- return false;
-
- if (iodev->support_noise_cancellation)
- return !!iodev->support_noise_cancellation(iodev);
- return false;
-}
diff --git a/cras/src/server/cras_iodev.h b/cras/src/server/cras_iodev.h
index 18a0962c..f6999336 100644
--- a/cras/src/server/cras_iodev.h
+++ b/cras/src/server/cras_iodev.h
@@ -19,7 +19,6 @@
#include "cras_dsp.h"
#include "cras_iodev_info.h"
#include "cras_messages.h"
-#include "ewma_power.h"
struct buffer_share;
struct cras_fmt_conv;
@@ -97,13 +96,13 @@ enum CRAS_IODEV_STATE {
* plugged - true if the device is plugged.
* plugged_time - If plugged is true, this is the time it was attached.
* volume - per-node volume (0-100)
- * capture_gain - Internal per-node capture gain/attenuation (in 100*dBFS)
- * This is only used for CRAS internal tuning, no way to change by
- * client.
- * ui_gain_scaler - The adjustable gain scaler set by client.
+ * capture_gain - per-node capture gain/attenuation (in 100*dBFS)
* left_right_swapped - If left and right output channels are swapped.
* type - Type displayed to the user.
* position - Specify where on the system this node locates.
+ * mic_positions - Whitespace-separated microphone positions using Cartesian
+ * coordinates in meters with ordering x, y, z. The string is formatted as:
+ * "x1 y1 z1 ... xn yn zn" for an n-microphone array.
* name - Name displayed to the user.
* dsp_name - The "DspName" variable specified in the ucm config.
* active_hotword_model - name of the currently selected hotword model.
@@ -111,8 +110,8 @@ enum CRAS_IODEV_STATE {
* software_volume_needed - For output: True if the volume range of the node
* is smaller than desired. For input: True if this node needs software
* gain.
- * intrinsic_sensitivity - The "IntrinsicSensitivity" in 0.01 dBFS/Pa
- * specified in the ucm config.
+ * min_software_gain - The minimum software gain in 0.01 dB if needed.
+ * max_software_gain - The maximum software gain in 0.01 dB if needed.
* stable_id - id for node that doesn't change after unplug/plug.
* is_sco_pcm - Bool to indicate whether the ionode is for SCO over PCM.
*/
@@ -123,16 +122,17 @@ struct cras_ionode {
struct timeval plugged_time;
unsigned int volume;
long capture_gain;
- float ui_gain_scaler;
int left_right_swapped;
enum CRAS_NODE_TYPE type;
enum CRAS_NODE_POSITION position;
+ char mic_positions[CRAS_NODE_MIC_POS_BUFFER_SIZE];
char name[CRAS_NODE_NAME_BUFFER_SIZE];
const char *dsp_name;
char active_hotword_model[CRAS_NODE_HOTWORD_MODEL_BUFFER_SIZE];
float *softvol_scalers;
int software_volume_needed;
- long intrinsic_sensitivity;
+ long min_software_gain;
+ long max_software_gain;
unsigned int stable_id;
int is_sco_pcm;
struct cras_ionode *prev, *next;
@@ -140,8 +140,8 @@ struct cras_ionode {
/* An input or output device, that can have audio routed to/from it.
* set_volume - Function to call if the system volume changes.
- * set_capture_gain - Function to call if active node's capture_gain changes.
* set_mute - Function to call if the system mute state changes.
+ * set_capture_gain - Function to call if the system capture_gain changes.
* set_capture_mute - Function to call if the system capture mute state changes.
* set_swap_mode_for_node - Function to call to set swap mode for the node.
* open_dev - Opens the device.
@@ -175,17 +175,12 @@ struct cras_ionode {
* set_hotword_model - Sets the hotword model to this iodev.
* get_hotword_models - Gets a comma separated string of the list of supported
* hotword models of this iodev.
+ * get_num_underruns - Gets number of underrun recorded so far.
* get_num_severe_underruns - Gets number of severe underrun recorded since
* iodev was created.
* get_valid_frames - Gets number of valid frames in device which have not
* played yet. Valid frames does not include zero samples
* we filled under no streams state.
- * frames_to_play_in_sleep - Returns the non-negative number of frames that
- * audio thread can sleep before serving this playback dev the next time.
- * Not implementing this ops means fall back to default behavior in
- * cras_iodev_default_frames_to_play_in_sleep().
- * support_noise_cancellation - (Optional) Checks if the device supports noise
- * cancellation.
* format - The audio format being rendered or captured to hardware.
* rate_est - Rate estimator to estimate the actual device rate.
* area - Information about how the samples are stored.
@@ -217,7 +212,6 @@ struct cras_ionode {
* largest_cb_level - The largest callback level of streams attached to this
* device. The difference with max_cb_level is it takes all
* streams into account even if they have been removed.
- * num_underruns - Number of times we have run out of data (playback only).
* buf_state - If multiple streams are writing to this device, then this
* keeps track of how much each stream has written.
* idle_timeout - The timestamp when to close the dev after being idle.
@@ -238,9 +232,6 @@ struct cras_ionode {
* been processed by the input DSP.
* input_data - Used to pass audio input data to streams with or without
* stream side processing.
- * initial_ramp_request - The value indicates which type of ramp the device
- * should perform when some samples are ready for playback.
- * ewma - The ewma instance to calculate iodev volume.
*/
struct cras_iodev {
void (*set_volume)(struct cras_iodev *iodev);
@@ -270,13 +261,10 @@ struct cras_iodev {
int (*set_hotword_model)(struct cras_iodev *iodev,
const char *model_name);
char *(*get_hotword_models)(struct cras_iodev *iodev);
+ unsigned int (*get_num_underruns)(const struct cras_iodev *iodev);
unsigned int (*get_num_severe_underruns)(const struct cras_iodev *iodev);
- int (*get_valid_frames)(struct cras_iodev *odev,
+ int (*get_valid_frames)(const struct cras_iodev *odev,
struct timespec *tstamp);
- unsigned int (*frames_to_play_in_sleep)(struct cras_iodev *iodev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp);
- int (*support_noise_cancellation)(const struct cras_iodev *iodev);
struct cras_audio_format *format;
struct rate_estimator *rate_est;
struct cras_audio_area *area;
@@ -301,7 +289,6 @@ struct cras_iodev {
unsigned int max_cb_level;
unsigned int highest_hw_level;
unsigned int largest_cb_level;
- unsigned int num_underruns;
struct buffer_share *buf_state;
struct timespec idle_timeout;
struct timespec open_ts;
@@ -314,9 +301,7 @@ struct cras_iodev {
int input_streaming;
unsigned int input_frames_read;
unsigned int input_dsp_offset;
- unsigned int initial_ramp_request;
struct input_data *input_data;
- struct ewma_power ewma;
struct cras_iodev *prev, *next;
};
@@ -344,24 +329,12 @@ struct cras_iodev {
* - CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK: Ramping is requested because
* first sample of new stream is ready, there is no need to change mute/unmute
* state.
- *
- * - CRAS_IODEV_RAMP_REQUEST_RESUME_MUTE: To prevent popped noise, mute the
- * device for RAMP_RESUME_MUTE_DURATION_SECS seconds on sample ready after
- * resume if there were playback stream before suspend.
- *
- * - CRAS_IODEV_RAMP_REQUEST_SWITCH_MUTE: To prevent popped noise, mute the
- * device for RAMP_SWITCH_MUTE_DURATION_SECS seconds on sample ready after
- * device switch if there were playback stream before switch.
- *
*/
enum CRAS_IODEV_RAMP_REQUEST {
- CRAS_IODEV_RAMP_REQUEST_NONE = 0,
- CRAS_IODEV_RAMP_REQUEST_UP_UNMUTE = 1,
- CRAS_IODEV_RAMP_REQUEST_DOWN_MUTE = 2,
- CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK = 3,
- CRAS_IODEV_RAMP_REQUEST_RESUME_MUTE = 4,
- CRAS_IODEV_RAMP_REQUEST_SWITCH_MUTE = 5,
+ CRAS_IODEV_RAMP_REQUEST_UP_UNMUTE = 0,
+ CRAS_IODEV_RAMP_REQUEST_DOWN_MUTE = 1,
+ CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK = 2,
};
/*
@@ -459,12 +432,6 @@ void cras_iodev_rm_node(struct cras_iodev *iodev, struct cras_ionode *node);
void cras_iodev_set_active_node(struct cras_iodev *iodev,
struct cras_ionode *node);
-/* Checks if the node is the typical playback or capture option for AEC usage. */
-bool cras_iodev_is_aec_use_case(const struct cras_ionode *node);
-
-/* Checks if the node is a playback or capture node on internal card. */
-bool cras_iodev_is_on_internal_card(const struct cras_ionode *node);
-
/* Adjust the system volume based on the volume of the given node. */
static inline unsigned int
cras_iodev_adjust_node_volume(const struct cras_ionode *node,
@@ -489,6 +456,17 @@ cras_iodev_adjust_active_node_volume(struct cras_iodev *iodev,
return cras_iodev_adjust_node_volume(iodev->active_node, system_volume);
}
+/* Get the gain adjusted based on system for the active node. */
+static inline long
+cras_iodev_adjust_active_node_gain(const struct cras_iodev *iodev,
+ long system_gain)
+{
+ if (!iodev->active_node)
+ return system_gain;
+
+ return iodev->active_node->capture_gain + system_gain;
+}
+
/* Returns true if the active node of the iodev needs software volume. */
static inline int
cras_iodev_software_volume_needed(const struct cras_iodev *iodev)
@@ -499,18 +477,39 @@ cras_iodev_software_volume_needed(const struct cras_iodev *iodev)
if (!iodev->active_node)
return 0;
- if (iodev->active_node->intrinsic_sensitivity)
- return 1;
-
return iodev->active_node->software_volume_needed;
}
-static inline float
-cras_iodev_get_ui_gain_scaler(const struct cras_iodev *iodev)
+/* Returns minimum software gain for the iodev.
+ * Args:
+ * iodev - The device.
+ * Returs:
+ * 0 if software gain is not needed, or if there is no active node.
+ * Returns min_software_gain on active node if there is one. */
+static inline long
+cras_iodev_minimum_software_gain(const struct cras_iodev *iodev)
{
+ if (!cras_iodev_software_volume_needed(iodev))
+ return 0;
if (!iodev->active_node)
- return 1.0f;
- return iodev->active_node->ui_gain_scaler;
+ return 0;
+ return iodev->active_node->min_software_gain;
+}
+
+/* Returns maximum software gain for the iodev.
+ * Args:
+ * iodev - The device.
+ * Returs:
+ * 0 if software gain is not needed, or if there is no active node.
+ * Returns max_software_gain on active node if there is one. */
+static inline long
+cras_iodev_maximum_software_gain(const struct cras_iodev *iodev)
+{
+ if (!cras_iodev_software_volume_needed(iodev))
+ return 0;
+ if (!iodev->active_node)
+ return 0;
+ return iodev->active_node->max_software_gain;
}
/* Gets the software gain scaler should be applied on the deivce.
@@ -664,17 +663,6 @@ void cras_iodev_set_ext_dsp_module(struct cras_iodev *iodev,
/* Put 'frames' worth of zero samples into odev. */
int cras_iodev_fill_odev_zeros(struct cras_iodev *odev, unsigned int frames);
-/*
- * The default implementation of frames_to_play_in_sleep ops, used when an
- * iodev doesn't have its own logic.
- * The default behavior is to calculate how log it takes for buffer level to
- * run to as low as min_buffer_level.
- */
-unsigned int
-cras_iodev_default_frames_to_play_in_sleep(struct cras_iodev *odev,
- unsigned int *hw_level,
- struct timespec *hw_tstamp);
-
/* Gets the number of frames to play when audio thread sleeps.
* Args:
* iodev[in] - The device.
@@ -770,13 +758,10 @@ int cras_iodev_reset_request(struct cras_iodev *iodev);
/* Handle output underrun.
* Args:
* odev[in] - The output device.
- * hw_level[in] - The current hw_level. Used in the debug log.
- * frames_written[in] - The number of written frames. Used in the debug log.
* Returns:
* 0 on success. Negative error code on failure.
*/
-int cras_iodev_output_underrun(struct cras_iodev *odev, unsigned int hw_level,
- unsigned int frames_written);
+int cras_iodev_output_underrun(struct cras_iodev *odev);
/* Start ramping samples up/down on a device.
* Args:
@@ -839,12 +824,4 @@ void cras_iodev_update_highest_hw_level(struct cras_iodev *iodev,
int cras_iodev_drop_frames_by_time(struct cras_iodev *iodev,
struct timespec ts);
-/* Checks if an input device supports noise cancellation.
- * Args:
- * iodev - The device.
- * Returns:
- * True if device supports noise cancellation. False otherwise.
- */
-bool cras_iodev_support_noise_cancellation(const struct cras_iodev *iodev);
-
#endif /* CRAS_IODEV_H_ */
diff --git a/cras/src/server/cras_iodev_list.c b/cras/src/server/cras_iodev_list.c
index b818c97b..c581acdf 100644
--- a/cras/src/server/cras_iodev_list.c
+++ b/cras/src/server/cras_iodev_list.c
@@ -11,7 +11,6 @@
#include "cras_iodev_info.h"
#include "cras_iodev_list.h"
#include "cras_loopback_iodev.h"
-#include "cras_main_thread_log.h"
#include "cras_observer.h"
#include "cras_rstream.h"
#include "cras_server.h"
@@ -19,7 +18,6 @@
#include "cras_types.h"
#include "cras_system_state.h"
#include "server_stream.h"
-#include "softvol_curve.h"
#include "stream_list.h"
#include "test_iodev.h"
#include "utlist.h"
@@ -54,8 +52,6 @@ struct device_enabled_cb {
struct device_enabled_cb *next, *prev;
};
-struct main_thread_event_log *main_log;
-
/* Lists for devs[CRAS_STREAM_INPUT] and devs[CRAS_STREAM_OUTPUT]. */
static struct iodev_list devs[CRAS_NUM_DIRECTIONS];
/* The observer client iodev_list used to listen on various events. */
@@ -91,9 +87,6 @@ static int stream_list_suspended = 0;
static const unsigned int INIT_DEV_DELAY_MS = 1000;
/* Flag to indicate that hotword streams are suspended. */
static int hotword_suspended = 0;
-/* Flag to indicate that suspended hotword streams should be auto-resumed at
- * system resume. */
-static int hotword_auto_resume = 0;
static void idle_dev_check(struct cras_timer *timer, void *data);
@@ -227,16 +220,10 @@ static const char *node_type_to_str(struct cras_ionode *node)
return "USB";
case CRAS_NODE_TYPE_BLUETOOTH:
return "BLUETOOTH";
- case CRAS_NODE_TYPE_BLUETOOTH_NB_MIC:
- return "BLUETOOTH_NB_MIC";
case CRAS_NODE_TYPE_FALLBACK_NORMAL:
return "FALLBACK_NORMAL";
case CRAS_NODE_TYPE_FALLBACK_ABNORMAL:
return "FALLBACK_ABNORMAL";
- case CRAS_NODE_TYPE_ECHO_REFERENCE:
- return "ECHO_REFERENCE";
- case CRAS_NODE_TYPE_ALSA_LOOPBACK:
- return "ALSA_LOOPBACK";
case CRAS_NODE_TYPE_UNKNOWN:
default:
return "UNKNOWN";
@@ -263,10 +250,10 @@ static int fill_node_list(struct iodev_list *list,
dev->is_enabled && (dev->active_node == node);
node_info->volume = node->volume;
node_info->capture_gain = node->capture_gain;
- node_info->ui_gain_scaler = node->ui_gain_scaler;
node_info->left_right_swapped =
node->left_right_swapped;
node_info->stable_id = node->stable_id;
+ strcpy(node_info->mic_positions, node->mic_positions);
strcpy(node_info->name, node->name);
strcpy(node_info->active_hotword_model,
node->active_hotword_model);
@@ -348,7 +335,7 @@ static void remove_all_streams_from_dev(struct cras_iodev *dev)
DL_FOREACH (stream_list_get(stream_list), rstream) {
if (rstream->apm_list == NULL)
continue;
- cras_apm_list_remove_apm(rstream->apm_list, dev);
+ cras_apm_list_remove(rstream->apm_list, dev);
}
}
@@ -364,8 +351,7 @@ static void possibly_enable_echo_reference(struct cras_iodev *dev)
if (dev->echo_reference_dev == NULL)
return;
- server_stream_create(stream_list, dev->echo_reference_dev->info.idx,
- dev->format);
+ server_stream_create(stream_list, dev->echo_reference_dev->info.idx);
}
/*
@@ -381,19 +367,33 @@ static void possibly_disable_echo_reference(struct cras_iodev *dev)
}
/*
- * Removes all attached streams and close dev if it's opened.
+ * Close dev if it's opened, without the extra call to idle_dev_check.
+ * This is useful for closing a dev inside idle_dev_check function to
+ * avoid infinite recursive call.
+ *
+ * Returns:
+ * -EINVAL if device was not opened, otherwise return 0.
*/
-static void close_dev(struct cras_iodev *dev)
+static int close_dev_without_idle_check(struct cras_iodev *dev)
{
if (!cras_iodev_is_open(dev))
- return;
+ return -EINVAL;
- MAINLOG(main_log, MAIN_THREAD_DEV_CLOSE, dev->info.idx, 0, 0);
remove_all_streams_from_dev(dev);
dev->idle_timeout.tv_sec = 0;
- /* close echo ref first to avoid underrun in hardware */
- possibly_disable_echo_reference(dev);
cras_iodev_close(dev);
+ possibly_disable_echo_reference(dev);
+ return 0;
+}
+
+static void close_dev(struct cras_iodev *dev)
+{
+ if (close_dev_without_idle_check(dev))
+ return;
+
+ if (idle_timer)
+ cras_tm_cancel_timer(cras_system_state_get_tm(), idle_timer);
+ idle_dev_check(NULL, NULL);
}
static void idle_dev_check(struct cras_timer *timer, void *data)
@@ -412,7 +412,7 @@ static void idle_dev_check(struct cras_timer *timer, void *data)
if (edev->dev->idle_timeout.tv_sec == 0)
continue;
if (timespec_after(&now, &edev->dev->idle_timeout)) {
- close_dev(edev->dev);
+ close_dev_without_idle_check(edev->dev);
continue;
}
num_idle_devs++;
@@ -467,8 +467,6 @@ static int init_device(struct cras_iodev *dev, struct cras_rstream *rstream)
if (cras_iodev_is_open(dev))
return 0;
cancel_pending_init_retries(dev->info.idx);
- MAINLOG(main_log, MAIN_THREAD_DEV_INIT, dev->info.idx,
- rstream->format.num_channels, rstream->format.frame_rate);
rc = cras_iodev_open(dev, rstream->cb_threshold, &rstream->format);
if (rc)
@@ -488,17 +486,10 @@ static void suspend_devs()
struct enabled_dev *edev;
struct cras_rstream *rstream;
- MAINLOG(main_log, MAIN_THREAD_SUSPEND_DEVS, 0, 0, 0);
-
DL_FOREACH (stream_list_get(stream_list), rstream) {
if (rstream->is_pinned) {
struct cras_iodev *dev;
- /* Skip closing hotword stream in the first pass.
- * Closing an input device may resume hotword stream
- * with its post_close_iodev_hook so we should deal
- * with hotword stream in the second pass.
- */
if ((rstream->flags & HOTWORD_STREAM) == HOTWORD_STREAM)
continue;
@@ -522,52 +513,15 @@ static void suspend_devs()
DL_FOREACH (enabled_devs[CRAS_STREAM_INPUT], edev) {
close_dev(edev->dev);
}
-
- /* Doing this check after all the other enabled iodevs are closed to
- * ensure preempted hotword streams obey the pause_at_suspend flag.
- */
- if (cras_system_get_hotword_pause_at_suspend()) {
- cras_iodev_list_suspend_hotword_streams();
- hotword_auto_resume = 1;
- }
}
static int stream_added_cb(struct cras_rstream *rstream);
static void resume_devs()
{
- struct enabled_dev *edev;
struct cras_rstream *rstream;
- int has_output_stream = 0;
stream_list_suspended = 0;
-
- MAINLOG(main_log, MAIN_THREAD_RESUME_DEVS, 0, 0, 0);
-
- /* Auto-resume based on the local flag in case the system state flag has
- * changed.
- */
- if (hotword_auto_resume) {
- cras_iodev_list_resume_hotword_stream();
- hotword_auto_resume = 0;
- }
-
- /*
- * To remove the short popped noise caused by applications that can not
- * stop playback "right away" after resume, we mute all output devices
- * for a short time if there is any output stream.
- */
- DL_FOREACH (stream_list_get(stream_list), rstream) {
- if (rstream->direction == CRAS_STREAM_OUTPUT)
- has_output_stream++;
- }
- if (has_output_stream) {
- DL_FOREACH (enabled_devs[CRAS_STREAM_OUTPUT], edev) {
- edev->dev->initial_ramp_request =
- CRAS_IODEV_RAMP_REQUEST_RESUME_MUTE;
- }
- }
-
DL_FOREACH (stream_list_get(stream_list), rstream) {
if ((rstream->flags & HOTWORD_STREAM) == HOTWORD_STREAM)
continue;
@@ -584,6 +538,18 @@ void sys_suspend_change(void *arg, int suspended)
resume_devs();
}
+/* Called when the system capture gain changes. Pass the current capture_gain
+ * setting to the default input if it is active. */
+void sys_cap_gain_change(void *context, int32_t gain)
+{
+ struct cras_iodev *dev;
+
+ DL_FOREACH (devs[CRAS_STREAM_INPUT].iodevs, dev) {
+ if (dev->set_capture_gain && cras_iodev_is_open(dev))
+ dev->set_capture_gain(dev);
+ }
+}
+
/* Called when the system capture mute state changes. Pass the current capture
* mute setting to the default input if it is active. */
static void sys_cap_mute_change(void *context, int muted, int mute_locked)
@@ -650,10 +616,8 @@ static int add_stream_to_open_devs(struct cras_rstream *stream,
int i;
if (stream->apm_list) {
for (i = 0; i < num_iodevs; i++)
- cras_apm_list_add_apm(stream->apm_list, iodevs[i],
- iodevs[i]->format,
- cras_iodev_is_aec_use_case(
- iodevs[i]->active_node));
+ cras_apm_list_add(stream->apm_list, iodevs[i],
+ iodevs[i]->format);
}
return audio_thread_add_stream(audio_thread, stream, iodevs,
num_iodevs);
@@ -674,39 +638,20 @@ static int init_and_attach_streams(struct cras_iodev *dev)
/* If there are active streams to attach to this device,
* open it. */
DL_FOREACH (stream_list_get(stream_list), stream) {
- bool can_attach = 0;
-
if (stream->direction != dir)
continue;
/*
- * For normal stream, if device is enabled by UI then it can
- * attach to this dev.
- */
- if (!stream->is_pinned) {
- can_attach = dev_enabled;
- }
- /*
- * If this is a pinned stream, attach it if its pinned dev id
- * matches this device or any fallback dev. Note that attaching
- * a pinned stream to fallback device is temporary. When the
- * fallback dev gets disabled in possibly_disable_fallback()
- * the check stream_list_has_pinned_stream() is key to allow
- * all streams to be removed from fallback and close it.
+ * Don't attach this stream if (1) this stream pins to a
+ * different device, or (2) this is a normal stream, but
+ * device is not enabled.
*/
- else if ((stream->pinned_dev_idx == dev->info.idx) ||
- (SILENT_PLAYBACK_DEVICE == dev->info.idx) ||
- (SILENT_RECORD_DEVICE == dev->info.idx)) {
- can_attach = 1;
- }
-
- if (!can_attach)
+ if (stream->is_pinned) {
+ if (stream->pinned_dev_idx != dev->info.idx)
+ continue;
+ } else if (!dev_enabled) {
continue;
+ }
- /*
- * Note that the stream list is descending ordered by channel
- * count, which guarantees the first attachable stream will have
- * the highest channel count.
- */
rc = init_device(dev, stream);
if (rc) {
syslog(LOG_ERR, "Enable %s failed, rc = %d",
@@ -778,11 +723,6 @@ static int init_pinned_device(struct cras_iodev *dev,
return 0;
}
-/*
- * Close device enabled by pinned stream. Since it's NOT in the enabled
- * dev list, make sure update_active_node() is called to correctly
- * configure the ALSA UCM or BT profile state.
- */
static int close_pinned_device(struct cras_iodev *dev)
{
close_dev(dev);
@@ -836,64 +776,34 @@ static int stream_added_cb(struct cras_rstream *rstream)
struct cras_iodev *iodevs[10];
unsigned int num_iodevs;
int rc;
- bool iodev_reopened;
if (stream_list_suspended)
return 0;
- MAINLOG(main_log, MAIN_THREAD_STREAM_ADDED, rstream->stream_id,
- rstream->direction, rstream->buffer_frames);
-
if (rstream->is_pinned)
return pinned_stream_added(rstream);
/* Add the new stream to all enabled iodevs at once to avoid offset
* in shm level between different ouput iodevs. */
num_iodevs = 0;
- iodev_reopened = false;
DL_FOREACH (enabled_devs[rstream->direction], edev) {
if (num_iodevs >= ARRAY_SIZE(iodevs)) {
syslog(LOG_ERR, "too many enabled devices");
break;
}
- if (cras_iodev_is_open(edev->dev) &&
- (rstream->format.num_channels >
- edev->dev->format->num_channels) &&
- (rstream->format.num_channels <=
- edev->dev->info.max_supported_channels)) {
- /* Re-open the device with the format of the attached
- * stream if it has higher channel count than the
- * current format of the device, and doesn't exceed the
- * max_supported_channels of the device.
- * Fallback device will be transciently enabled during
- * the device re-opening.
+ rc = init_device(edev->dev, rstream);
+ if (rc) {
+ /* Error log but don't return error here, because
+ * stopping audio could block video playback.
*/
- MAINLOG(main_log, MAIN_THREAD_DEV_REOPEN,
- rstream->format.num_channels,
- edev->dev->format->num_channels,
- edev->dev->format->frame_rate);
- syslog(LOG_INFO, "re-open %s for higher channel count",
- edev->dev->info.name);
- possibly_enable_fallback(rstream->direction, false);
- cras_iodev_list_suspend_dev(edev->dev->info.idx);
- cras_iodev_list_resume_dev(edev->dev->info.idx);
- possibly_disable_fallback(rstream->direction);
- iodev_reopened = true;
- } else {
- rc = init_device(edev->dev, rstream);
- if (rc) {
- /* Error log but don't return error here, because
- * stopping audio could block video playback.
- */
- syslog(LOG_ERR, "Init %s failed, rc = %d",
- edev->dev->info.name, rc);
- schedule_init_device_retry(edev->dev);
- continue;
- }
-
- iodevs[num_iodevs++] = edev->dev;
+ syslog(LOG_ERR, "Init %s failed, rc = %d",
+ edev->dev->info.name, rc);
+ schedule_init_device_retry(edev->dev);
+ continue;
}
+
+ iodevs[num_iodevs++] = edev->dev;
}
if (num_iodevs) {
rc = add_stream_to_open_devs(rstream, iodevs, num_iodevs);
@@ -901,9 +811,9 @@ static int stream_added_cb(struct cras_rstream *rstream)
syslog(LOG_ERR, "adding stream to thread fail");
return rc;
}
- } else if (!iodev_reopened) {
+ } else {
/* Enable fallback device if no other iodevs can be initialized
- * or re-opened successfully.
+ * successfully.
* For error codes like EAGAIN and ENOENT, a new iodev will be
* enabled soon so streams are going to route there. As for the
* rest of the error cases, silence will be played or recorded
@@ -970,8 +880,6 @@ static int stream_removed_cb(struct cras_rstream *rstream)
if (rc)
return rc;
- MAINLOG(main_log, MAIN_THREAD_STREAM_REMOVED, rstream->stream_id, 0, 0);
-
if (rstream->is_pinned)
pinned_stream_removed(rstream);
@@ -1018,7 +926,6 @@ static int disable_device(struct enabled_dev *edev, bool force)
struct cras_rstream *stream;
struct device_enabled_cb *callback;
- MAINLOG(main_log, MAIN_THREAD_DEV_DISABLE, dev->info.idx, force, 0);
/*
* Remove from enabled dev list. However this dev could have a stream
* pinned to it, only cancel pending init timers when force flag is set.
@@ -1026,23 +933,26 @@ static int disable_device(struct enabled_dev *edev, bool force)
DL_DELETE(enabled_devs[dir], edev);
free(edev);
dev->is_enabled = 0;
- if (force) {
+ if (force)
cancel_pending_init_retries(dev->info.idx);
+
+ /*
+ * Pull all default streams off this device.
+ * Pull all pinned streams off as well if force is true.
+ */
+ DL_FOREACH (stream_list_get(stream_list), stream) {
+ if (stream->direction != dev->direction)
+ continue;
+ if (stream->is_pinned && !force)
+ continue;
+ audio_thread_disconnect_stream(audio_thread, stream, dev);
}
- /* If there's a pinned stream exists, simply disconnect all the normal
- * streams off this device and return. */
- else if (stream_list_has_pinned_stream(stream_list, dev->info.idx)) {
- DL_FOREACH (stream_list_get(stream_list), stream) {
- if (stream->direction != dev->direction)
- continue;
- if (stream->is_pinned)
- continue;
- audio_thread_disconnect_stream(audio_thread, stream,
- dev);
- }
+ /* If this is a force disable call, that guarantees pinned streams have
+ * all been detached. Otherwise check with stream_list to see if
+ * there's still a pinned stream using this device.
+ */
+ if (!force && stream_list_has_pinned_stream(stream_list, dev->info.idx))
return 0;
- }
-
DL_FOREACH (device_enable_cbs, callback)
callback->disabled_cb(dev, callback->cb_data);
close_dev(dev);
@@ -1052,6 +962,36 @@ static int disable_device(struct enabled_dev *edev, bool force)
}
/*
+ * Assume the device is not in enabled_devs list.
+ * Assume there is no default stream on the device.
+ * An example is that this device is unplugged while it is playing
+ * a pinned stream. The device and stream may have been removed in
+ * audio thread due to I/O error handling.
+ */
+static int force_close_pinned_only_device(struct cras_iodev *dev)
+{
+ struct cras_rstream *rstream;
+
+ /* Pull pinned streams off this device. Note that this is initiated
+ * from server side, so the pin stream still exist in stream_list
+ * pending client side to actually remove it.
+ */
+ DL_FOREACH (stream_list_get(stream_list), rstream) {
+ if (rstream->direction != dev->direction)
+ continue;
+ if (!rstream->is_pinned)
+ continue;
+ if (dev->info.idx != rstream->pinned_dev_idx)
+ continue;
+ audio_thread_disconnect_stream(audio_thread, rstream, dev);
+ }
+
+ close_dev(dev);
+ dev->update_active_node(dev, dev->active_node->idx, 0);
+ return 0;
+}
+
+/*
* Exported Interface.
*/
@@ -1062,13 +1002,12 @@ void cras_iodev_list_init()
memset(&observer_ops, 0, sizeof(observer_ops));
observer_ops.output_volume_changed = sys_vol_change;
observer_ops.output_mute_changed = sys_mute_change;
+ observer_ops.capture_gain_changed = sys_cap_gain_change;
observer_ops.capture_mute_changed = sys_cap_mute_change;
observer_ops.suspend_changed = sys_suspend_change;
list_observer = cras_observer_add(&observer_ops, NULL);
idle_timer = NULL;
- main_log = main_thread_event_log_init();
-
/* Create the audio stream list for the system. */
stream_list =
stream_list_create(stream_added_cb, stream_removed_cb,
@@ -1110,7 +1049,6 @@ void cras_iodev_list_deinit()
empty_iodev_destroy(fallback_devs[CRAS_STREAM_INPUT]);
empty_iodev_destroy(fallback_devs[CRAS_STREAM_OUTPUT]);
stream_list_destroy(stream_list);
- main_thread_event_log_deinit(main_log);
if (list_observer) {
cras_observer_remove(list_observer);
list_observer = NULL;
@@ -1146,8 +1084,6 @@ void cras_iodev_list_add_active_node(enum CRAS_STREAM_DIRECTION dir,
if (!new_dev || new_dev->direction != dir)
return;
- MAINLOG(main_log, MAIN_THREAD_ADD_ACTIVE_NODE, new_dev->info.idx, 0, 0);
-
/* If the new dev is already enabled but its active node needs to be
* changed. Disable new dev first, update active node, and then
* re-enable it again.
@@ -1187,7 +1123,7 @@ void cras_iodev_list_disable_dev(struct cras_iodev *dev, bool force_close)
*/
if (!edev_to_disable) {
if (force_close)
- close_pinned_device(dev);
+ force_close_pinned_only_device(dev);
return;
}
@@ -1205,13 +1141,25 @@ void cras_iodev_list_disable_dev(struct cras_iodev *dev, bool force_close)
void cras_iodev_list_suspend_dev(unsigned int dev_idx)
{
+ struct cras_rstream *rstream;
struct cras_iodev *dev = find_dev(dev_idx);
if (!dev)
return;
- /* Remove all streams including the pinned streams, and close
- * this iodev. */
+ DL_FOREACH (stream_list_get(stream_list), rstream) {
+ if (rstream->direction != dev->direction)
+ continue;
+ /* Disconnect all streams that are either:
+ * (1) normal stream while dev is enabled by UI, or
+ * (2) stream specifically pins to this dev.
+ */
+ if ((dev->is_enabled && !rstream->is_pinned) ||
+ (rstream->is_pinned &&
+ (dev->info.idx != rstream->pinned_dev_idx)))
+ audio_thread_disconnect_stream(audio_thread, rstream,
+ dev);
+ }
close_dev(dev);
dev->update_active_node(dev, dev->active_node->idx, 0);
}
@@ -1272,8 +1220,6 @@ int cras_iodev_list_add_output(struct cras_iodev *output)
if (rc)
return rc;
- MAINLOG(main_log, MAIN_THREAD_ADD_TO_DEV_LIST, output->info.idx,
- CRAS_STREAM_OUTPUT, 0);
return 0;
}
@@ -1288,8 +1234,6 @@ int cras_iodev_list_add_input(struct cras_iodev *input)
if (rc)
return rc;
- MAINLOG(main_log, MAIN_THREAD_ADD_TO_DEV_LIST, input->info.idx,
- CRAS_STREAM_INPUT, 0);
return 0;
}
@@ -1532,15 +1476,11 @@ void cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
struct cras_iodev *new_dev = NULL;
struct enabled_dev *edev;
int new_node_already_enabled = 0;
- struct cras_rstream *rstream;
- int has_output_stream = 0;
int rc;
/* find the devices for the id. */
new_dev = find_dev(dev_index_of(node_id));
- MAINLOG(main_log, MAIN_THREAD_SELECT_NODE, dev_index_of(node_id), 0, 0);
-
/* Do nothing if the direction is mismatched. The new_dev == NULL case
could happen if node_id is 0 (no selection), or the client tries
to select a non-existing node (maybe it's unplugged just before
@@ -1568,44 +1508,17 @@ void cras_iodev_list_select_node(enum CRAS_STREAM_DIRECTION direction,
if (!new_node_already_enabled)
possibly_enable_fallback(direction, false);
+ /* Disable all devices except for fallback device, and the new device,
+ * provided it is already enabled. */
DL_FOREACH (enabled_devs[direction], edev) {
- /* Don't disable fallback devices. */
- if (edev->dev == fallback_devs[direction])
- continue;
- /*
- * Disable enabled device if it's not the new one, use non-force
- * disable call so we don't interrupt existing pinned streams on
- * it.
- */
- if (edev->dev != new_dev) {
+ if (edev->dev != fallback_devs[direction] &&
+ !(new_node_already_enabled && edev->dev == new_dev)) {
disable_device(edev, false);
}
- /*
- * Otherwise if this happens to be the new device but about to
- * select to a different node (on the same dev). Force disable
- * this device to avoid any pinned stream occupies it in audio
- * thread and cause problem in later update_active_node call.
- */
- else if (!new_node_already_enabled) {
- disable_device(edev, true);
- }
}
if (new_dev && !new_node_already_enabled) {
new_dev->update_active_node(new_dev, node_index_of(node_id), 1);
-
- /* To reduce the popped noise of active device change, mute
- * new_dev's for RAMP_SWITCH_MUTE_DURATION_SECS s.
- */
- DL_FOREACH (stream_list_get(stream_list), rstream) {
- if (rstream->direction == CRAS_STREAM_OUTPUT)
- has_output_stream++;
- }
- if (direction == CRAS_STREAM_OUTPUT && has_output_stream) {
- new_dev->initial_ramp_request =
- CRAS_IODEV_RAMP_REQUEST_SWITCH_MUTE;
- }
-
rc = enable_device(new_dev);
if (rc == 0) {
/* Disable fallback device after new device is enabled.
@@ -1647,38 +1560,22 @@ static int set_node_volume(struct cras_iodev *iodev, unsigned int node_idx,
if (iodev->set_volume)
iodev->set_volume(iodev);
cras_iodev_list_notify_node_volume(node);
- MAINLOG(main_log, MAIN_THREAD_OUTPUT_NODE_VOLUME, iodev->info.idx,
- volume, 0);
return 0;
}
static int set_node_capture_gain(struct cras_iodev *iodev,
- unsigned int node_idx, int value)
+ unsigned int node_idx, int capture_gain)
{
struct cras_ionode *node;
- int db_scale;
node = find_node(iodev, node_idx);
if (!node)
return -EINVAL;
- /* Assert value in range 0 - 100. */
- if (value < 0)
- value = 0;
- if (value > 100)
- value = 100;
-
- /* Linear maps (0, 50) to (-4000, 0) and (50, 100) to (0, 2000) dBFS.
- * Calculate and store corresponding scaler in ui_gain_scaler. */
- db_scale = (value > 50) ? 40 : 80;
- node->ui_gain_scaler =
- convert_softvol_scaler_from_dB((value - 50) * db_scale);
-
+ node->capture_gain = capture_gain;
if (iodev->set_capture_gain)
iodev->set_capture_gain(iodev);
cras_iodev_list_notify_node_capture_gain(node);
- MAINLOG(main_log, MAIN_THREAD_INPUT_NODE_GAIN, iodev->info.idx, value,
- 0);
return 0;
}
@@ -1881,24 +1778,6 @@ void cras_iodev_list_unregister_loopback(enum CRAS_LOOPBACK_TYPE type,
}
}
-void cras_iodev_list_reset_for_noise_cancellation()
-{
- struct cras_iodev *dev;
- bool enabled = cras_system_get_noise_cancellation_enabled();
-
- DL_FOREACH (devs[CRAS_STREAM_INPUT].iodevs, dev) {
- if (!cras_iodev_is_open(dev) ||
- !cras_iodev_support_noise_cancellation(dev))
- continue;
- syslog(LOG_INFO, "Re-open %s for %s noise cancellation",
- dev->info.name, enabled ? "enabling" : "disabling");
- possibly_enable_fallback(CRAS_STREAM_INPUT, false);
- cras_iodev_list_suspend_dev(dev->info.idx);
- cras_iodev_list_resume_dev(dev->info.idx);
- possibly_disable_fallback(CRAS_STREAM_INPUT);
- }
-}
-
void cras_iodev_list_reset()
{
struct enabled_dev *edev;
diff --git a/cras/src/server/cras_iodev_list.h b/cras/src/server/cras_iodev_list.h
index d6e9ba54..61c3a182 100644
--- a/cras/src/server/cras_iodev_list.h
+++ b/cras/src/server/cras_iodev_list.h
@@ -274,11 +274,6 @@ int cras_iodev_list_suspend_hotword_streams();
/* Resumes all hotwording streams. */
int cras_iodev_list_resume_hotword_stream();
-/* Sets the state of noise cancellation for input devices which supports noise
- * cancellation by suspend, enable/disable, then resume.
- */
-void cras_iodev_list_reset_for_noise_cancellation();
-
/* For unit test only. */
void cras_iodev_list_reset();
diff --git a/cras/src/server/cras_loopback_iodev.c b/cras/src/server/cras_loopback_iodev.c
index cf3ba4ae..dea96169 100644
--- a/cras/src/server/cras_loopback_iodev.c
+++ b/cras/src/server/cras_loopback_iodev.c
@@ -7,7 +7,6 @@
#include <sys/param.h>
#include <syslog.h>
-#include "audio_thread_log.h"
#include "byte_buffer.h"
#include "cras_audio_area.h"
#include "cras_config.h"
@@ -61,9 +60,6 @@ static int sample_hook_start(bool start, void *cb_data)
/*
* Called in the put buffer function of the sender that hooked to.
- *
- * Returns:
- * Number of frames copied to the sample buffer in the hook.
*/
static int sample_hook(const uint8_t *frames, unsigned int nframes,
const struct cras_audio_format *fmt, void *cb_data)
@@ -71,26 +67,17 @@ static int sample_hook(const uint8_t *frames, unsigned int nframes,
struct loopback_iodev *loopdev = (struct loopback_iodev *)cb_data;
struct byte_buffer *sbuf = loopdev->sample_buffer;
unsigned int frame_bytes = cras_get_format_bytes(fmt);
- unsigned int frames_to_copy, bytes_to_copy, frames_copied = 0;
- int i;
-
- for (i = 0; i < 2; i++) {
- frames_to_copy = MIN(buf_writable(sbuf) / frame_bytes, nframes);
- if (!frames_to_copy)
- break;
-
- bytes_to_copy = frames_to_copy * frame_bytes;
- memcpy(buf_write_pointer(sbuf), frames, bytes_to_copy);
- buf_increment_write(sbuf, bytes_to_copy);
- frames += bytes_to_copy;
- nframes -= frames_to_copy;
- frames_copied += frames_to_copy;
- }
+ unsigned int frames_to_copy, bytes_to_copy;
+
+ frames_to_copy = MIN(buf_writable(sbuf) / frame_bytes, nframes);
+ if (!frames_to_copy)
+ return 0;
- ATLOG(atlog, AUDIO_THREAD_LOOPBACK_SAMPLE_HOOK, nframes + frames_copied,
- frames_copied, 0);
+ bytes_to_copy = frames_to_copy * frame_bytes;
+ memcpy(buf_write_pointer(sbuf), frames, bytes_to_copy);
+ buf_increment_write(sbuf, bytes_to_copy);
- return frames_copied;
+ return frames_to_copy;
}
static void update_first_output_to_loopback(struct loopback_iodev *loopdev)
@@ -219,8 +206,6 @@ static int get_record_buffer(struct cras_iodev *iodev,
unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
unsigned int avail_frames = buf_readable(sbuf) / frame_bytes;
- ATLOG(atlog, AUDIO_THREAD_LOOPBACK_GET, *frames, avail_frames, 0);
-
*frames = MIN(avail_frames, *frames);
iodev->area->frames = *frames;
cras_audio_area_config_buf_pointers(iodev->area, iodev->format,
@@ -236,9 +221,8 @@ static int put_record_buffer(struct cras_iodev *iodev, unsigned nframes)
struct byte_buffer *sbuf = loopdev->sample_buffer;
unsigned int frame_bytes = cras_get_format_bytes(iodev->format);
- buf_increment_read(sbuf, (size_t)nframes * (size_t)frame_bytes);
+ buf_increment_read(sbuf, nframes * frame_bytes);
loopdev->read_frames += nframes;
- ATLOG(atlog, AUDIO_THREAD_LOOPBACK_PUT, nframes, 0, 0);
return 0;
}
@@ -297,12 +281,6 @@ static struct cras_iodev *create_loopback_iodev(enum CRAS_LOOPBACK_TYPE type)
iodev->put_buffer = put_record_buffer;
iodev->flush_buffer = flush_record_buffer;
- /*
- * Record max supported channels into cras_iodev_info.
- * The value is the max of loopback_supported_channel_counts.
- */
- iodev->info.max_supported_channels = 2;
-
return iodev;
}
@@ -331,15 +309,15 @@ struct cras_iodev *loopback_iodev_create(enum CRAS_LOOPBACK_TYPE type)
if (iodev == NULL)
return NULL;
- /* Create an empty ionode */
+ /* Create a dummy ionode */
node = (struct cras_ionode *)calloc(1, sizeof(*node));
node->dev = iodev;
node->type = node_type;
node->plugged = 1;
node->volume = 100;
- node->ui_gain_scaler = 1.0f;
node->stable_id = iodev->info.stable_id;
node->software_volume_needed = 0;
+ node->max_software_gain = 0;
strcpy(node->name, loopdev_names[type]);
cras_iodev_add_node(iodev, node);
cras_iodev_set_active_node(iodev, node);
diff --git a/cras/src/server/cras_main_message.c b/cras/src/server/cras_main_message.c
index b88e4000..9fe62afb 100644
--- a/cras/src/server/cras_main_message.c
+++ b/cras/src/server/cras_main_message.c
@@ -77,7 +77,7 @@ static int read_main_message(int msg_fd, uint8_t *buf, size_t max_len)
return 0;
}
-static void handle_main_messages(void *arg, int revents)
+static void handle_main_messages(void *arg)
{
uint8_t buf[256];
int rc;
@@ -112,6 +112,5 @@ void cras_main_message_init()
cras_make_fd_nonblocking(main_msg_fds[0]);
cras_make_fd_nonblocking(main_msg_fds[1]);
- cras_system_add_select_fd(main_msg_fds[0], handle_main_messages, NULL,
- POLLIN);
+ cras_system_add_select_fd(main_msg_fds[0], handle_main_messages, NULL);
}
diff --git a/cras/src/server/cras_main_thread_log.h b/cras/src/server/cras_main_thread_log.h
deleted file mode 100644
index 1d92585a..00000000
--- a/cras/src/server/cras_main_thread_log.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef CRAS_MAIN_THREAD_LOG_H_
-#define CRAS_MAIN_THREAD_LOG_H_
-
-#include <stdint.h>
-
-#include "cras_types.h"
-
-#define CRAS_MAIN_THREAD_LOGGING 1
-
-#if (CRAS_MAIN_THREAD_LOGGING)
-#define MAINLOG(log, event, data1, data2, data3) \
- main_thread_event_log_data(log, event, data1, data2, data3);
-#else
-#define MAINLOG(log, event, data1, data2, data3)
-#endif
-
-extern struct main_thread_event_log *main_log;
-
-static inline struct main_thread_event_log *main_thread_event_log_init()
-{
- struct main_thread_event_log *log;
- log = (struct main_thread_event_log *)calloc(
- 1, sizeof(struct main_thread_event_log));
- if (!log)
- return NULL;
-
- log->len = MAIN_THREAD_EVENT_LOG_SIZE;
- return log;
-}
-
-static inline void
-main_thread_event_log_deinit(struct main_thread_event_log *log)
-{
- if (log)
- free(log);
-}
-
-static inline void main_thread_event_log_data(struct main_thread_event_log *log,
- enum MAIN_THREAD_LOG_EVENTS event,
- uint32_t data1, uint32_t data2,
- uint32_t data3)
-{
- struct timespec now;
-
- if (!log)
- return;
-
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- log->log[log->write_pos].tag_sec =
- (event << 24) | ((now.tv_sec % 86400) & 0x00ffffff);
- log->log[log->write_pos].nsec = now.tv_nsec;
- log->log[log->write_pos].data1 = data1;
- log->log[log->write_pos].data2 = data2;
- log->log[log->write_pos].data3 = data3;
- log->write_pos++;
- log->write_pos %= MAIN_THREAD_EVENT_LOG_SIZE;
-}
-
-#endif /* CRAS_MAIN_THREAD_LOG_H_ */
diff --git a/cras/src/server/cras_observer.c b/cras/src/server/cras_observer.c
index 0f17dc92..0f6ab96b 100644
--- a/cras/src/server/cras_observer.c
+++ b/cras/src/server/cras_observer.c
@@ -7,7 +7,6 @@
#include "cras_alert.h"
#include "cras_iodev_list.h"
-#include "cras_types.h"
#include "utlist.h"
struct cras_observer_client {
@@ -35,8 +34,6 @@ struct cras_observer_alerts {
* per-direciton. */
struct cras_alert *num_active_streams[CRAS_NUM_DIRECTIONS];
struct cras_alert *non_empty_audio_state_changed;
- struct cras_alert *bt_battery_changed;
- struct cras_alert *num_input_streams_with_permission;
};
struct cras_observer_server {
@@ -78,10 +75,6 @@ struct cras_observer_alert_data_streams {
uint32_t num_active_streams;
};
-struct cras_observer_alert_data_input_streams {
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE];
-};
-
struct cras_observer_alert_data_hotword_triggered {
int64_t tv_sec;
int64_t tv_nsec;
@@ -91,11 +84,6 @@ struct cras_observer_non_empty_audio_state {
int non_empty;
};
-struct cras_observer_alert_data_bt_battery_changed {
- const char *address;
- uint32_t level;
-};
-
/* Global observer instance. */
static struct cras_observer_server *g_observer;
@@ -259,20 +247,6 @@ static void num_active_streams_alert(void *arg, void *data)
}
}
-static void num_input_streams_with_permission_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_input_streams *input_streams_data =
- (struct cras_observer_alert_data_input_streams *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.num_input_streams_with_permission_changed)
- client->ops.num_input_streams_with_permission_changed(
- client->context,
- input_streams_data->num_input_streams);
- }
-}
-
static void hotword_triggered_alert(void *arg, void *data)
{
struct cras_observer_client *client;
@@ -302,20 +276,6 @@ static void non_empty_audio_state_changed_alert(void *arg, void *data)
}
}
-static void bt_battery_changed_alert(void *arg, void *data)
-{
- struct cras_observer_client *client;
- struct cras_observer_alert_data_bt_battery_changed *triggered_data =
- (struct cras_observer_alert_data_bt_battery_changed *)data;
-
- DL_FOREACH (g_observer->clients, client) {
- if (client->ops.bt_battery_changed)
- client->ops.bt_battery_changed(client->context,
- triggered_data->address,
- triggered_data->level);
- }
-}
-
static int cras_observer_server_set_alert(struct cras_alert **alert,
cras_alert_cb cb,
cras_alert_prepare prepare,
@@ -372,8 +332,6 @@ int cras_observer_server_init()
CRAS_OBSERVER_SET_ALERT(suspend_changed, NULL, 0);
CRAS_OBSERVER_SET_ALERT(hotword_triggered, NULL, 0);
CRAS_OBSERVER_SET_ALERT(non_empty_audio_state_changed, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(bt_battery_changed, NULL, 0);
- CRAS_OBSERVER_SET_ALERT(num_input_streams_with_permission, NULL, 0);
CRAS_OBSERVER_SET_ALERT_WITH_DIRECTION(num_active_streams,
CRAS_STREAM_OUTPUT);
@@ -405,9 +363,6 @@ void cras_observer_server_free()
cras_alert_destroy(g_observer->alerts.suspend_changed);
cras_alert_destroy(g_observer->alerts.hotword_triggered);
cras_alert_destroy(g_observer->alerts.non_empty_audio_state_changed);
- cras_alert_destroy(g_observer->alerts.bt_battery_changed);
- cras_alert_destroy(
- g_observer->alerts.num_input_streams_with_permission);
cras_alert_destroy(
g_observer->alerts.num_active_streams[CRAS_STREAM_OUTPUT]);
cras_alert_destroy(
@@ -585,21 +540,6 @@ void cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,
cras_alert_pending_data(alert, &data, sizeof(data));
}
-void cras_observer_notify_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- struct cras_observer_alert_data_input_streams data;
- struct cras_alert *alert;
-
- memcpy(&data.num_input_streams, num_input_streams,
- sizeof(*num_input_streams) * CRAS_NUM_CLIENT_TYPE);
- alert = g_observer->alerts.num_input_streams_with_permission;
- if (!alert)
- return;
-
- cras_alert_pending_data(alert, &data, sizeof(data));
-}
-
void cras_observer_notify_hotword_triggered(int64_t tv_sec, int64_t tv_nsec)
{
struct cras_observer_alert_data_hotword_triggered data;
@@ -619,16 +559,4 @@ void cras_observer_notify_non_empty_audio_state_changed(int non_empty)
cras_alert_pending_data(
g_observer->alerts.non_empty_audio_state_changed, &data,
sizeof(data));
-}
-
-void cras_observer_notify_bt_battery_changed(const char *address,
- uint32_t level)
-{
- struct cras_observer_alert_data_bt_battery_changed data;
-
- data.address = address;
- data.level = level;
-
- cras_alert_pending_data(g_observer->alerts.bt_battery_changed, &data,
- sizeof(data));
-}
+} \ No newline at end of file
diff --git a/cras/src/server/cras_observer.h b/cras/src/server/cras_observer.h
index 2dd013b8..109bd609 100644
--- a/cras/src/server/cras_observer.h
+++ b/cras/src/server/cras_observer.h
@@ -92,18 +92,10 @@ void cras_observer_notify_suspend_changed(int suspended);
void cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,
uint32_t num_active_streams);
-/* Notify observers of the number of input streams with permission. */
-void cras_observer_notify_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE]);
-
/* Notify observers of the timestamp when hotword triggered. */
void cras_observer_notify_hotword_triggered(int64_t tv_sec, int64_t tv_nsec);
/* Notify observers the non-empty audio state changed. */
void cras_observer_notify_non_empty_audio_state_changed(int active);
-/* Notify observers the bluetooth headset battery level changed. */
-void cras_observer_notify_bt_battery_changed(const char *address,
- uint32_t level);
-
#endif /* CRAS_OBSERVER_H */
diff --git a/cras/src/server/cras_playback_rclient.c b/cras/src/server/cras_playback_rclient.c
index 54a75dbd..a282e8b1 100644
--- a/cras/src/server/cras_playback_rclient.c
+++ b/cras/src/server/cras_playback_rclient.c
@@ -11,12 +11,63 @@
#include "cras_rclient.h"
#include "cras_rclient_util.h"
#include "cras_rstream.h"
+#include "cras_system_state.h"
#include "cras_types.h"
#include "cras_util.h"
+#include "stream_list.h"
+
+/* Entry point for handling a message from the client. Called from the main
+ * server context. */
+static int cpr_handle_message_from_client(struct cras_rclient *client,
+ const struct cras_server_message *msg,
+ int *fds, unsigned int num_fds)
+{
+ int rc = 0;
+ assert(client && msg);
+
+ rc = rclient_validate_message_fds(msg, fds, num_fds);
+ if (rc < 0) {
+ for (int i = 0; i < (int)num_fds; i++)
+ if (fds[i] >= 0)
+ close(fds[i]);
+ return rc;
+ }
+ int fd = num_fds > 0 ? fds[0] : -1;
+
+ switch (msg->id) {
+ case CRAS_SERVER_CONNECT_STREAM: {
+ int client_shm_fd = num_fds > 1 ? fds[1] : -1;
+ struct cras_connect_message cmsg;
+ if (MSG_LEN_VALID(msg, struct cras_connect_message)) {
+ rc = rclient_handle_client_stream_connect(
+ client,
+ (const struct cras_connect_message *)msg, fd,
+ client_shm_fd);
+ } else if (!convert_connect_message_old(msg, &cmsg)) {
+ rc = rclient_handle_client_stream_connect(
+ client, &cmsg, fd, client_shm_fd);
+ } else {
+ return -EINVAL;
+ }
+ break;
+ }
+ case CRAS_SERVER_DISCONNECT_STREAM:
+ if (!MSG_LEN_VALID(msg, struct cras_disconnect_stream_message))
+ return -EINVAL;
+ rc = rclient_handle_client_stream_disconnect(
+ client,
+ (const struct cras_disconnect_stream_message *)msg);
+ break;
+ default:
+ break;
+ }
+
+ return rc;
+}
/* Declarations of cras_rclient operators for cras_playback_rclient. */
static const struct cras_rclient_ops cras_playback_rclient_ops = {
- .handle_message_from_client = rclient_handle_message_from_client,
+ .handle_message_from_client = cpr_handle_message_from_client,
.send_message_to_client = rclient_send_message_to_client,
.destroy = rclient_destroy,
};
@@ -29,7 +80,24 @@ static const struct cras_rclient_ops cras_playback_rclient_ops = {
* the connection has succeeded. */
struct cras_rclient *cras_playback_rclient_create(int fd, size_t id)
{
- return rclient_generic_create(
- fd, id, &cras_playback_rclient_ops,
- cras_stream_direction_mask(CRAS_STREAM_OUTPUT));
+ struct cras_rclient *client;
+ struct cras_client_connected msg;
+ int state_fd;
+
+ client = (struct cras_rclient *)calloc(1, sizeof(struct cras_rclient));
+ if (!client)
+ return NULL;
+
+ client->fd = fd;
+ client->id = id;
+
+ client->ops = &cras_playback_rclient_ops;
+ client->supported_directions =
+ cras_stream_direction_mask(CRAS_STREAM_OUTPUT);
+
+ cras_fill_client_connected(&msg, client->id);
+ state_fd = cras_sys_state_shm_fd();
+ client->ops->send_message_to_client(client, &msg.header, &state_fd, 1);
+
+ return client;
}
diff --git a/cras/src/server/cras_ramp.c b/cras/src/server/cras_ramp.c
index f0272047..5f40a777 100644
--- a/cras/src/server/cras_ramp.c
+++ b/cras/src/server/cras_ramp.c
@@ -62,11 +62,7 @@ int cras_ramp_start(struct cras_ramp *ramp, int mute_ramp, float from, float to,
{
struct cras_ramp_action action;
- if (!ramp)
- return -EINVAL;
-
- /* if from == to == 0 means we want to mute for duration_frames */
- if (from == to && from != 0)
+ if (from == to)
return 0;
/* Get current scaler position so it can serve as new start scaler. */
diff --git a/cras/src/server/cras_rclient.c b/cras/src/server/cras_rclient.c
index d2646e75..38ba5c20 100644
--- a/cras/src/server/cras_rclient.c
+++ b/cras/src/server/cras_rclient.c
@@ -24,7 +24,6 @@
#include "cras_server_metrics.h"
#include "cras_system_state.h"
#include "cras_types.h"
-#include "cras_unified_rclient.h"
#include "cras_util.h"
#include "stream_list.h"
#include "utlist.h"
@@ -59,16 +58,9 @@ int cras_rclient_send_message(const struct cras_rclient *client,
return client->ops->send_message_to_client(client, msg, fds, num_fds);
}
-static void cras_rclient_set_client_type(struct cras_rclient *client,
- enum CRAS_CLIENT_TYPE client_type)
-{
- client->client_type = client_type;
-}
-
struct cras_rclient *cras_rclient_create(int fd, size_t id,
enum CRAS_CONNECTION_TYPE conn_type)
{
- struct cras_rclient *client;
if (!cras_validate_connection_type(conn_type))
goto error;
@@ -79,18 +71,6 @@ struct cras_rclient *cras_rclient_create(int fd, size_t id,
return cras_playback_rclient_create(fd, id);
case CRAS_CAPTURE:
return cras_capture_rclient_create(fd, id);
- case CRAS_VMS_LEGACY:
- return cras_playback_rclient_create(fd, id);
- case CRAS_VMS_UNIFIED:
- return cras_unified_rclient_create(fd, id);
- case CRAS_PLUGIN_PLAYBACK:
- client = cras_playback_rclient_create(fd, id);
- cras_rclient_set_client_type(client, CRAS_CLIENT_TYPE_PLUGIN);
- return client;
- case CRAS_PLUGIN_UNIFIED:
- client = cras_unified_rclient_create(fd, id);
- cras_rclient_set_client_type(client, CRAS_CLIENT_TYPE_PLUGIN);
- return client;
default:
goto error;
}
diff --git a/cras/src/server/cras_rclient.h b/cras/src/server/cras_rclient.h
index 3a3988c2..6cffb7d8 100644
--- a/cras/src/server/cras_rclient.h
+++ b/cras/src/server/cras_rclient.h
@@ -20,9 +20,6 @@ struct cras_server_message;
* fd - Connection for client communication.
* ops - cras_rclient_ops for the cras_rclient.
* supported_directions - Bit mask for supported stream directions.
- * client_type - Client type of this rclient. If this is set to value other
- * than CRAS_CLIENT_TYPE_UNKNOWN, rclient will overwrite incoming
- * messages' client type.
*/
struct cras_rclient {
struct cras_observer_client *observer;
@@ -30,7 +27,6 @@ struct cras_rclient {
int fd;
const struct cras_rclient_ops *ops;
int supported_directions;
- enum CRAS_CLIENT_TYPE client_type;
};
/* Operations for cras_rclient.
diff --git a/cras/src/server/cras_rclient_util.c b/cras/src/server/cras_rclient_util.c
index 0af98863..c88df82e 100644
--- a/cras/src/server/cras_rclient_util.c
+++ b/cras/src/server/cras_rclient_util.c
@@ -12,7 +12,6 @@
#include "cras_rclient_util.h"
#include "cras_rstream.h"
#include "cras_server_metrics.h"
-#include "cras_system_state.h"
#include "cras_tm.h"
#include "cras_types.h"
#include "cras_util.h"
@@ -43,8 +42,9 @@ int rclient_validate_message_fds(const struct cras_server_message *msg,
goto error;
break;
case CRAS_SERVER_SET_AEC_DUMP:
- if (num_fds > 1)
+ if (num_fds != 1)
goto error;
+ syslog(LOG_ERR, "client msg for APM debug, fd %d", fds[0]);
break;
default:
if (num_fds > 0)
@@ -80,13 +80,6 @@ rclient_validate_stream_connect_message(const struct cras_rclient *client,
msg->direction, client->id);
return -EINVAL;
}
-
- if (!cras_validate_client_type(msg->client_type)) {
- syslog(LOG_ERR,
- "stream_connect: invalid stream client_type: %x for "
- "client: %zx.\n",
- msg->client_type, client->id);
- }
return 0;
}
@@ -140,15 +133,10 @@ int rclient_handle_client_stream_connect(struct cras_rclient *client,
struct cras_audio_format remote_fmt;
struct cras_rstream_config stream_config;
int rc, header_fd, samples_fd;
- size_t samples_size;
int stream_fds[2];
rc = rclient_validate_stream_connect_params(client, msg, aud_fd,
client_shm_fd);
- remote_fmt = unpack_cras_audio_format(&msg->format);
- if (rc == 0 && !cras_audio_format_valid(&remote_fmt)) {
- rc = -EINVAL;
- }
if (rc) {
if (client_shm_fd >= 0)
close(client_shm_fd);
@@ -157,40 +145,26 @@ int rclient_handle_client_stream_connect(struct cras_rclient *client,
goto reply_err;
}
+ unpack_cras_audio_format(&remote_fmt, &msg->format);
+
/* When full, getting an error is preferable to blocking. */
cras_make_fd_nonblocking(aud_fd);
- stream_config = cras_rstream_config_init_with_message(
- client, msg, &aud_fd, &client_shm_fd, &remote_fmt);
- /* Overwrite client_type if client->client_type is set. */
- if (client->client_type != CRAS_CLIENT_TYPE_UNKNOWN)
- stream_config.client_type = client->client_type;
+ cras_rstream_config_init_with_message(client, msg, &aud_fd,
+ &client_shm_fd, &remote_fmt,
+ &stream_config);
rc = stream_list_add(cras_iodev_list_get_stream_list(), &stream_config,
&stream);
if (rc)
goto cleanup_config;
- detect_rtc_stream_pair(cras_iodev_list_get_stream_list(), stream);
-
/* Tell client about the stream setup. */
syslog(LOG_DEBUG, "Send connected for stream %x\n", msg->stream_id);
-
- // Check that shm size is at most UINT32_MAX for non-shm streams.
- samples_size = cras_rstream_get_samples_shm_size(stream);
- if (samples_size > UINT32_MAX && stream_config.client_shm_fd < 0) {
- syslog(LOG_ERR,
- "Non client-provided shm stream has samples shm larger "
- "than uint32_t: %zu",
- samples_size);
- if (aud_fd >= 0)
- close(aud_fd);
- rc = -EINVAL;
- goto cleanup_config;
- }
- cras_fill_client_stream_connected(&stream_connected, 0, /* No error. */
- msg->stream_id, &remote_fmt,
- samples_size,
- cras_rstream_get_effects(stream));
+ cras_fill_client_stream_connected(
+ &stream_connected, 0, /* No error. */
+ msg->stream_id, &remote_fmt,
+ cras_rstream_get_samples_shm_size(stream),
+ cras_rstream_get_effects(stream));
reply = &stream_connected.header;
rc = cras_rstream_get_shm_fds(stream, &header_fd, &samples_fd);
@@ -210,6 +184,9 @@ int rclient_handle_client_stream_connect(struct cras_rclient *client,
goto cleanup_config;
}
+ /* Metrics logs the stream configurations. */
+ cras_server_metrics_stream_config(&stream_config);
+
/* Cleanup local object explicitly. */
cras_rstream_config_cleanup(&stream_config);
return 0;
@@ -243,74 +220,3 @@ int rclient_handle_client_stream_disconnect(
return stream_list_rm(cras_iodev_list_get_stream_list(),
msg->stream_id);
}
-
-/* Creates a client structure and sends a message back informing the client that
- * the connection has succeeded. */
-struct cras_rclient *rclient_generic_create(int fd, size_t id,
- const struct cras_rclient_ops *ops,
- int supported_directions)
-{
- struct cras_rclient *client;
- struct cras_client_connected msg;
- int state_fd;
-
- client = (struct cras_rclient *)calloc(1, sizeof(struct cras_rclient));
- if (!client)
- return NULL;
-
- client->fd = fd;
- client->id = id;
- client->ops = ops;
- client->supported_directions = supported_directions;
-
- cras_fill_client_connected(&msg, client->id);
- state_fd = cras_sys_state_shm_fd();
- client->ops->send_message_to_client(client, &msg.header, &state_fd, 1);
-
- return client;
-}
-
-/* A generic entry point for handling a message from the client. Called from
- * the main server context. */
-int rclient_handle_message_from_client(struct cras_rclient *client,
- const struct cras_server_message *msg,
- int *fds, unsigned int num_fds)
-{
- int rc = 0;
- assert(client && msg);
-
- rc = rclient_validate_message_fds(msg, fds, num_fds);
- if (rc < 0) {
- for (int i = 0; i < (int)num_fds; i++)
- if (fds[i] >= 0)
- close(fds[i]);
- return rc;
- }
- int fd = num_fds > 0 ? fds[0] : -1;
-
- switch (msg->id) {
- case CRAS_SERVER_CONNECT_STREAM: {
- int client_shm_fd = num_fds > 1 ? fds[1] : -1;
- if (MSG_LEN_VALID(msg, struct cras_connect_message)) {
- rclient_handle_client_stream_connect(
- client,
- (const struct cras_connect_message *)msg, fd,
- client_shm_fd);
- } else {
- return -EINVAL;
- }
- break;
- }
- case CRAS_SERVER_DISCONNECT_STREAM:
- if (!MSG_LEN_VALID(msg, struct cras_disconnect_stream_message))
- return -EINVAL;
- rclient_handle_client_stream_disconnect(
- client,
- (const struct cras_disconnect_stream_message *)msg);
- break;
- default:
- break;
- }
-
- return rc;
-}
diff --git a/cras/src/server/cras_rclient_util.h b/cras/src/server/cras_rclient_util.h
index 089c2ecb..4768a476 100644
--- a/cras/src/server/cras_rclient_util.h
+++ b/cras/src/server/cras_rclient_util.h
@@ -86,40 +86,30 @@ int rclient_handle_client_stream_disconnect(
struct cras_rclient *client,
const struct cras_disconnect_stream_message *msg);
-/* Generic rclient create function for different types of rclients.
- * Creates a client structure and sends a message back informing the client
- * that the connection has succeeded.
- *
- * Args:
- * fd - The file descriptor used for communication with the client.
- * id - Unique identifier for this client.
- * ops - cras_rclient_ops pointer for the client.
- * supported_directions - supported directions for the this rclient.
- * Returns:
- * A pointer to the newly created rclient on success, NULL on failure.
+/*
+ * Converts an old version of connect message to the correct
+ * cras_connect_message. Returns zero on success, negative on failure.
+ * Note that this is special check only for libcras transition in
+ * clients, from CRAS_PROTO_VER = 3 to 5.
+ * TODO(yuhsuan): clean up the function once clients transition is done.
*/
-struct cras_rclient *rclient_generic_create(int fd, size_t id,
- const struct cras_rclient_ops *ops,
- int supported_directions);
+static inline int
+convert_connect_message_old(const struct cras_server_message *msg,
+ struct cras_connect_message *cmsg)
+{
+ struct cras_connect_message_old *old;
-/* Generic handle_message_from_client function for different types of rlicnets.
- * Supports only stream connect and stream disconnect messages.
- *
- * If the message from clients has incorrect length (truncated message), return
- * an error up to CRAS server.
- * If the message from clients has invalid content, should return the errors to
- * clients by send_message_to_client and return 0 here.
- *
- * Args:
- * client - The cras_rclient which gets the message.
- * msg - The cras_server_message from client.
- * fds - The array for incoming fds from client.
- * num_fds - The number of fds from client.
- * Returns:
- * 0 on success, negative error on failure.
- */
-int rclient_handle_message_from_client(struct cras_rclient *client,
- const struct cras_server_message *msg,
- int *fds, unsigned int num_fds);
+ if (!MSG_LEN_VALID(msg, struct cras_connect_message_old))
+ return -EINVAL;
+
+ old = (struct cras_connect_message_old *)msg;
+ if (old->proto_version != 3 || CRAS_PROTO_VER != 5)
+ return -EINVAL;
+
+ memcpy(cmsg, old, sizeof(*old));
+ cmsg->client_type = CRAS_CLIENT_TYPE_LEGACY;
+ cmsg->client_shm_size = 0;
+ return 0;
+}
#endif /* CRAS_RCLIENT_UTIL_H_ */
diff --git a/cras/src/server/cras_rstream.c b/cras/src/server/cras_rstream.c
index 3c0a0ce3..55beed2b 100644
--- a/cras/src/server/cras_rstream.c
+++ b/cras/src/server/cras_rstream.c
@@ -17,20 +17,63 @@
#include "cras_server_metrics.h"
#include "cras_shm.h"
#include "cras_types.h"
+#include "buffer_share.h"
#include "cras_system_state.h"
-static bool cras_rstream_config_is_client_shm_stream(
- const struct cras_rstream_config *config)
+void cras_rstream_config_init(
+ struct cras_rclient *client, cras_stream_id_t stream_id,
+ enum CRAS_STREAM_TYPE stream_type, enum CRAS_CLIENT_TYPE client_type,
+ enum CRAS_STREAM_DIRECTION direction, uint32_t dev_idx, uint32_t flags,
+ uint32_t effects, const struct cras_audio_format *format,
+ size_t buffer_frames, size_t cb_threshold, int *audio_fd,
+ int *client_shm_fd, size_t client_shm_size,
+ struct cras_rstream_config *stream_config)
{
- return config && config->client_shm_fd >= 0 &&
- config->client_shm_size > 0;
+ stream_config->stream_id = stream_id;
+ stream_config->stream_type = stream_type;
+ stream_config->client_type = client_type;
+ stream_config->direction = direction;
+ stream_config->dev_idx = dev_idx;
+ stream_config->flags = flags;
+ stream_config->effects = effects;
+ stream_config->format = format;
+ stream_config->buffer_frames = buffer_frames;
+ stream_config->cb_threshold = cb_threshold;
+ stream_config->audio_fd = *audio_fd;
+ *audio_fd = -1;
+ stream_config->client_shm_fd = *client_shm_fd;
+ *client_shm_fd = -1;
+ stream_config->client_shm_size = client_shm_size;
+ stream_config->client = client;
}
-/* Setup the shared memory area used for audio samples. config->client_shm_fd
- * must be closed after calling this function.
+void cras_rstream_config_init_with_message(
+ struct cras_rclient *client, const struct cras_connect_message *msg,
+ int *aud_fd, int *client_shm_fd,
+ const struct cras_audio_format *remote_fmt,
+ struct cras_rstream_config *stream_config)
+{
+ cras_rstream_config_init(client, msg->stream_id, msg->stream_type,
+ msg->client_type, msg->direction, msg->dev_idx,
+ msg->flags, msg->effects, remote_fmt,
+ msg->buffer_frames, msg->cb_threshold, aud_fd,
+ client_shm_fd, msg->client_shm_size,
+ stream_config);
+}
+
+void cras_rstream_config_cleanup(struct cras_rstream_config *stream_config)
+{
+ if (stream_config->audio_fd >= 0)
+ close(stream_config->audio_fd);
+ if (stream_config->client_shm_fd >= 0)
+ close(stream_config->client_shm_fd);
+}
+
+/* Setup the shared memory area used for audio samples. client_shm_fd must be
+ * closed after calling this function.
*/
-static inline int setup_shm_area(struct cras_rstream *stream,
- struct cras_rstream_config *config)
+static inline int setup_shm_area(struct cras_rstream *stream, int client_shm_fd,
+ size_t client_shm_size)
{
const struct cras_audio_format *fmt = &stream->format;
char header_name[NAME_MAX];
@@ -38,8 +81,6 @@ static inline int setup_shm_area(struct cras_rstream *stream,
struct cras_shm_info header_info, samples_info;
uint32_t frame_bytes, used_size;
int rc;
- bool client_shm_stream =
- cras_rstream_config_is_client_shm_stream(config);
if (stream->shm) {
/* already setup */
@@ -58,9 +99,8 @@ static inline int setup_shm_area(struct cras_rstream *stream,
fmt->num_channels;
used_size = stream->buffer_frames * frame_bytes;
- if (client_shm_stream) {
- rc = cras_shm_info_init_with_fd(config->client_shm_fd,
- config->client_shm_size,
+ if (client_shm_fd >= 0 && client_shm_size > 0) {
+ rc = cras_shm_info_init_with_fd(client_shm_fd, client_shm_size,
&samples_info);
} else {
snprintf(samples_name, sizeof(samples_name),
@@ -89,11 +129,6 @@ static inline int setup_shm_area(struct cras_rstream *stream,
cras_shm_set_frame_bytes(stream->shm, frame_bytes);
cras_shm_set_used_size(stream->shm, used_size);
- if (client_shm_stream) {
- for (int i = 0; i < 2; i++)
- cras_shm_set_buffer_offset(stream->shm, i,
- config->buffer_offsets[i]);
- }
stream->audio_area =
cras_audio_area_create(stream->format.num_channels);
@@ -104,16 +139,23 @@ static inline int setup_shm_area(struct cras_rstream *stream,
static inline int buffer_meets_size_limit(size_t buffer_size, size_t rate)
{
- return (buffer_size < (CRAS_MAX_BUFFER_TIME_IN_S * rate)) &&
- (buffer_size > (CRAS_MIN_BUFFER_TIME_IN_US * rate) / 1000000);
+ return buffer_size > (CRAS_MIN_BUFFER_TIME_IN_US * rate) / 1000000;
}
/* Verifies that the given stream parameters are valid. */
-static int verify_rstream_parameters(const struct cras_rstream_config *config,
- struct cras_rstream *const *stream_out)
+static int verify_rstream_parameters(enum CRAS_STREAM_DIRECTION direction,
+ const struct cras_audio_format *format,
+ enum CRAS_STREAM_TYPE stream_type,
+ size_t buffer_frames, size_t cb_threshold,
+ int client_shm_fd, size_t client_shm_size,
+ struct cras_rclient *client,
+ struct cras_rstream **stream_out)
{
- const struct cras_audio_format *format = config->format;
-
+ if (!buffer_meets_size_limit(buffer_frames, format->frame_rate)) {
+ syslog(LOG_ERR, "rstream: invalid buffer_frames %zu\n",
+ buffer_frames);
+ return -EINVAL;
+ }
if (stream_out == NULL) {
syslog(LOG_ERR, "rstream: stream_out can't be NULL\n");
return -EINVAL;
@@ -122,33 +164,6 @@ static int verify_rstream_parameters(const struct cras_rstream_config *config,
syslog(LOG_ERR, "rstream: format can't be NULL\n");
return -EINVAL;
}
- if (format->frame_rate < 4000 || format->frame_rate > 192000) {
- syslog(LOG_ERR, "rstream: invalid frame_rate %zu\n",
- format->frame_rate);
- return -EINVAL;
- }
- /*
- * Valid buffer settings:
- * Frames in 1ms <= cb_threshold <= buffer_frames <= Frames in 10s.
- */
- if (!buffer_meets_size_limit(config->buffer_frames,
- format->frame_rate)) {
- syslog(LOG_ERR, "rstream: invalid buffer_frames %zu\n",
- config->buffer_frames);
- return -EINVAL;
- }
- if (!buffer_meets_size_limit(config->cb_threshold,
- format->frame_rate) ||
- config->cb_threshold > config->buffer_frames) {
- syslog(LOG_ERR, "rstream: invalid cb_threshold %zu\n",
- config->cb_threshold);
- return -EINVAL;
- }
- if (format->num_channels < 0 || format->num_channels > CRAS_CH_MAX) {
- syslog(LOG_ERR, "rstream: invalid num_channels %zu\n",
- format->num_channels);
- return -EINVAL;
- }
if ((format->format != SND_PCM_FORMAT_S16_LE) &&
(format->format != SND_PCM_FORMAT_S32_LE) &&
(format->format != SND_PCM_FORMAT_U8) &&
@@ -157,34 +172,24 @@ static int verify_rstream_parameters(const struct cras_rstream_config *config,
format->format);
return -EINVAL;
}
- if (config->direction != CRAS_STREAM_OUTPUT &&
- config->direction != CRAS_STREAM_INPUT) {
+ if (direction != CRAS_STREAM_OUTPUT && direction != CRAS_STREAM_INPUT) {
syslog(LOG_ERR, "rstream: Invalid direction.\n");
return -EINVAL;
}
- if (config->stream_type < CRAS_STREAM_TYPE_DEFAULT ||
- config->stream_type >= CRAS_STREAM_NUM_TYPES) {
+ if (stream_type < CRAS_STREAM_TYPE_DEFAULT ||
+ stream_type >= CRAS_STREAM_NUM_TYPES) {
syslog(LOG_ERR, "rstream: Invalid stream type.\n");
return -EINVAL;
}
- if (config->client_type < CRAS_CLIENT_TYPE_UNKNOWN ||
- config->client_type >= CRAS_NUM_CLIENT_TYPE) {
- syslog(LOG_ERR, "rstream: Invalid client type.\n");
+ if (!buffer_meets_size_limit(cb_threshold, format->frame_rate)) {
+ syslog(LOG_ERR, "rstream: cb_threshold too low\n");
return -EINVAL;
}
- if ((config->client_shm_size > 0 && config->client_shm_fd < 0) ||
- (config->client_shm_size == 0 && config->client_shm_fd >= 0)) {
+ if ((client_shm_size > 0 && client_shm_fd < 0) ||
+ (client_shm_size == 0 && client_shm_fd >= 0)) {
syslog(LOG_ERR, "rstream: invalid client-provided shm info\n");
return -EINVAL;
}
- if (cras_rstream_config_is_client_shm_stream(config) &&
- (config->buffer_offsets[0] > config->client_shm_size ||
- config->buffer_offsets[1] > config->client_shm_size)) {
- syslog(LOG_ERR,
- "rstream: initial buffer offsets are outside shm area\n");
- return -EINVAL;
- }
-
return 0;
}
@@ -243,6 +248,7 @@ static int read_and_handle_client_message(struct cras_rstream *stream)
rc = get_audio_request_reply(stream, &msg);
if (rc <= 0) {
+ syslog(LOG_ERR, "Got error from client: rc: %d", rc);
clear_pending_reply(stream);
return rc;
}
@@ -274,7 +280,11 @@ int cras_rstream_create(struct cras_rstream_config *config,
struct cras_rstream *stream;
int rc;
- rc = verify_rstream_parameters(config, stream_out);
+ rc = verify_rstream_parameters(
+ config->direction, config->format, config->stream_type,
+ config->buffer_frames, config->cb_threshold,
+ config->client_shm_fd, config->client_shm_size, config->client,
+ stream_out);
if (rc < 0)
return rc;
@@ -292,14 +302,14 @@ int cras_rstream_create(struct cras_rstream_config *config,
stream->cb_threshold = config->cb_threshold;
stream->client = config->client;
stream->shm = NULL;
- stream->main_dev.dev_id = NO_DEVICE;
- stream->main_dev.dev_ptr = NULL;
+ stream->master_dev.dev_id = NO_DEVICE;
+ stream->master_dev.dev_ptr = NULL;
stream->num_missed_cb = 0;
stream->is_pinned = (config->dev_idx != NO_DEVICE);
stream->pinned_dev_idx = config->dev_idx;
- ewma_power_init(&stream->ewma, stream->format.frame_rate);
- rc = setup_shm_area(stream, config);
+ rc = setup_shm_area(stream, config->client_shm_fd,
+ config->client_shm_size);
if (rc < 0) {
syslog(LOG_ERR, "failed to setup shm %d\n", rc);
free(stream);
@@ -318,20 +328,17 @@ int cras_rstream_create(struct cras_rstream_config *config,
config->stream_id, config->buffer_frames, config->cb_threshold);
*stream_out = stream;
- cras_system_state_stream_added(stream->direction, stream->client_type);
+ cras_system_state_stream_added(stream->direction);
clock_gettime(CLOCK_MONOTONIC_RAW, &stream->start_ts);
- cras_server_metrics_stream_create(config);
-
return 0;
}
void cras_rstream_destroy(struct cras_rstream *stream)
{
- cras_server_metrics_stream_destroy(stream);
- cras_system_state_stream_removed(stream->direction,
- stream->client_type);
+ cras_server_metrics_missed_cb_frequency(stream);
+ cras_system_state_stream_removed(stream->direction);
close(stream->fd);
cras_audio_shm_destroy(stream->shm);
cras_audio_area_destroy(stream->audio_area);
@@ -353,7 +360,10 @@ cras_rstream_post_processing_format(const struct cras_rstream *stream,
{
struct cras_apm *apm;
- apm = cras_apm_list_get_active_apm((void *)stream, dev_ptr);
+ if (NULL == stream->apm_list)
+ return NULL;
+
+ apm = cras_apm_list_get(stream->apm_list, dev_ptr);
if (NULL == apm)
return NULL;
return cras_apm_list_get_format(apm);
@@ -431,12 +441,12 @@ void cras_rstream_dev_attach(struct cras_rstream *rstream, unsigned int dev_id,
if (buffer_share_add_id(rstream->buf_state, dev_id, dev_ptr) == 0)
rstream->num_attached_devs++;
- /* TODO(hychao): Handle main device assignment for complicated
+ /* TODO(hychao): Handle master device assignment for complicated
* routing case.
*/
- if (rstream->main_dev.dev_id == NO_DEVICE) {
- rstream->main_dev.dev_id = dev_id;
- rstream->main_dev.dev_ptr = dev_ptr;
+ if (rstream->master_dev.dev_id == NO_DEVICE) {
+ rstream->master_dev.dev_id = dev_id;
+ rstream->master_dev.dev_ptr = dev_ptr;
}
}
@@ -445,18 +455,18 @@ void cras_rstream_dev_detach(struct cras_rstream *rstream, unsigned int dev_id)
if (buffer_share_rm_id(rstream->buf_state, dev_id) == 0)
rstream->num_attached_devs--;
- if (rstream->main_dev.dev_id == dev_id) {
+ if (rstream->master_dev.dev_id == dev_id) {
int i;
struct id_offset *o;
- /* Choose the first device id as a main device. */
- rstream->main_dev.dev_id = NO_DEVICE;
- rstream->main_dev.dev_ptr = NULL;
+ /* Choose the first device id as master. */
+ rstream->master_dev.dev_id = NO_DEVICE;
+ rstream->master_dev.dev_ptr = NULL;
for (i = 0; i < rstream->buf_state->id_sz; i++) {
o = &rstream->buf_state->wr_idx[i];
if (o->used) {
- rstream->main_dev.dev_id = o->id;
- rstream->main_dev.dev_ptr = o->data;
+ rstream->master_dev.dev_id = o->id;
+ rstream->master_dev.dev_ptr = o->data;
break;
}
}
@@ -479,16 +489,9 @@ void cras_rstream_update_input_write_pointer(struct cras_rstream *rstream)
void cras_rstream_update_output_read_pointer(struct cras_rstream *rstream)
{
- size_t nfr = 0;
- uint8_t *src;
unsigned int nwritten =
buffer_share_get_new_write_point(rstream->buf_state);
- /* Retrieve the read pointer |src| start from which to calculate
- * the EWMA power. */
- src = cras_shm_get_readable_frames(rstream->shm, 0, &nfr);
- ewma_power_calculate(&rstream->ewma, (int16_t *)src,
- rstream->format.num_channels, nwritten);
cras_shm_buffer_read(rstream->shm, nwritten);
}
@@ -553,8 +556,5 @@ int cras_rstream_flush_old_audio_messages(struct cras_rstream *stream)
}
} while (err > 0);
- if (err < 0)
- syslog(LOG_ERR, "Error reading msg from client: rc: %d", err);
-
return 0;
}
diff --git a/cras/src/server/cras_rstream.h b/cras/src/server/cras_rstream.h
index d57c13be..3329fe0c 100644
--- a/cras/src/server/cras_rstream.h
+++ b/cras/src/server/cras_rstream.h
@@ -9,23 +9,20 @@
#ifndef CRAS_RSTREAM_H_
#define CRAS_RSTREAM_H_
-#include "buffer_share.h"
#include "cras_apm_list.h"
#include "cras_shm.h"
#include "cras_types.h"
-#include "cras_rstream_config.h"
-#include "ewma_power.h"
struct cras_connect_message;
struct cras_rclient;
struct dev_mix;
-/* Holds informations about the main active device.
+/* Holds informations about the master active device.
* Members:
- * dev_id - id of the main device.
- * dev_ptr - pointer to the main device.
+ * dev_id - id of the master device.
+ * dev_ptr - pointer to the master device.
*/
-struct main_dev_info {
+struct master_dev_info {
int dev_id;
void *dev_ptr;
};
@@ -42,7 +39,7 @@ struct main_dev_info {
* fd - Socket for requesting and sending audio buffer events.
* buffer_frames - Buffer size in frames.
* cb_threshold - Callback client when this much is left.
- * main_dev_info - The info of the main device this stream attaches to.
+ * master_dev_info - The info of the master device this stream attaches to.
* is_draining - The stream is draining and waiting to be removed.
* client - The client who uses this stream.
* shm - shared memory
@@ -56,7 +53,6 @@ struct main_dev_info {
* first_missed_cb_ts - The time when the first missed callback happens.
* buf_state - State of the buffer from all devices for this stream.
* apm_list - List of audio processing module instances.
- * ewma - The ewma instance to calculate stream volume.
* num_attached_devs - Number of iodevs this stream has attached to.
* num_missed_cb - Number of callback schedules have been missed.
* queued_frames - Cached value of the number of queued frames in shm.
@@ -74,7 +70,7 @@ struct cras_rstream {
size_t buffer_frames;
size_t cb_threshold;
int is_draining;
- struct main_dev_info main_dev;
+ struct master_dev_info master_dev;
struct cras_rclient *client;
struct cras_audio_shm *shm;
struct cras_audio_area *audio_area;
@@ -87,7 +83,6 @@ struct cras_rstream {
struct timespec first_missed_cb_ts;
struct buffer_share *buf_state;
struct cras_apm_list *apm_list;
- struct ewma_power ewma;
int num_attached_devs;
int num_missed_cb;
int queued_frames;
@@ -97,6 +92,85 @@ struct cras_rstream {
struct cras_rstream *prev, *next;
};
+/* Config for creating an rstream.
+ * stream_type - CRAS_STREAM_TYPE.
+ * client_type - CRAS_CLIENT_TYPE.
+ * direction - CRAS_STREAM_OUTPUT or CRAS_STREAM_INPUT.
+ * dev_idx - Pin to this device if != NO_DEVICE.
+ * flags - Any special handling for this stream.
+ * effects - Bit map of effects to be enabled on this stream.
+ * format - The audio format the stream wishes to use.
+ * buffer_frames - Total number of audio frames to buffer.
+ * cb_threshold - # of frames when to request more from the client.
+ * audio_fd - The fd to read/write audio signals to. May be -1 for server
+ * stream. Some functions may mutably borrow the config and move
+ * the fd ownership.
+ * client_shm_fd - The shm fd to use to back the samples area. May be -1.
+ * Some functions may dup this fd while borrowing the config.
+ * client_shm_size - The size of shm area backed by client_shm_fd.
+ * client - The client that owns this stream.
+ */
+struct cras_rstream_config {
+ cras_stream_id_t stream_id;
+ enum CRAS_STREAM_TYPE stream_type;
+ enum CRAS_CLIENT_TYPE client_type;
+ enum CRAS_STREAM_DIRECTION direction;
+ uint32_t dev_idx;
+ uint32_t flags;
+ uint32_t effects;
+ const struct cras_audio_format *format;
+ size_t buffer_frames;
+ size_t cb_threshold;
+ int audio_fd;
+ int client_shm_fd;
+ size_t client_shm_size;
+ struct cras_rclient *client;
+};
+
+/* Fills cras_rstream_config with given parameters.
+ *
+ * Args:
+ * audio_fd - The audio fd pointer from client. Its ownership will be moved to
+ * stream_config.
+ * client_shm_fd - The shared memory fd pointer for samples from client. Its
+ * ownership will be moved to stream_config.
+ * Other args - See comments in struct cras_rstream_config.
+ */
+void cras_rstream_config_init(
+ struct cras_rclient *client, cras_stream_id_t stream_id,
+ enum CRAS_STREAM_TYPE stream_type, enum CRAS_CLIENT_TYPE client_type,
+ enum CRAS_STREAM_DIRECTION direction, uint32_t dev_idx, uint32_t flags,
+ uint32_t effects, const struct cras_audio_format *format,
+ size_t buffer_frames, size_t cb_threshold, int *audio_fd,
+ int *client_shm_fd, size_t client_shm_size,
+ struct cras_rstream_config *stream_config);
+
+/* Fills cras_rstream_config with given parameters and a cras_connect_message.
+ *
+ * Args:
+ * client - The rclient which handles the connect message.
+ * msg - The cras_connect_message from client.
+ * aud_fd - The audio fd pointer from client. Its ownership will be moved to
+ * stream_config.
+ * client_shm_fd - The shared memory fd pointer for samples from client. Its
+ * ownership will be moved to stream_config.
+ * remote_format - The remote_format for the config.
+ * stream_config - The cras_rstream_config to be filled.
+ */
+void cras_rstream_config_init_with_message(
+ struct cras_rclient *client, const struct cras_connect_message *msg,
+ int *aud_fd, int *client_shm_fd,
+ const struct cras_audio_format *remote_format,
+ struct cras_rstream_config *stream_config);
+
+/* Cleans up given cras_rstream_config. All fds inside the config will be
+ * closed.
+ *
+ * Args:
+ * stream_config - The config to be cleaned up.
+ */
+void cras_rstream_config_cleanup(struct cras_rstream_config *stream_config);
+
/* Creates an rstream.
* Args:
* config - Params for configuration of the new rstream. It's a mutable
@@ -260,12 +334,6 @@ void cras_rstream_dev_attach(struct cras_rstream *rstream, unsigned int dev_id,
void *dev_ptr);
void cras_rstream_dev_detach(struct cras_rstream *rstream, unsigned int dev_id);
-static inline void *cras_rstream_dev_ptr(struct cras_rstream *rstream,
- unsigned int dev_id)
-{
- return buffer_share_get_data(rstream->buf_state, dev_id);
-}
-
/* A device using this stream has read or written samples. */
void cras_rstream_dev_offset_update(struct cras_rstream *rstream,
unsigned int frames, unsigned int dev_id);
diff --git a/cras/src/server/cras_rstream_config.c b/cras/src/server/cras_rstream_config.c
deleted file mode 100644
index c5cd9c57..00000000
--- a/cras/src/server/cras_rstream_config.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <fcntl.h>
-#include <stdint.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <syslog.h>
-
-#include "cras_audio_area.h"
-#include "cras_config.h"
-#include "cras_messages.h"
-#include "cras_rclient.h"
-#include "cras_rstream.h"
-#include "cras_rstream_config.h"
-#include "cras_server_metrics.h"
-#include "cras_shm.h"
-#include "cras_types.h"
-#include "cras_system_state.h"
-
-void cras_rstream_config_init(
- struct cras_rclient *client, cras_stream_id_t stream_id,
- enum CRAS_STREAM_TYPE stream_type, enum CRAS_CLIENT_TYPE client_type,
- enum CRAS_STREAM_DIRECTION direction, uint32_t dev_idx, uint32_t flags,
- uint32_t effects, const struct cras_audio_format *format,
- size_t buffer_frames, size_t cb_threshold, int *audio_fd,
- int *client_shm_fd, size_t client_shm_size,
- const uint64_t buffer_offsets[2],
- struct cras_rstream_config *stream_config)
-{
- stream_config->stream_id = stream_id;
- stream_config->stream_type = stream_type;
- stream_config->client_type = client_type;
- stream_config->direction = direction;
- stream_config->dev_idx = dev_idx;
- stream_config->flags = flags;
- stream_config->effects = effects;
- stream_config->format = format;
- stream_config->buffer_frames = buffer_frames;
- stream_config->cb_threshold = cb_threshold;
- stream_config->audio_fd = *audio_fd;
- *audio_fd = -1;
- stream_config->client_shm_fd = *client_shm_fd;
- *client_shm_fd = -1;
- stream_config->client_shm_size = client_shm_size;
- stream_config->buffer_offsets[0] = buffer_offsets[0];
- stream_config->buffer_offsets[1] = buffer_offsets[1];
- stream_config->client = client;
-}
-
-struct cras_rstream_config cras_rstream_config_init_with_message(
- struct cras_rclient *client, const struct cras_connect_message *msg,
- int *aud_fd, int *client_shm_fd,
- const struct cras_audio_format *remote_fmt)
-{
- struct cras_rstream_config stream_config;
-
- const uint64_t buffer_offsets[2] = { msg->buffer_offsets[0],
- msg->buffer_offsets[1] };
- cras_rstream_config_init(client, msg->stream_id, msg->stream_type,
- msg->client_type, msg->direction, msg->dev_idx,
- msg->flags, msg->effects, remote_fmt,
- msg->buffer_frames, msg->cb_threshold, aud_fd,
- client_shm_fd, msg->client_shm_size,
- buffer_offsets, &stream_config);
- return stream_config;
-}
-
-void cras_rstream_config_cleanup(struct cras_rstream_config *stream_config)
-{
- if (stream_config->audio_fd >= 0)
- close(stream_config->audio_fd);
- if (stream_config->client_shm_fd >= 0)
- close(stream_config->client_shm_fd);
-}
diff --git a/cras/src/server/cras_rstream_config.h b/cras/src/server/cras_rstream_config.h
deleted file mode 100644
index 4d3713ce..00000000
--- a/cras/src/server/cras_rstream_config.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * Remote Stream Configuration
- */
-#ifndef CRAS_RSTREAM_CONFIG_H_
-#define CRAS_RSTREAM_CONFIG_H_
-
-#include "buffer_share.h"
-#include "cras_shm.h"
-#include "cras_types.h"
-
-struct cras_connect_message;
-struct dev_mix;
-
-/* Config for creating an rstream.
- * stream_type - CRAS_STREAM_TYPE.
- * client_type - CRAS_CLIENT_TYPE.
- * direction - CRAS_STREAM_OUTPUT or CRAS_STREAM_INPUT.
- * dev_idx - Pin to this device if != NO_DEVICE.
- * flags - Any special handling for this stream.
- * effects - Bit map of effects to be enabled on this stream.
- * format - The audio format the stream wishes to use.
- * buffer_frames - Total number of audio frames to buffer.
- * cb_threshold - # of frames when to request more from the client.
- * audio_fd - The fd to read/write audio signals to. May be -1 for server
- * stream. Some functions may mutably borrow the config and move
- * the fd ownership.
- * client_shm_fd - The shm fd to use to back the samples area. May be -1.
- * Some functions may dup this fd while borrowing the config.
- * client_shm_size - The size of shm area backed by client_shm_fd.
- * buffer_offsets - Initial values for buffer_offset for a client shm stream.
- * client - The client that owns this stream.
- */
-struct cras_rstream_config {
- cras_stream_id_t stream_id;
- enum CRAS_STREAM_TYPE stream_type;
- enum CRAS_CLIENT_TYPE client_type;
- enum CRAS_STREAM_DIRECTION direction;
- uint32_t dev_idx;
- uint32_t flags;
- uint32_t effects;
- const struct cras_audio_format *format;
- size_t buffer_frames;
- size_t cb_threshold;
- int audio_fd;
- int client_shm_fd;
- size_t client_shm_size;
- uint32_t buffer_offsets[2];
- struct cras_rclient *client;
-};
-
-/* Fills cras_rstream_config with given parameters.
- *
- * Args:
- * audio_fd - The audio fd pointer from client. Its ownership will be moved to
- * stream_config.
- * client_shm_fd - The shared memory fd pointer for samples from client. Its
- * ownership will be moved to stream_config.
- * Other args - See comments in struct cras_rstream_config.
- */
-void cras_rstream_config_init(
- struct cras_rclient *client, cras_stream_id_t stream_id,
- enum CRAS_STREAM_TYPE stream_type, enum CRAS_CLIENT_TYPE client_type,
- enum CRAS_STREAM_DIRECTION direction, uint32_t dev_idx, uint32_t flags,
- uint32_t effects, const struct cras_audio_format *format,
- size_t buffer_frames, size_t cb_threshold, int *audio_fd,
- int *client_shm_fd, size_t client_shm_size,
- const uint64_t buffer_offsets[2],
- struct cras_rstream_config *stream_config);
-
-/* Fills cras_rstream_config with given parameters and a cras_connect_message.
- *
- * Args:
- * client - The rclient which handles the connect message.
- * msg - The cras_connect_message from client.
- * aud_fd - The audio fd pointer from client. Its ownership will be moved to
- * stream_config.
- * client_shm_fd - The shared memory fd pointer for samples from client. Its
- * ownership will be moved to stream_config.
- * remote_format - The remote_format for the config.
- *
- * Returns a cras_rstream_config struct filled in with params from the message.
- */
-struct cras_rstream_config cras_rstream_config_init_with_message(
- struct cras_rclient *client, const struct cras_connect_message *msg,
- int *aud_fd, int *client_shm_fd,
- const struct cras_audio_format *remote_format);
-
-/* Cleans up given cras_rstream_config. All fds inside the config will be
- * closed.
- *
- * Args:
- * stream_config - The config to be cleaned up.
- */
-void cras_rstream_config_cleanup(struct cras_rstream_config *stream_config);
-
-#endif /* CRAS_RSTREAM_CONFIG_H_ */
diff --git a/cras/src/server/cras_server.c b/cras/src/server/cras_server.c
index 5f2ce632..97c83dfd 100644
--- a/cras/src/server/cras_server.c
+++ b/cras/src/server/cras_server.c
@@ -79,18 +79,16 @@ struct attached_client {
* to watch file descriptors. The client can then read or write the fd.
* Members:
* fd - The file descriptor passed to select.
- * callback - The funciton to call when fd is ready.
+ * callack - The funciton to call when fd is ready.
* callback_data - Pointer passed to the callback.
* pollfd - Pointer to struct pollfd for this callback.
- * events - The events to poll for.
*/
struct client_callback {
int select_fd;
- void (*callback)(void *data, int revents);
+ void (*callback)(void *);
void *callback_data;
struct pollfd *pollfd;
int deleted;
- int events;
struct client_callback *prev, *next;
};
@@ -279,8 +277,8 @@ error:
/* Add a file descriptor to be passed to select in the main loop. This is
* registered with system state so that it is called when any client asks to
* have a callback triggered based on an fd being readable. */
-static int add_select_fd(int fd, void (*cb)(void *data, int events),
- void *callback_data, int events, void *server_data)
+static int add_select_fd(int fd, void (*cb)(void *data), void *callback_data,
+ void *server_data)
{
struct client_callback *new_cb;
struct client_callback *client_cb;
@@ -303,7 +301,6 @@ static int add_select_fd(int fd, void (*cb)(void *data, int events),
new_cb->callback = cb;
new_cb->callback_data = callback_data;
new_cb->deleted = 0;
- new_cb->events = events;
new_cb->pollfd = NULL;
DL_APPEND(serv->client_callbacks, new_cb);
@@ -477,7 +474,7 @@ int cras_server_init()
* Returns 0 on success and leaves the created fd and the address information
* in server_socket.
* When error occurs, the created fd will be closed and the file path will be
- * unlinked and returns negative error code.
+ * unlinked.
*/
static int create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,
struct server_socket *server_socket)
@@ -511,7 +508,7 @@ static int create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,
sizeof(struct sockaddr_un));
if (rc < 0) {
syslog(LOG_ERR, "Bind to server socket failed.");
- rc = -errno;
+ rc = errno;
goto error;
}
@@ -522,7 +519,7 @@ static int create_and_listen_server_socket(enum CRAS_CONNECTION_TYPE conn_type,
if (listen(socket_fd, 5) != 0) {
syslog(LOG_ERR, "Listen on server socket failed.");
- rc = -errno;
+ rc = errno;
goto error;
}
@@ -644,7 +641,7 @@ int cras_server_run(unsigned int profile_disable_mask)
if (client_cb->deleted)
continue;
pollfds[num_pollfds].fd = client_cb->select_fd;
- pollfds[num_pollfds].events = client_cb->events;
+ pollfds[num_pollfds].events = POLLIN;
client_cb->pollfd = &pollfds[num_pollfds];
num_pollfds++;
}
@@ -690,9 +687,8 @@ int cras_server_run(unsigned int profile_disable_mask)
/* Check any client-registered fd/callback pairs. */
DL_FOREACH (server_instance.client_callbacks, client_cb)
if (!client_cb->deleted && client_cb->pollfd &&
- (client_cb->pollfd->revents & client_cb->events))
- client_cb->callback(client_cb->callback_data,
- client_cb->pollfd->revents);
+ (client_cb->pollfd->revents & POLLIN))
+ client_cb->callback(client_cb->callback_data);
cleanup_select_fds(&server_instance);
@@ -717,4 +713,4 @@ void cras_server_send_to_all_clients(const struct cras_client_message *msg)
DL_FOREACH (server_instance.clients_head, client)
cras_rclient_send_message(client->client, msg, NULL, 0);
-}
+} \ No newline at end of file
diff --git a/cras/src/server/cras_server_metrics.c b/cras/src/server/cras_server_metrics.c
index 7e487107..5f51e83e 100644
--- a/cras/src/server/cras_server_metrics.c
+++ b/cras/src/server/cras_server_metrics.c
@@ -16,18 +16,13 @@
#include "cras_metrics.h"
#include "cras_main_message.h"
#include "cras_rstream.h"
-#include "cras_server_metrics.h"
#include "cras_system_state.h"
-#define METRICS_NAME_BUFFER_SIZE 100
+#define METRICS_NAME_BUFFER_SIZE 50
const char kBusyloop[] = "Cras.Busyloop";
-const char kBusyloopLength[] = "Cras.BusyloopLength";
const char kDeviceTypeInput[] = "Cras.DeviceTypeInput";
const char kDeviceTypeOutput[] = "Cras.DeviceTypeOutput";
-const char kDeviceGain[] = "Cras.DeviceGain";
-const char kDeviceVolume[] = "Cras.DeviceVolume";
-const char kFetchDelayMilliSeconds[] = "Cras.FetchDelayMilliSeconds";
const char kHighestDeviceDelayInput[] = "Cras.HighestDeviceDelayInput";
const char kHighestDeviceDelayOutput[] = "Cras.HighestDeviceDelayOutput";
const char kHighestInputHardwareLevel[] = "Cras.HighestInputHardwareLevel";
@@ -49,23 +44,16 @@ const char kMissedCallbackSecondTimeInput[] =
const char kMissedCallbackSecondTimeOutput[] =
"Cras.MissedCallbackSecondTimeOutput";
const char kNoCodecsFoundMetric[] = "Cras.NoCodecsFoundAtBoot";
+const char kStreamTimeoutMilliSeconds[] = "Cras.StreamTimeoutMilliSeconds";
const char kStreamCallbackThreshold[] = "Cras.StreamCallbackThreshold";
const char kStreamClientTypeInput[] = "Cras.StreamClientTypeInput";
const char kStreamClientTypeOutput[] = "Cras.StreamClientTypeOutput";
const char kStreamFlags[] = "Cras.StreamFlags";
-const char kStreamEffects[] = "Cras.StreamEffects";
-const char kStreamRuntime[] = "Cras.StreamRuntime";
const char kStreamSamplingFormat[] = "Cras.StreamSamplingFormat";
const char kStreamSamplingRate[] = "Cras.StreamSamplingRate";
const char kUnderrunsPerDevice[] = "Cras.UnderrunsPerDevice";
-const char kHfpScoConnectionError[] = "Cras.HfpScoConnectionError";
-const char kHfpBatteryIndicatorSupported[] =
- "Cras.HfpBatteryIndicatorSupported";
-const char kHfpBatteryReport[] = "Cras.HfpBatteryReport";
const char kHfpWidebandSpeechSupported[] = "Cras.HfpWidebandSpeechSupported";
const char kHfpWidebandSpeechPacketLoss[] = "Cras.HfpWidebandSpeechPacketLoss";
-const char kHfpWidebandSpeechSelectedCodec[] =
- "Cras.kHfpWidebandSpeechSelectedCodec";
/*
* Records missed callback frequency only when the runtime of stream is larger
@@ -87,17 +75,10 @@ static const char *get_timespec_period_str(struct timespec ts)
/* Type of metrics to log. */
enum CRAS_SERVER_METRICS_TYPE {
- BT_BATTERY_INDICATOR_SUPPORTED,
- BT_BATTERY_REPORT,
- BT_SCO_CONNECTION_ERROR,
BT_WIDEBAND_PACKET_LOSS,
BT_WIDEBAND_SUPPORTED,
- BT_WIDEBAND_SELECTED_CODEC,
BUSYLOOP,
- BUSYLOOP_LENGTH,
- DEVICE_GAIN,
DEVICE_RUNTIME,
- DEVICE_VOLUME,
HIGHEST_DEVICE_DELAY_INPUT,
HIGHEST_DEVICE_DELAY_OUTPUT,
HIGHEST_INPUT_HW_LEVEL,
@@ -112,8 +93,7 @@ enum CRAS_SERVER_METRICS_TYPE {
MISSED_CB_SECOND_TIME_INPUT,
MISSED_CB_SECOND_TIME_OUTPUT,
NUM_UNDERRUNS,
- STREAM_CONFIG,
- STREAM_RUNTIME
+ STREAM_CONFIG
};
enum CRAS_METRICS_DEVICE_TYPE {
@@ -138,21 +118,17 @@ enum CRAS_METRICS_DEVICE_TYPE {
CRAS_METRICS_DEVICE_HFP,
CRAS_METRICS_DEVICE_HSP,
CRAS_METRICS_DEVICE_BLUETOOTH,
- CRAS_METRICS_DEVICE_BLUETOOTH_NB_MIC,
CRAS_METRICS_DEVICE_NO_DEVICE,
CRAS_METRICS_DEVICE_NORMAL_FALLBACK,
CRAS_METRICS_DEVICE_ABNORMAL_FALLBACK,
CRAS_METRICS_DEVICE_SILENT_HOTWORD,
CRAS_METRICS_DEVICE_UNKNOWN,
- CRAS_METRICS_DEVICE_BLUETOOTH_WB_MIC,
- CRAS_METRICS_DEVICE_ALSA_LOOPBACK,
};
struct cras_server_metrics_stream_config {
enum CRAS_STREAM_DIRECTION direction;
unsigned cb_threshold;
unsigned flags;
- unsigned effects;
int format;
unsigned rate;
enum CRAS_CLIENT_TYPE client_type;
@@ -162,14 +138,6 @@ struct cras_server_metrics_device_data {
enum CRAS_METRICS_DEVICE_TYPE type;
enum CRAS_STREAM_DIRECTION direction;
struct timespec runtime;
- unsigned value;
-};
-
-struct cras_server_metrics_stream_data {
- enum CRAS_CLIENT_TYPE client_type;
- enum CRAS_STREAM_TYPE stream_type;
- enum CRAS_STREAM_DIRECTION direction;
- struct timespec runtime;
};
struct cras_server_metrics_timespec_data {
@@ -181,7 +149,6 @@ union cras_server_metrics_data {
unsigned value;
struct cras_server_metrics_stream_config stream_config;
struct cras_server_metrics_device_data device_data;
- struct cras_server_metrics_stream_data stream_data;
struct cras_server_metrics_timespec_data timespec_data;
};
@@ -264,15 +231,9 @@ metrics_device_type_str(enum CRAS_METRICS_DEVICE_TYPE device_type)
return "HSP";
case CRAS_METRICS_DEVICE_BLUETOOTH:
return "Bluetooth";
- case CRAS_METRICS_DEVICE_BLUETOOTH_NB_MIC:
- return "BluetoothNarrowBandMic";
- case CRAS_METRICS_DEVICE_BLUETOOTH_WB_MIC:
- return "BluetoothWideBandMic";
case CRAS_METRICS_DEVICE_NO_DEVICE:
return "NoDevice";
- case CRAS_METRICS_DEVICE_ALSA_LOOPBACK:
- return "AlsaLoopback";
- /* Other fallback devices. */
+ /* Other dummy devices. */
case CRAS_METRICS_DEVICE_NORMAL_FALLBACK:
return "NormalFallback";
case CRAS_METRICS_DEVICE_ABNORMAL_FALLBACK:
@@ -286,58 +247,6 @@ metrics_device_type_str(enum CRAS_METRICS_DEVICE_TYPE device_type)
}
}
-static inline const char *
-metrics_client_type_str(enum CRAS_CLIENT_TYPE client_type)
-{
- switch (client_type) {
- case CRAS_CLIENT_TYPE_UNKNOWN:
- return "Unknown";
- case CRAS_CLIENT_TYPE_LEGACY:
- return "Legacy";
- case CRAS_CLIENT_TYPE_TEST:
- return "Test";
- case CRAS_CLIENT_TYPE_PCM:
- return "PCM";
- case CRAS_CLIENT_TYPE_CHROME:
- return "Chrome";
- case CRAS_CLIENT_TYPE_ARC:
- return "ARC";
- case CRAS_CLIENT_TYPE_CROSVM:
- return "CrOSVM";
- case CRAS_CLIENT_TYPE_SERVER_STREAM:
- return "ServerStream";
- case CRAS_CLIENT_TYPE_LACROS:
- return "LaCrOS";
- case CRAS_CLIENT_TYPE_PLUGIN:
- return "PluginVM";
- case CRAS_CLIENT_TYPE_ARCVM:
- return "ARCVM";
- default:
- return "InvalidType";
- }
-}
-
-static inline const char *
-metrics_stream_type_str(enum CRAS_STREAM_TYPE stream_type)
-{
- switch (stream_type) {
- case CRAS_STREAM_TYPE_DEFAULT:
- return "Default";
- case CRAS_STREAM_TYPE_MULTIMEDIA:
- return "Multimedia";
- case CRAS_STREAM_TYPE_VOICE_COMMUNICATION:
- return "VoiceCommunication";
- case CRAS_STREAM_TYPE_SPEECH_RECOGNITION:
- return "SpeechRecognition";
- case CRAS_STREAM_TYPE_PRO_AUDIO:
- return "ProAudio";
- case CRAS_STREAM_TYPE_ACCESSIBILITY:
- return "Accessibility";
- default:
- return "InvalidType";
- }
-}
-
static enum CRAS_METRICS_DEVICE_TYPE
get_metrics_device_type(struct cras_iodev *iodev)
{
@@ -392,158 +301,25 @@ get_metrics_device_type(struct cras_iodev *iodev)
return CRAS_METRICS_DEVICE_POST_DSP_LOOPBACK;
case CRAS_NODE_TYPE_USB:
return CRAS_METRICS_DEVICE_USB;
- case CRAS_NODE_TYPE_BLUETOOTH: {
+ case CRAS_NODE_TYPE_BLUETOOTH:
#ifdef CRAS_DBUS
- enum cras_bt_device_profile profile =
- cras_bt_io_profile_to_log(iodev);
- switch (profile) {
- case CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE:
+ if (cras_bt_io_on_profile(iodev,
+ CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE))
return CRAS_METRICS_DEVICE_A2DP;
- case CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY:
- /* HFP narrow band has its own node type so we know
- * this is wideband mic for sure. */
- return (iodev->direction == CRAS_STREAM_INPUT) ?
- CRAS_METRICS_DEVICE_BLUETOOTH_WB_MIC :
- CRAS_METRICS_DEVICE_HFP;
- case CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY:
+ if (cras_bt_io_on_profile(
+ iodev, CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY))
+ return CRAS_METRICS_DEVICE_HFP;
+ if (cras_bt_io_on_profile(
+ iodev, CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY))
return CRAS_METRICS_DEVICE_HSP;
- default:
- break;
- }
#endif
return CRAS_METRICS_DEVICE_BLUETOOTH;
- }
- case CRAS_NODE_TYPE_BLUETOOTH_NB_MIC:
- return CRAS_METRICS_DEVICE_BLUETOOTH_NB_MIC;
- case CRAS_NODE_TYPE_ALSA_LOOPBACK:
- return CRAS_METRICS_DEVICE_ALSA_LOOPBACK;
case CRAS_NODE_TYPE_UNKNOWN:
default:
return CRAS_METRICS_DEVICE_UNKNOWN;
}
}
-/*
- * Logs metrics for each group it belongs to. The UMA does not merge subgroups
- * automatically so we need to log them separately.
- *
- * For example, if we call this function with argument (3, 48000,
- * Cras.StreamSamplingRate, Input, Chrome), it will send 48000 to below
- * metrics:
- * Cras.StreamSamplingRate.Input.Chrome
- * Cras.StreamSamplingRate.Input
- * Cras.StreamSamplingRate
- */
-static void log_sparse_histogram_each_level(int num, int sample, ...)
-{
- char metrics_name[METRICS_NAME_BUFFER_SIZE] = {};
- va_list valist;
- int i, len = 0;
-
- va_start(valist, sample);
-
- for (i = 0; i < num && len < METRICS_NAME_BUFFER_SIZE; i++) {
- int metric_len =
- snprintf(metrics_name + len,
- METRICS_NAME_BUFFER_SIZE - len, "%s%s",
- i ? "." : "", va_arg(valist, char *));
- // Exit early on error or running out of bufferspace. Avoids
- // logging partial or corrupted strings.
- if (metric_len < 0 ||
- metric_len > METRICS_NAME_BUFFER_SIZE - len)
- break;
- len += metric_len;
- cras_metrics_log_sparse_histogram(metrics_name, sample);
- }
-
- va_end(valist);
-}
-
-static void log_histogram_each_level(int num, int sample, int min, int max,
- int nbuckets, ...)
-{
- char metrics_name[METRICS_NAME_BUFFER_SIZE] = {};
- va_list valist;
- int i, len = 0;
-
- va_start(valist, nbuckets);
-
- for (i = 0; i < num && len < METRICS_NAME_BUFFER_SIZE; i++) {
- int metric_len =
- snprintf(metrics_name + len,
- METRICS_NAME_BUFFER_SIZE - len, "%s%s",
- i ? "." : "", va_arg(valist, char *));
- // Exit early on error or running out of bufferspace. Avoids
- // logging partial or corrupted strings.
- if (metric_len < 0 ||
- metric_len > METRICS_NAME_BUFFER_SIZE - len)
- break;
- len += metric_len;
- cras_metrics_log_histogram(metrics_name, sample, min, max,
- nbuckets);
- }
-
- va_end(valist);
-}
-
-int cras_server_metrics_hfp_sco_connection_error(
- enum CRAS_METRICS_BT_SCO_ERROR_TYPE type)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- data.value = type;
- init_server_metrics_msg(&msg, BT_SCO_CONNECTION_ERROR, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send metrics message: "
- "BT_SCO_CONNECTION_ERROR");
- return err;
- }
- return 0;
-}
-
-int cras_server_metrics_hfp_battery_indicator(int battery_indicator_support)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- data.value = battery_indicator_support;
- init_server_metrics_msg(&msg, BT_BATTERY_INDICATOR_SUPPORTED, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send metrics message: "
- "BT_BATTERY_INDICATOR_SUPPORTED");
- return err;
- }
- return 0;
-}
-
-int cras_server_metrics_hfp_battery_report(int battery_report)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- data.value = battery_report;
- init_server_metrics_msg(&msg, BT_BATTERY_REPORT, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send metrics message: "
- "BT_BATTERY_REPORT");
- return err;
- }
- return 0;
-}
-
int cras_server_metrics_hfp_packet_loss(float packet_loss_ratio)
{
struct cras_server_metrics_message msg;
@@ -584,25 +360,6 @@ int cras_server_metrics_hfp_wideband_support(bool supported)
return 0;
}
-int cras_server_metrics_hfp_wideband_selected_codec(int codec)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- data.value = codec;
- init_server_metrics_msg(&msg, BT_WIDEBAND_SELECTED_CODEC, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send metrics message: "
- "BT_WIDEBAND_SELECTED_CODEC");
- return err;
- }
- return 0;
-}
-
int cras_server_metrics_device_runtime(struct cras_iodev *iodev)
{
struct cras_server_metrics_message msg;
@@ -628,56 +385,6 @@ int cras_server_metrics_device_runtime(struct cras_iodev *iodev)
return 0;
}
-int cras_server_metrics_device_gain(struct cras_iodev *iodev)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- if (iodev->direction == CRAS_STREAM_OUTPUT)
- return 0;
-
- data.device_data.type = get_metrics_device_type(iodev);
- data.device_data.value =
- (unsigned)100 * iodev->active_node->ui_gain_scaler;
-
- init_server_metrics_msg(&msg, DEVICE_GAIN, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR, "Failed to send metrics message: DEVICE_GAIN");
- return err;
- }
-
- return 0;
-}
-
-int cras_server_metrics_device_volume(struct cras_iodev *iodev)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- if (iodev->direction == CRAS_STREAM_INPUT)
- return 0;
-
- data.device_data.type = get_metrics_device_type(iodev);
- data.device_data.value = iodev->active_node->volume;
-
- init_server_metrics_msg(&msg, DEVICE_VOLUME, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR,
- "Failed to send metrics message: DEVICE_VOLUME");
- return err;
- }
-
- return 0;
-}
-
int cras_server_metrics_highest_device_delay(
unsigned int hw_level, unsigned int largest_cb_level,
enum CRAS_STREAM_DIRECTION direction)
@@ -757,31 +464,13 @@ int cras_server_metrics_highest_hw_level(unsigned hw_level,
return 0;
}
-/* Logs longest fetch delay of a stream. */
-int cras_server_metrics_longest_fetch_delay(const struct cras_rstream *stream)
+int cras_server_metrics_longest_fetch_delay(unsigned delay_msec)
{
struct cras_server_metrics_message msg;
union cras_server_metrics_data data;
int err;
- data.stream_data.client_type = stream->client_type;
- data.stream_data.stream_type = stream->stream_type;
- data.stream_data.direction = stream->direction;
-
- /*
- * There is no delay when the sleep_interval_ts larger than the
- * longest_fetch_interval.
- */
- if (!timespec_after(&stream->longest_fetch_interval,
- &stream->sleep_interval_ts)) {
- data.stream_data.runtime.tv_sec = 0;
- data.stream_data.runtime.tv_nsec = 0;
- } else {
- subtract_timespecs(&stream->longest_fetch_interval,
- &stream->sleep_interval_ts,
- &data.stream_data.runtime);
- }
-
+ data.value = delay_msec;
init_server_metrics_msg(&msg, LONGEST_FETCH_DELAY, data);
err = cras_server_metrics_message_send(
(struct cras_main_message *)&msg);
@@ -813,9 +502,7 @@ int cras_server_metrics_num_underruns(unsigned num_underruns)
return 0;
}
-/* Logs the frequency of missed callback. */
-static int
-cras_server_metrics_missed_cb_frequency(const struct cras_rstream *stream)
+int cras_server_metrics_missed_cb_frequency(const struct cras_rstream *stream)
{
struct cras_server_metrics_message msg;
union cras_server_metrics_data data;
@@ -968,9 +655,7 @@ int cras_server_metrics_missed_cb_event(struct cras_rstream *stream)
return rc;
}
-/* Logs the stream configurations from clients. */
-static int
-cras_server_metrics_stream_config(const struct cras_rstream_config *config)
+int cras_server_metrics_stream_config(struct cras_rstream_config *config)
{
struct cras_server_metrics_message msg;
union cras_server_metrics_data data;
@@ -979,7 +664,6 @@ cras_server_metrics_stream_config(const struct cras_rstream_config *config)
data.stream_config.direction = config->direction;
data.stream_config.cb_threshold = (unsigned)config->cb_threshold;
data.stream_config.flags = (unsigned)config->flags;
- data.stream_config.effects = (unsigned)config->effects;
data.stream_config.format = (int)config->format->format;
data.stream_config.rate = (unsigned)config->format->frame_rate;
data.stream_config.client_type = config->client_type;
@@ -996,50 +680,6 @@ cras_server_metrics_stream_config(const struct cras_rstream_config *config)
return 0;
}
-/* Logs runtime of a stream. */
-int cras_server_metrics_stream_runtime(const struct cras_rstream *stream)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- struct timespec now;
- int err;
-
- data.stream_data.client_type = stream->client_type;
- data.stream_data.stream_type = stream->stream_type;
- data.stream_data.direction = stream->direction;
- clock_gettime(CLOCK_MONOTONIC_RAW, &now);
- subtract_timespecs(&now, &stream->start_ts, &data.stream_data.runtime);
-
- init_server_metrics_msg(&msg, STREAM_RUNTIME, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR,
- "Failed to send metrics message: STREAM_RUNTIME");
- return err;
- }
-
- return 0;
-}
-
-int cras_server_metrics_stream_create(const struct cras_rstream_config *config)
-{
- return cras_server_metrics_stream_config(config);
-}
-
-int cras_server_metrics_stream_destroy(const struct cras_rstream *stream)
-{
- int rc;
- rc = cras_server_metrics_missed_cb_frequency(stream);
- if (rc < 0)
- return rc;
- rc = cras_server_metrics_stream_runtime(stream);
- if (rc < 0)
- return rc;
- return cras_server_metrics_longest_fetch_delay(stream);
-}
-
int cras_server_metrics_busyloop(struct timespec *ts, unsigned count)
{
struct cras_server_metrics_message msg;
@@ -1060,26 +700,6 @@ int cras_server_metrics_busyloop(struct timespec *ts, unsigned count)
return 0;
}
-int cras_server_metrics_busyloop_length(unsigned length)
-{
- struct cras_server_metrics_message msg;
- union cras_server_metrics_data data;
- int err;
-
- data.value = length;
-
- init_server_metrics_msg(&msg, BUSYLOOP_LENGTH, data);
-
- err = cras_server_metrics_message_send(
- (struct cras_main_message *)&msg);
- if (err < 0) {
- syslog(LOG_ERR,
- "Failed to send metrics message: BUSYLOOP_LENGTH");
- return err;
- }
- return 0;
-}
-
static void metrics_device_runtime(struct cras_server_metrics_device_data data)
{
char metrics_name[METRICS_NAME_BUFFER_SIZE];
@@ -1098,44 +718,6 @@ static void metrics_device_runtime(struct cras_server_metrics_device_data data)
cras_metrics_log_sparse_histogram(kDeviceTypeOutput, data.type);
}
-static void metrics_device_gain(struct cras_server_metrics_device_data data)
-{
- char metrics_name[METRICS_NAME_BUFFER_SIZE];
-
- snprintf(metrics_name, METRICS_NAME_BUFFER_SIZE, "%s.%s", kDeviceGain,
- metrics_device_type_str(data.type));
- cras_metrics_log_histogram(metrics_name, data.value, 0, 2000, 20);
-}
-
-static void metrics_device_volume(struct cras_server_metrics_device_data data)
-{
- char metrics_name[METRICS_NAME_BUFFER_SIZE];
-
- snprintf(metrics_name, METRICS_NAME_BUFFER_SIZE, "%s.%s", kDeviceVolume,
- metrics_device_type_str(data.type));
- cras_metrics_log_histogram(metrics_name, data.value, 0, 100, 20);
-}
-
-static void
-metrics_longest_fetch_delay(struct cras_server_metrics_stream_data data)
-{
- int fetch_delay_msec =
- data.runtime.tv_sec * 1000 + data.runtime.tv_nsec / 1000000;
- log_histogram_each_level(3, fetch_delay_msec, 0, 10000, 20,
- kFetchDelayMilliSeconds,
- metrics_client_type_str(data.client_type),
- metrics_stream_type_str(data.stream_type));
-}
-
-static void metrics_stream_runtime(struct cras_server_metrics_stream_data data)
-{
- log_histogram_each_level(
- 4, (int)data.runtime.tv_sec, 0, 10000, 20, kStreamRuntime,
- data.direction == CRAS_STREAM_INPUT ? "Input" : "Output",
- metrics_client_type_str(data.client_type),
- metrics_stream_type_str(data.stream_type));
-}
-
static void metrics_busyloop(struct cras_server_metrics_timespec_data data)
{
char metrics_name[METRICS_NAME_BUFFER_SIZE];
@@ -1149,37 +731,18 @@ static void metrics_busyloop(struct cras_server_metrics_timespec_data data)
static void
metrics_stream_config(struct cras_server_metrics_stream_config config)
{
- const char *direction;
-
- if (config.direction == CRAS_STREAM_INPUT)
- direction = "Input";
- else
- direction = "Output";
-
/* Logs stream callback threshold. */
- log_sparse_histogram_each_level(
- 3, config.cb_threshold, kStreamCallbackThreshold, direction,
- metrics_client_type_str(config.client_type));
+ cras_metrics_log_sparse_histogram(kStreamCallbackThreshold,
+ config.cb_threshold);
/* Logs stream flags. */
- log_sparse_histogram_each_level(
- 3, config.flags, kStreamFlags, direction,
- metrics_client_type_str(config.client_type));
-
- /* Logs stream effects. */
- log_sparse_histogram_each_level(
- 3, config.effects, kStreamEffects, direction,
- metrics_client_type_str(config.client_type));
+ cras_metrics_log_sparse_histogram(kStreamFlags, config.flags);
/* Logs stream sampling format. */
- log_sparse_histogram_each_level(
- 3, config.format, kStreamSamplingFormat, direction,
- metrics_client_type_str(config.client_type));
+ cras_metrics_log_sparse_histogram(kStreamSamplingFormat, config.format);
/* Logs stream sampling rate. */
- log_sparse_histogram_each_level(
- 3, config.rate, kStreamSamplingRate, direction,
- metrics_client_type_str(config.client_type));
+ cras_metrics_log_sparse_histogram(kStreamSamplingRate, config.rate);
/* Logs stream client type. */
if (config.direction == CRAS_STREAM_INPUT)
@@ -1195,18 +758,6 @@ static void handle_metrics_message(struct cras_main_message *msg, void *arg)
struct cras_server_metrics_message *metrics_msg =
(struct cras_server_metrics_message *)msg;
switch (metrics_msg->metrics_type) {
- case BT_SCO_CONNECTION_ERROR:
- cras_metrics_log_sparse_histogram(kHfpScoConnectionError,
- metrics_msg->data.value);
- break;
- case BT_BATTERY_INDICATOR_SUPPORTED:
- cras_metrics_log_sparse_histogram(kHfpBatteryIndicatorSupported,
- metrics_msg->data.value);
- break;
- case BT_BATTERY_REPORT:
- cras_metrics_log_sparse_histogram(kHfpBatteryReport,
- metrics_msg->data.value);
- break;
case BT_WIDEBAND_PACKET_LOSS:
cras_metrics_log_histogram(kHfpWidebandSpeechPacketLoss,
metrics_msg->data.value, 0, 1000,
@@ -1216,20 +767,9 @@ static void handle_metrics_message(struct cras_main_message *msg, void *arg)
cras_metrics_log_sparse_histogram(kHfpWidebandSpeechSupported,
metrics_msg->data.value);
break;
- case BT_WIDEBAND_SELECTED_CODEC:
- cras_metrics_log_sparse_histogram(
- kHfpWidebandSpeechSelectedCodec,
- metrics_msg->data.value);
- break;
- case DEVICE_GAIN:
- metrics_device_gain(metrics_msg->data.device_data);
- break;
case DEVICE_RUNTIME:
metrics_device_runtime(metrics_msg->data.device_data);
break;
- case DEVICE_VOLUME:
- metrics_device_volume(metrics_msg->data.device_data);
- break;
case HIGHEST_DEVICE_DELAY_INPUT:
cras_metrics_log_histogram(kHighestDeviceDelayInput,
metrics_msg->data.value, 1, 10000,
@@ -1251,7 +791,9 @@ static void handle_metrics_message(struct cras_main_message *msg, void *arg)
20);
break;
case LONGEST_FETCH_DELAY:
- metrics_longest_fetch_delay(metrics_msg->data.stream_data);
+ cras_metrics_log_histogram(kStreamTimeoutMilliSeconds,
+ metrics_msg->data.value, 1, 20000,
+ 10);
break;
case MISSED_CB_FIRST_TIME_INPUT:
cras_metrics_log_histogram(kMissedCallbackFirstTimeInput,
@@ -1301,16 +843,9 @@ static void handle_metrics_message(struct cras_main_message *msg, void *arg)
case STREAM_CONFIG:
metrics_stream_config(metrics_msg->data.stream_config);
break;
- case STREAM_RUNTIME:
- metrics_stream_runtime(metrics_msg->data.stream_data);
- break;
case BUSYLOOP:
metrics_busyloop(metrics_msg->data.timespec_data);
break;
- case BUSYLOOP_LENGTH:
- cras_metrics_log_histogram(
- kBusyloopLength, metrics_msg->data.value, 0, 1000, 50);
- break;
default:
syslog(LOG_ERR, "Unknown metrics type %u",
metrics_msg->metrics_type);
diff --git a/cras/src/server/cras_server_metrics.h b/cras/src/server/cras_server_metrics.h
index e8458087..b9eb1216 100644
--- a/cras/src/server/cras_server_metrics.h
+++ b/cras/src/server/cras_server_metrics.h
@@ -13,48 +13,15 @@
extern const char kNoCodecsFoundMetric[];
-enum CRAS_METRICS_BT_SCO_ERROR_TYPE {
- CRAS_METRICS_SCO_SKT_SUCCESS = 0,
- CRAS_METRICS_SCO_SKT_CONNECT_ERROR = 1,
- CRAS_METRICS_SCO_SKT_OPEN_ERROR = 2,
- CRAS_METRICS_SCO_SKT_POLL_TIMEOUT = 3,
- CRAS_METRICS_SCO_SKT_POLL_ERR_HUP = 4,
-};
-
-/* Logs the error type happens when setting up SCO connection. This is mainly
- * used to track whether the setup of SCO connection succeeds and the frequency
- * of different errors. This will also be used to track if our fixes for these
- * errors address the issues we find.
- */
-int cras_server_metrics_hfp_sco_connection_error(
- enum CRAS_METRICS_BT_SCO_ERROR_TYPE type);
-
-/* Logs an enum representing which spec does HFP headset supports battery
- * indicator. Apple, HFP, none or both. */
-int cras_server_metrics_hfp_battery_indicator(int battery_indicator_support);
-
-/* Logs an enum representing the spec through which the battery level change
- * event reported. Apple or HFP.*/
-int cras_server_metrics_hfp_battery_report(int battery_report);
-
/* Logs if connected HFP headset supports wideband speech. */
int cras_server_metrics_hfp_wideband_support(bool supported);
-/* Logs the selected codec in HFP wideband connection. */
-int cras_server_metrics_hfp_wideband_selected_codec(int codec);
-
/* Logs the number of packet loss per 1000 packets under HFP capture. */
int cras_server_metrics_hfp_packet_loss(float packet_loss_ratio);
/* Logs runtime of a device. */
int cras_server_metrics_device_runtime(struct cras_iodev *iodev);
-/* Logs the gain of a device. */
-int cras_server_metrics_device_gain(struct cras_iodev *iodev);
-
-/* Logs the volume of a device. */
-int cras_server_metrics_device_volume(struct cras_iodev *iodev);
-
/* Logs the highest delay time of a device. */
int cras_server_metrics_highest_device_delay(
unsigned int hw_level, unsigned int largest_cb_level,
@@ -64,24 +31,24 @@ int cras_server_metrics_highest_device_delay(
int cras_server_metrics_highest_hw_level(unsigned hw_level,
enum CRAS_STREAM_DIRECTION direction);
+/* Logs the longest fetch delay of a stream in millisecond. */
+int cras_server_metrics_longest_fetch_delay(unsigned delay_msec);
+
/* Logs the number of underruns of a device. */
int cras_server_metrics_num_underruns(unsigned num_underruns);
-/* Logs the missed callback event. */
-int cras_server_metrics_missed_cb_event(struct cras_rstream *stream);
+/* Logs the frequency of missed callback. */
+int cras_server_metrics_missed_cb_frequency(const struct cras_rstream *stream);
-/* Logs information when a stream creates. */
-int cras_server_metrics_stream_create(const struct cras_rstream_config *config);
+/* Logs the missed callback event. */
+int cras_server_metrics_missed_cb_event(const struct cras_rstream *stream);
-/* Logs information when a stream destroys. */
-int cras_server_metrics_stream_destroy(const struct cras_rstream *stream);
+/* Logs the stream configurations from clients. */
+int cras_server_metrics_stream_config(struct cras_rstream_config *config);
/* Logs the number of busyloops for different time periods. */
int cras_server_metrics_busyloop(struct timespec *ts, unsigned count);
-/* Logs the length of busyloops. */
-int cras_server_metrics_busyloop_length(unsigned length);
-
/* Initialize metrics logging stuff. */
int cras_server_metrics_init();
diff --git a/cras/src/server/cras_system_state.c b/cras/src/server/cras_system_state.c
index 366afb5f..7aa3367e 100644
--- a/cras/src/server/cras_system_state.c
+++ b/cras/src/server/cras_system_state.c
@@ -3,7 +3,6 @@
* found in the LICENSE file.
*/
-#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
@@ -14,11 +13,9 @@
#include <syslog.h>
#include "cras_alsa_card.h"
-#include "cras_alert.h"
#include "cras_board_config.h"
#include "cras_config.h"
-#include "cras_device_blocklist.h"
-#include "cras_iodev_list.h"
+#include "cras_device_blacklist.h"
#include "cras_observer.h"
#include "cras_shm.h"
#include "cras_system_state.h"
@@ -32,11 +29,6 @@ struct card_list {
struct card_list *prev, *next;
};
-struct name_list {
- char name[NAME_MAX];
- struct name_list *prev, *next;
-};
-
/* The system state.
* Members:
* exp_state - The exported system state shared with clients.
@@ -48,7 +40,7 @@ struct name_list {
* device_config_dir - Directory of device configs where volume curves live.
* internal_ucm_suffix - The suffix to append to internal card name to
* control which ucm config file to load.
- * device_blocklist - Blocklist of device the server will ignore.
+ * device_blacklist - Blacklist of device the server will ignore.
* cards - A list of active sound cards in the system.
* update_lock - Protects the update_count, as audio threads can update the
* stream count.
@@ -56,8 +48,6 @@ struct name_list {
* add_task - Function to handle adding a task for main thread to execute.
* task_data - Data to be passed to add_task handler function.
* main_thread_tid - The thread id of the main thread.
- * bt_fix_a2dp_packet_size - The flag to override A2DP packet size set by
- * Blueetoh peer devices to a smaller default value.
*/
static struct {
struct cras_server_state *exp_state;
@@ -67,14 +57,13 @@ static struct {
size_t shm_size;
const char *device_config_dir;
const char *internal_ucm_suffix;
- struct name_list *ignore_suffix_cards;
- struct cras_device_blocklist *device_blocklist;
+ struct cras_device_blacklist *device_blacklist;
struct card_list *cards;
pthread_mutex_t update_lock;
struct cras_tm *tm;
/* Select loop callback registration. */
- int (*fd_add)(int fd, void (*cb)(void *data, int events), void *cb_data,
- int events, void *select_data);
+ int (*fd_add)(int fd, void (*cb)(void *data), void *cb_data,
+ void *select_data);
void (*fd_rm)(int fd, void *select_data);
void *select_data;
int (*add_task)(void (*callback)(void *data), void *callback_data,
@@ -82,42 +71,8 @@ static struct {
void *task_data;
struct cras_audio_thread_snapshot_buffer snapshot_buffer;
pthread_t main_thread_tid;
- bool bt_fix_a2dp_packet_size;
} state;
-/* The string format is CARD1,CARD2,CARD3. Divide it into a list. */
-void init_ignore_suffix_cards(char *str)
-{
- struct name_list *card;
- char *ptr;
-
- state.ignore_suffix_cards = NULL;
-
- if (str == NULL)
- return;
-
- ptr = strtok(str, ",");
- while (ptr != NULL) {
- card = (struct name_list *)calloc(1, sizeof(*card));
- if (!card) {
- syslog(LOG_ERR, "Failed to call calloc: %d", errno);
- return;
- }
- strncpy(card->name, ptr, NAME_MAX - 1);
- DL_APPEND(state.ignore_suffix_cards, card);
- ptr = strtok(NULL, ",");
- }
-}
-
-void deinit_ignore_suffix_cards()
-{
- struct name_list *card;
- DL_FOREACH (state.ignore_suffix_cards, card) {
- DL_DELETE(state.ignore_suffix_cards, card);
- free(card);
- }
-}
-
/*
* Exported Interface.
*/
@@ -148,21 +103,20 @@ void cras_system_state_init(const char *device_config_dir, const char *shm_name,
exp_state->mute = 0;
exp_state->mute_locked = 0;
exp_state->suspended = 0;
+ exp_state->capture_gain = DEFAULT_CAPTURE_GAIN;
+ exp_state->capture_gain_target = DEFAULT_CAPTURE_GAIN;
exp_state->capture_mute = 0;
exp_state->capture_mute_locked = 0;
exp_state->min_volume_dBFS = DEFAULT_MIN_VOLUME_DBFS;
exp_state->max_volume_dBFS = DEFAULT_MAX_VOLUME_DBFS;
+ exp_state->min_capture_gain = DEFAULT_MIN_CAPTURE_GAIN;
+ exp_state->max_capture_gain = DEFAULT_MAX_CAPTURE_GAIN;
exp_state->num_streams_attached = 0;
exp_state->default_output_buffer_size =
board_config.default_output_buffer_size;
exp_state->aec_supported = board_config.aec_supported;
exp_state->aec_group_id = board_config.aec_group_id;
- exp_state->bt_wbs_enabled = board_config.bt_wbs_enabled;
- exp_state->deprioritize_bt_wbs_mic =
- board_config.deprioritize_bt_wbs_mic;
- exp_state->noise_cancellation_enabled = 0;
- exp_state->hotword_pause_at_suspend =
- board_config.hotword_pause_at_suspend;
+ exp_state->bt_wbs_enabled = 0;
if ((rc = pthread_mutex_init(&state.update_lock, 0) != 0)) {
syslog(LOG_ERR, "Fatal: system state mutex init");
@@ -172,13 +126,11 @@ void cras_system_state_init(const char *device_config_dir, const char *shm_name,
state.exp_state = exp_state;
/* Directory for volume curve configs.
- * Note that device_config_dir does not affect device blocklist.
- * Device blocklist is common to all boards so we do not need
- * to change device blocklist at run time. */
+ * Note that device_config_dir does not affect device blacklist.
+ * Device blacklist is common to all boards so we do not need
+ * to change device blacklist at run time. */
state.device_config_dir = device_config_dir;
state.internal_ucm_suffix = NULL;
- init_ignore_suffix_cards(board_config.ucm_ignore_suffix);
- free(board_config.ucm_ignore_suffix);
state.tm = cras_tm_init();
if (!state.tm) {
@@ -186,9 +138,9 @@ void cras_system_state_init(const char *device_config_dir, const char *shm_name,
exit(-ENOMEM);
}
- /* Read config file for blocklisted devices. */
- state.device_blocklist =
- cras_device_blocklist_create(CRAS_CONFIG_FILE_DIR);
+ /* Read config file for blacklisted devices. */
+ state.device_blacklist =
+ cras_device_blacklist_create(CRAS_CONFIG_FILE_DIR);
/* Initialize snapshot buffer memory */
memset(&state.snapshot_buffer, 0,
@@ -196,8 +148,6 @@ void cras_system_state_init(const char *device_config_dir, const char *shm_name,
/* Save thread id of the main thread. */
state.main_thread_tid = pthread_self();
-
- state.bt_fix_a2dp_packet_size = false;
}
void cras_system_state_set_internal_ucm_suffix(const char *internal_ucm_suffix)
@@ -209,7 +159,7 @@ void cras_system_state_deinit()
{
/* Free any resources used. This prevents unit tests from leaking. */
- cras_device_blocklist_destroy(state.device_blocklist);
+ cras_device_blacklist_destroy(state.device_blacklist);
cras_tm_deinit(state.tm);
@@ -220,7 +170,6 @@ void cras_system_state_deinit()
close(state.shm_fd_ro);
}
- deinit_ignore_suffix_cards();
pthread_mutex_destroy(&state.update_lock);
}
@@ -238,6 +187,21 @@ size_t cras_system_get_volume()
return state.exp_state->volume;
}
+void cras_system_set_capture_gain(long gain)
+{
+ /* Adjust targeted gain to be in supported range. */
+ state.exp_state->capture_gain_target = gain;
+ gain = MAX(gain, state.exp_state->min_capture_gain);
+ gain = MIN(gain, state.exp_state->max_capture_gain);
+ state.exp_state->capture_gain = gain;
+ cras_observer_notify_capture_gain(state.exp_state->capture_gain);
+}
+
+long cras_system_get_capture_gain()
+{
+ return state.exp_state->capture_gain;
+}
+
void cras_system_notify_mute(void)
{
cras_observer_notify_output_mute(state.exp_state->mute,
@@ -346,7 +310,6 @@ void cras_system_set_suspended(int suspended)
{
state.exp_state->suspended = suspended;
cras_observer_notify_suspend_changed(suspended);
- cras_alert_process_all_pending_alerts();
}
void cras_system_set_volume_limits(long min, long max)
@@ -365,6 +328,24 @@ long cras_system_get_max_volume()
return state.exp_state->max_volume_dBFS;
}
+void cras_system_set_capture_gain_limits(long min, long max)
+{
+ state.exp_state->min_capture_gain = MAX(min, DEFAULT_MIN_CAPTURE_GAIN);
+ state.exp_state->max_capture_gain = max;
+ /* Re-apply target gain subjected to the new supported range. */
+ cras_system_set_capture_gain(state.exp_state->capture_gain_target);
+}
+
+long cras_system_get_min_capture_gain()
+{
+ return state.exp_state->min_capture_gain;
+}
+
+long cras_system_get_max_capture_gain()
+{
+ return state.exp_state->max_capture_gain;
+}
+
int cras_system_get_default_output_buffer_size()
{
return state.exp_state->default_output_buffer_size;
@@ -390,60 +371,6 @@ bool cras_system_get_bt_wbs_enabled()
return !!state.exp_state->bt_wbs_enabled;
}
-bool cras_system_get_deprioritize_bt_wbs_mic()
-{
- return !!state.exp_state->deprioritize_bt_wbs_mic;
-}
-
-void cras_system_set_bt_fix_a2dp_packet_size_enabled(bool enabled)
-{
- state.bt_fix_a2dp_packet_size = enabled;
-}
-
-bool cras_system_get_bt_fix_a2dp_packet_size_enabled()
-{
- return state.bt_fix_a2dp_packet_size;
-}
-
-void cras_system_set_noise_cancellation_enabled(bool enabled)
-{
- /* When the flag is toggled, propagate to all iodevs immediately. */
- if (cras_system_get_noise_cancellation_enabled() != enabled) {
- state.exp_state->noise_cancellation_enabled = enabled;
- cras_iodev_list_reset_for_noise_cancellation();
- }
-}
-
-bool cras_system_get_noise_cancellation_enabled()
-{
- return !!state.exp_state->noise_cancellation_enabled;
-}
-
-bool cras_system_check_ignore_ucm_suffix(const char *card_name)
-{
- /* Check the general case: ALSA Loopback card "Loopback". */
- if (!strcmp("Loopback", card_name))
- return true;
-
- /* Check board-specific ignore ucm suffix cards. */
- struct name_list *card;
- DL_FOREACH (state.ignore_suffix_cards, card) {
- if (!strcmp(card->name, card_name))
- return true;
- }
- return false;
-}
-
-bool cras_system_get_hotword_pause_at_suspend()
-{
- return !!state.exp_state->hotword_pause_at_suspend;
-}
-
-void cras_system_set_hotword_pause_at_suspend(bool pause)
-{
- state.exp_state->hotword_pause_at_suspend = pause;
-}
-
int cras_system_add_alsa_card(struct cras_alsa_card_info *alsa_card_info)
{
struct card_list *card;
@@ -459,10 +386,11 @@ int cras_system_add_alsa_card(struct cras_alsa_card_info *alsa_card_info)
if (card_index == cras_alsa_card_get_index(card->card))
return -EEXIST;
}
- alsa_card =
- cras_alsa_card_create(alsa_card_info, state.device_config_dir,
- state.device_blocklist,
- state.internal_ucm_suffix);
+ alsa_card = cras_alsa_card_create(
+ alsa_card_info, state.device_config_dir, state.device_blacklist,
+ (alsa_card_info->card_type == ALSA_CARD_TYPE_INTERNAL) ?
+ state.internal_ucm_suffix :
+ NULL);
if (alsa_card == NULL)
return -ENOMEM;
card = calloc(1, sizeof(*card));
@@ -500,8 +428,8 @@ int cras_system_alsa_card_exists(unsigned alsa_card_index)
}
int cras_system_set_select_handler(
- int (*add)(int fd, void (*callback)(void *data, int events),
- void *callback_data, int events, void *select_data),
+ int (*add)(int fd, void (*callback)(void *data), void *callback_data,
+ void *select_data),
void (*rm)(int fd, void *select_data), void *select_data)
{
if (state.fd_add != NULL || state.fd_rm != NULL)
@@ -512,13 +440,12 @@ int cras_system_set_select_handler(
return 0;
}
-int cras_system_add_select_fd(int fd, void (*callback)(void *data, int revents),
- void *callback_data, int events)
+int cras_system_add_select_fd(int fd, void (*callback)(void *data),
+ void *callback_data)
{
if (state.fd_add == NULL)
return -EINVAL;
- return state.fd_add(fd, callback, callback_data, events,
- state.select_data);
+ return state.fd_add(fd, callback, callback_data, state.select_data);
}
int cras_system_set_add_task_handler(int (*add_task)(void (*cb)(void *data),
@@ -548,8 +475,7 @@ void cras_system_rm_select_fd(int fd)
state.fd_rm(fd, state.select_data);
}
-void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type)
+void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction)
{
struct cras_server_state *s;
@@ -559,19 +485,13 @@ void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
s->num_active_streams[direction]++;
s->num_streams_attached++;
- if (direction == CRAS_STREAM_INPUT) {
- s->num_input_streams_with_permission[client_type]++;
- cras_observer_notify_input_streams_with_permission(
- s->num_input_streams_with_permission);
- }
cras_system_state_update_complete();
cras_observer_notify_num_active_streams(
direction, s->num_active_streams[direction]);
}
-void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type)
+void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction)
{
struct cras_server_state *s;
unsigned i, sum;
@@ -589,11 +509,6 @@ void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
cras_clock_gettime(CLOCK_MONOTONIC_RAW,
&s->last_active_stream_time);
s->num_active_streams[direction]--;
- if (direction == CRAS_STREAM_INPUT) {
- s->num_input_streams_with_permission[client_type]--;
- cras_observer_notify_input_streams_with_permission(
- s->num_input_streams_with_permission);
- }
cras_system_state_update_complete();
cras_observer_notify_num_active_streams(
@@ -615,15 +530,6 @@ unsigned cras_system_state_get_active_streams_by_direction(
return state.exp_state->num_active_streams[direction];
}
-void cras_system_state_get_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE])
-{
- unsigned type;
- for (type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type)
- num_input_streams[type] =
- state.exp_state->num_input_streams_with_permission[type];
-}
-
void cras_system_state_get_last_stream_active_time(struct cras_timespec *ts)
{
*ts = state.exp_state->last_active_stream_time;
diff --git a/cras/src/server/cras_system_state.h b/cras/src/server/cras_system_state.h
index bd09395c..270e54c2 100644
--- a/cras/src/server/cras_system_state.h
+++ b/cras/src/server/cras_system_state.h
@@ -20,12 +20,7 @@
#define CRAS_MAX_SYSTEM_VOLUME 100
#define DEFAULT_CAPTURE_GAIN 2000 /* 20dB of gain. */
-/* Default to -6 dBFS as 90% of CrOS boards use microphone with -26dBFS
- * sensitivity under 94dB SPL @ 1kHz and we generally added 20dB gain to it.
- * This is a temporary value that should be refined when the standard process
- * measuring intrinsic sensitivity is built. */
-#define DEFAULT_CAPTURE_VOLUME_DBFS -600
-/* Default to 1--dB of range for playback and capture. */
+/* Default to 1--dB of range for palyback and capture. */
#define DEFAULT_MIN_VOLUME_DBFS -10000
#define DEFAULT_MAX_VOLUME_DBFS 0
#define DEFAULT_MIN_CAPTURE_GAIN -5000
@@ -57,8 +52,9 @@ void cras_system_set_volume(size_t volume);
/* Gets the current system volume. */
size_t cras_system_get_volume();
-/* Gets the current system capture volume. As we remove the support of setting
- * system capture gain, it should always be DEFAULT_CAPTURE_GAIN now. */
+/* Sets the system capture volume. Will be applied by the active device. */
+void cras_system_set_capture_gain(long gain);
+/* Gets the current system capture volume. */
long cras_system_get_capture_gain();
/* Sets if the system is muted by the user. */
@@ -107,6 +103,19 @@ long cras_system_get_min_volume();
/* Returns the dB value when volume = CRAS_MAX_SYSTEM_VOLUME, in dB * 100. */
long cras_system_get_max_volume();
+/* Sets the limits in dB * 100 of the MAX and MIN capture gain. This will allow
+ * clients to query what range of control is available. Both arguments are
+ * specified as dB * 100.
+ * Args:
+ * min - minimum allowed capture gain.
+ * max - maximum allowed capture gaax.
+ */
+void cras_system_set_capture_gain_limits(long min, long max);
+/* Returns the max value allowed for capture gain in dB * 100. */
+long cras_system_get_min_capture_gain();
+/* Returns the min value allowed for capture gain in dB * 100. */
+long cras_system_get_max_capture_gain();
+
/* Returns the default value of output buffer size in frames. */
int cras_system_get_default_output_buffer_size();
@@ -122,33 +131,6 @@ void cras_system_set_bt_wbs_enabled(bool enabled);
/* Gets the elable flag of bluetooth wideband speech feature. */
bool cras_system_get_bt_wbs_enabled();
-/*
- * Returns if Bluetooth WBS mic should be deprioritized for selecting
- * as default audio input option.
- */
-bool cras_system_get_deprioritize_bt_wbs_mic();
-
-/* Sets the flag to enable or disable Bluetooth fixed A2DP packet size. */
-void cras_system_set_bt_fix_a2dp_packet_size_enabled(bool enabled);
-
-/* Gets the flag of Bluetooth fixed A2DP packet size. */
-bool cras_system_get_bt_fix_a2dp_packet_size_enabled();
-
-/* Sets the flag to enable or disable Noise Cancellation. */
-void cras_system_set_noise_cancellation_enabled(bool enabled);
-
-/* Gets the flag of Noise Cancellation. */
-bool cras_system_get_noise_cancellation_enabled();
-
-/* Checks if the card ignores the ucm suffix. */
-bool cras_system_check_ignore_ucm_suffix(const char *card_name);
-
-/* Returns true if hotword detection is paused at system suspend. */
-bool cras_system_get_hotword_pause_at_suspend();
-
-/* Sets whether to pause hotword detection at system suspend. */
-void cras_system_set_hotword_pause_at_suspend(bool pause);
-
/* Adds a card at the given index to the system. When a new card is found
* (through a udev event notification) this will add the card to the system,
* causing its devices to become available for playback/capture.
@@ -192,8 +174,8 @@ int cras_system_alsa_card_exists(unsigned alsa_card_index);
* 0 on success, or -EBUSY if there is already a registered handler.
*/
int cras_system_set_select_handler(
- int (*add)(int fd, void (*callback)(void *data, int revents),
- void *callback_data, int events, void *select_data),
+ int (*add)(int fd, void (*callback)(void *data), void *callback_data,
+ void *select_data),
void (*rm)(int fd, void *select_data), void *select_data);
/* Adds the fd and callback pair. When select indicates that fd is readable,
@@ -202,12 +184,11 @@ int cras_system_set_select_handler(
* fd - The file descriptor to pass to select(2).
* callback - The callback to call when fd is ready.
* callback_data - Value passed back to the callback.
- * events - The events to poll for.
* Returns:
* 0 on success or a negative error code on failure.
*/
-int cras_system_add_select_fd(int fd, void (*callback)(void *data, int revents),
- void *callback_data, int events);
+int cras_system_add_select_fd(int fd, void (*callback)(void *data),
+ void *callback_data);
/* Removes the fd from the list of fds that are passed to select.
* Args:
@@ -244,20 +225,16 @@ int cras_system_add_task(void (*callback)(void *data), void *callback_data);
* subsystem is idle.
* Args:
* direction - Directions of audio streams.
- * client_type - CRAS_CLIENT_TYPE of the audio stream.
*/
-void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type);
+void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction);
/* Signals that an audio input or output stream has been removed from the
* system. This allows the count of active streams can be used to notice when
* the audio subsystem is idle.
* Args:
* direction - Directions of audio stream.
- * client_type - CRAS_CLIENT_TYPE of the audio stream.
*/
-void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type);
+void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction);
/* Returns the number of active playback and capture streams. */
unsigned cras_system_state_get_active_streams();
@@ -269,16 +246,6 @@ unsigned cras_system_state_get_active_streams();
unsigned cras_system_state_get_active_streams_by_direction(
enum CRAS_STREAM_DIRECTION direction);
-/* Returns the number of input streams with permission per CRAS_CLIENT_TYPE.
- *
- * Returns:
- * num_input_streams - An array with length = CRAS_NUM_CLIENT_TYPE and each
- * element is the number of the current input
- * streams with permission in each client type.
- */
-void cras_system_state_get_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE]);
-
/* Fills ts with the time the last stream was removed from the system, the time
* the stream count went to zero.
*/
diff --git a/cras/src/server/cras_telephony.c b/cras/src/server/cras_telephony.c
index 805fb137..ac95f7e1 100644
--- a/cras/src/server/cras_telephony.c
+++ b/cras/src/server/cras_telephony.c
@@ -41,12 +41,6 @@
" <method name=\"SetCallheld\">\n" \
" <arg name=\"value\" type=\"i\" direction=\"in\"/>\n" \
" </method>\n" \
- " <method name=\"SetCallsetup\">\n" \
- " <arg name=\"value\" type=\"i\" direction=\"in\"/>\n" \
- " </method>\n" \
- " <method name=\"SetCall\">\n" \
- " <arg name=\"value\" type=\"i\" direction=\"in\"/>\n" \
- " </method>\n" \
" </interface>\n" \
" <interface name=\"" DBUS_INTERFACE_INTROSPECTABLE "\">\n" \
" <method name=\"Introspect\">\n" \
@@ -226,46 +220,6 @@ static DBusHandlerResult handle_set_callheld(DBusConnection *conn,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static DBusHandlerResult handle_set_callsetup(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- struct hfp_slc_handle *handle;
- DBusHandlerResult rc;
- int value;
-
- rc = get_single_arg(message, DBUS_TYPE_INT32, &value);
- if (rc != DBUS_HANDLER_RESULT_HANDLED)
- return rc;
-
- telephony_handle.callsetup = value;
- handle = cras_hfp_ag_get_active_handle();
- if (handle)
- hfp_event_update_callsetup(handle);
-
- send_empty_reply(conn, message);
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
-static DBusHandlerResult handle_set_call(DBusConnection *conn,
- DBusMessage *message, void *arg)
-{
- struct hfp_slc_handle *handle;
- DBusHandlerResult rc;
- int value;
-
- rc = get_single_arg(message, DBUS_TYPE_INT32, &value);
- if (rc != DBUS_HANDLER_RESULT_HANDLED)
- return rc;
-
- telephony_handle.call = value;
- handle = cras_hfp_ag_get_active_handle();
- if (handle)
- hfp_event_update_call(handle);
-
- send_empty_reply(conn, message);
- return DBUS_HANDLER_RESULT_HANDLED;
-}
-
/* Handle incoming messages. */
static DBusHandlerResult
handle_telephony_message(DBusConnection *conn, DBusMessage *message, void *arg)
@@ -320,12 +274,6 @@ handle_telephony_message(DBusConnection *conn, DBusMessage *message, void *arg)
} else if (dbus_message_is_method_call(
message, CRAS_TELEPHONY_INTERFACE, "SetCallheld")) {
return handle_set_callheld(conn, message, arg);
- } else if (dbus_message_is_method_call(
- message, CRAS_TELEPHONY_INTERFACE, "SetCallsetup")) {
- return handle_set_callsetup(conn, message, arg);
- } else if (dbus_message_is_method_call(
- message, CRAS_TELEPHONY_INTERFACE, "SetCall")) {
- return handle_set_call(conn, message, arg);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
diff --git a/cras/src/server/cras_udev.c b/cras/src/server/cras_udev.c
index 16f0e3b2..dc4c2dd8 100644
--- a/cras/src/server/cras_udev.c
+++ b/cras/src/server/cras_udev.c
@@ -271,7 +271,7 @@ static void fill_usb_card_info(struct cras_alsa_card_info *card_info,
card_info->usb_desc_checksum = calculate_desc_checksum(parent_dev);
- syslog(LOG_INFO,
+ syslog(LOG_ERR,
"USB card: vendor:%04x, product:%04x, serial num:%s, "
"checksum:%08x",
card_info->usb_vendor_id, card_info->usb_product_id,
@@ -367,7 +367,7 @@ static void enumerate_devices(struct udev_callback_data *data)
udev_enumerate_unref(enumerate);
}
-static void udev_sound_subsystem_callback(void *arg, int revents)
+static void udev_sound_subsystem_callback(void *arg)
{
struct udev_callback_data *data = (struct udev_callback_data *)arg;
struct udev_device *dev;
@@ -408,9 +408,8 @@ void cras_udev_start_sound_subsystem_monitor()
udev_monitor_enable_receiving(udev_data.mon);
udev_data.fd = udev_monitor_get_fd(udev_data.mon);
- r = cras_system_add_select_fd(udev_data.fd,
- udev_sound_subsystem_callback, &udev_data,
- POLLIN);
+ r = cras_system_add_select_fd(
+ udev_data.fd, udev_sound_subsystem_callback, &udev_data);
assert(r == 0);
compile_regex(&pcm_regex, pcm_regex_string);
compile_regex(&card_regex, card_regex_string);
diff --git a/cras/src/server/cras_unified_rclient.c b/cras/src/server/cras_unified_rclient.c
deleted file mode 100644
index cdb7b47d..00000000
--- a/cras/src/server/cras_unified_rclient.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <syslog.h>
-
-#include "cras_iodev_list.h"
-#include "cras_messages.h"
-#include "cras_observer.h"
-#include "cras_rclient.h"
-#include "cras_rclient_util.h"
-#include "cras_rstream.h"
-#include "cras_types.h"
-#include "cras_util.h"
-
-/* Declarations of cras_rclient operators for cras_unified_rclient. */
-static const struct cras_rclient_ops cras_unified_rclient_ops = {
- .handle_message_from_client = rclient_handle_message_from_client,
- .send_message_to_client = rclient_send_message_to_client,
- .destroy = rclient_destroy,
-};
-
-/*
- * Exported Functions.
- */
-
-/* Creates a client structure and sends a message back informing the client that
- * the connection has succeeded. */
-struct cras_rclient *cras_unified_rclient_create(int fd, size_t id)
-{
- int supported_directions =
- cras_stream_direction_mask(CRAS_STREAM_OUTPUT) |
- cras_stream_direction_mask(CRAS_STREAM_INPUT);
- return rclient_generic_create(fd, id, &cras_unified_rclient_ops,
- supported_directions);
-}
diff --git a/cras/src/server/cras_unified_rclient.h b/cras/src/server/cras_unified_rclient.h
deleted file mode 100644
index 19973f88..00000000
--- a/cras/src/server/cras_unified_rclient.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef CRAS_UNIFIED_RCLIENT_H_
-#define CRAS_UNIFIED_RCLIENT_H_
-
-struct cras_rclient;
-
-/* Creates a unified rclient structure. This client supports only playback
- * and capture functions but not control features.
- * Args:
- * fd - The file descriptor used for communication with the client.
- * id - Unique identifier for this client.
- * Returns:
- * A pointer to the newly created rclient on success, NULL on failure.
- */
-struct cras_rclient *cras_unified_rclient_create(int fd, size_t id);
-
-#endif /* CRAS_UNIFIED_RCLIENT_H_ */
diff --git a/cras/src/server/dev_io.c b/cras/src/server/dev_io.c
index b311b221..97c61f92 100644
--- a/cras/src/server/dev_io.c
+++ b/cras/src/server/dev_io.c
@@ -10,7 +10,6 @@
#include "audio_thread_log.h"
#include "cras_audio_area.h"
#include "cras_audio_thread_monitor.h"
-#include "cras_device_monitor.h"
#include "cras_iodev.h"
#include "cras_non_empty_audio_handler.h"
#include "cras_rstream.h"
@@ -48,78 +47,33 @@ static const int DROP_FRAMES_THRESHOLD_MS = 50;
/* The number of devices playing/capturing non-empty stream(s). */
static int non_empty_device_count = 0;
-/* The timestamp of last EIO error time. */
-static struct timespec last_io_err_time = { 0, 0 };
-
-/* The gap time to avoid repeated error close request to main thread. */
-static const int ERROR_CLOSE_GAP_TIME_SECS = 10;
-
-/* Gets the main device which the stream is attached to. */
-static inline struct cras_iodev *get_main_dev(const struct dev_stream *stream)
+/* Gets the master device which the stream is attached to. */
+static inline struct cras_iodev *get_master_dev(const struct dev_stream *stream)
{
- return (struct cras_iodev *)stream->stream->main_dev.dev_ptr;
+ return (struct cras_iodev *)stream->stream->master_dev.dev_ptr;
}
/* Updates the estimated sample rate of open device to all attached
* streams.
*/
-static void update_estimated_rate(struct open_dev *adev,
- struct open_dev *odev_list,
- bool self_rate_need_update)
+static void update_estimated_rate(struct open_dev *adev)
{
- struct cras_iodev *main_dev;
+ struct cras_iodev *master_dev;
struct cras_iodev *dev = adev->dev;
- struct cras_iodev *tracked_dev = NULL;
struct dev_stream *dev_stream;
- double dev_rate_ratio;
- double main_dev_rate_ratio;
-
- /*
- * If there is an output device on the same sound card running with the same
- * sampling rate, use the rate of that output device for this device.
- */
- if (dev->direction == CRAS_STREAM_INPUT &&
- cras_iodev_is_on_internal_card(dev->active_node)) {
- struct open_dev *odev;
- DL_FOREACH (odev_list, odev) {
- if (!cras_iodev_is_on_internal_card(
- odev->dev->active_node))
- continue;
- if (odev->dev->format->frame_rate !=
- dev->format->frame_rate)
- continue;
- tracked_dev = odev->dev;
- break;
- }
- }
-
- /*
- * Self-owned rate esimator does not need to udpate rate. There is no tracked
- * output device. So there is no need to update.
- */
- if (!self_rate_need_update && !tracked_dev)
- return;
DL_FOREACH (dev->streams, dev_stream) {
- main_dev = get_main_dev(dev_stream);
- if (main_dev == NULL) {
- syslog(LOG_ERR, "Fail to find main open dev.");
+ master_dev = get_master_dev(dev_stream);
+ if (master_dev == NULL) {
+ syslog(LOG_ERR, "Fail to find master open dev.");
continue;
}
- if (tracked_dev) {
- dev_rate_ratio =
- cras_iodev_get_est_rate_ratio(tracked_dev);
- main_dev_rate_ratio = dev_rate_ratio;
- } else {
- dev_rate_ratio = cras_iodev_get_est_rate_ratio(dev);
- main_dev_rate_ratio =
- cras_iodev_get_est_rate_ratio(main_dev);
- }
-
- dev_stream_set_dev_rate(dev_stream, dev->format->frame_rate,
- dev_rate_ratio, main_dev_rate_ratio,
- adev->coarse_rate_adjust);
+ dev_stream_set_dev_rate(
+ dev_stream, dev->format->frame_rate,
+ cras_iodev_get_est_rate_ratio(dev),
+ cras_iodev_get_est_rate_ratio(master_dev),
+ adev->coarse_rate_adjust);
}
}
@@ -138,7 +92,7 @@ static inline int count_non_empty_dev(struct open_dev *adevs)
return count;
}
-int dev_io_check_non_empty_state_transition(struct open_dev *adevs)
+static void check_non_empty_state_transition(struct open_dev *adevs)
{
int new_non_empty_dev_count = count_non_empty_dev(adevs);
@@ -149,7 +103,6 @@ int dev_io_check_non_empty_state_transition(struct open_dev *adevs)
0);
non_empty_device_count = new_non_empty_dev_count;
- return non_empty_device_count > 0;
}
/* Checks whether it is time to fetch. */
@@ -172,19 +125,6 @@ static bool is_time_to_fetch(const struct dev_stream *dev_stream,
return 0;
}
-/* The log only accepts uint32 arguments, so the float power
- * must be written as bits and assumed to have a float when
- * parsing the log.
- */
-static uint32_t get_ewma_power_as_int(struct ewma_power *ewma)
-{
- uint32_t pow_as_int = 0;
-
- if (sizeof(uint32_t) == sizeof(float))
- memcpy(&pow_as_int, &ewma->power, sizeof(uint32_t));
- return pow_as_int;
-}
-
/* Asks any stream with room for more data. Sets the time stamp for all streams.
* Args:
* adev - The output device streams are attached to.
@@ -246,15 +186,13 @@ static int fetch_streams(struct open_dev *adev)
shm->header->write_offset[0],
shm->header->write_offset[1]);
dev_stream_update_next_wake_time(dev_stream);
- cras_server_metrics_missed_cb_event(dev_stream->stream);
continue;
}
dev_stream_set_delay(dev_stream, delay);
ATLOG(atlog, AUDIO_THREAD_FETCH_STREAM, rstream->stream_id,
- cras_rstream_get_cb_threshold(rstream),
- get_ewma_power_as_int(&rstream->ewma));
+ cras_rstream_get_cb_threshold(rstream), delay);
rc = dev_stream_request_playback_samples(dev_stream, &now);
if (rc < 0) {
@@ -404,9 +342,7 @@ static bool input_devices_can_drop_samples(struct cras_iodev *iodev)
if (!iodev->streams)
return false;
if (!iodev->active_node ||
- iodev->active_node->type == CRAS_NODE_TYPE_HOTWORD ||
- iodev->active_node->type == CRAS_NODE_TYPE_POST_MIX_PRE_DSP ||
- iodev->active_node->type == CRAS_NODE_TYPE_POST_DSP)
+ iodev->active_node->type == CRAS_NODE_TYPE_HOTWORD)
return false;
return true;
}
@@ -446,14 +382,11 @@ static int set_input_dev_wake_ts(struct open_dev *adev, bool *need_to_drop)
clock_gettime(CLOCK_MONOTONIC_RAW, &level_tstamp);
/*
- * Drop frames from all devices if any device meets these requirements:
- * 1. The hw_level is larger than largest_cb_level * 1.5 or larger than
- * buffer_size * 0.5.
- * 2. The time of those frames is larger than DROP_FRAMES_THRESHOLD_MS.
+ * If any input device has more than largest_cb_level * 1.5 frames, need to
+ * drop frames from all devices.
*/
if (input_devices_can_drop_samples(adev->dev) &&
- (rc >= adev->dev->largest_cb_level * 1.5 ||
- rc >= adev->dev->buffer_size * 0.5) &&
+ rc >= adev->dev->largest_cb_level * 1.5 &&
cras_frames_to_ms(rc, adev->dev->format->frame_rate) >=
DROP_FRAMES_THRESHOLD_MS)
*need_to_drop = true;
@@ -510,7 +443,7 @@ static int set_input_dev_wake_ts(struct open_dev *adev, bool *need_to_drop)
* adev - The device to capture samples from.
* Returns 0 on success.
*/
-static int capture_to_streams(struct open_dev *adev, struct open_dev *odev_list)
+static int capture_to_streams(struct open_dev *adev)
{
struct cras_iodev *idev = adev->dev;
snd_pcm_uframes_t remainder, hw_level, cap_limit;
@@ -532,29 +465,14 @@ static int capture_to_streams(struct open_dev *adev, struct open_dev *odev_list)
ATLOG(atlog, AUDIO_THREAD_READ_AUDIO_TSTAMP, idev->info.idx,
hw_tstamp.tv_sec, hw_tstamp.tv_nsec);
if (timespec_is_nonzero(&hw_tstamp)) {
- bool self_rate_need_update;
-
if (hw_level < idev->min_cb_level / 2)
adev->coarse_rate_adjust = 1;
else if (hw_level > idev->max_cb_level * 2)
adev->coarse_rate_adjust = -1;
else
adev->coarse_rate_adjust = 0;
-
- /*
- * This values means whether the rate estimator in the device
- * wants to update estimated rate.
- */
- self_rate_need_update =
- !!cras_iodev_update_rate(idev, hw_level, &hw_tstamp);
-
- /*
- * Always calls update_estimated_rate so that new output rate
- * has a chance to propagate to input. In update_estimated_rate,
- * it will decide whether the new rate is from self rate estimator
- * or from the tracked output device.
- */
- update_estimated_rate(adev, odev_list, self_rate_need_update);
+ if (cras_iodev_update_rate(idev, hw_level, &hw_tstamp))
+ update_estimated_rate(adev);
}
cap_limit = get_stream_limit(adev, hw_level, &cap_limit_stream);
@@ -591,19 +509,24 @@ static int capture_to_streams(struct open_dev *adev, struct open_dev *odev_list)
stream->stream,
idev->buf_state, &area,
&area_offset);
-
/*
- * The UI gain scaler should always take effect.
- * input_data will decide if stream and iodev internal
- * software gains should be used or not, based on use
- * case.
+ * The software gain scaler consist of two parts:
+ * (1) The device gain scaler used when lack of hardware
+ * gain control. Configured by the DefaultNodeGain label
+ * in alsa UCM config.
+ * (2) The gain scaler in cras_rstream set by app, for
+ * example the AGC module in Chrome.
+ *
+ * APM has more advanced gain control mechanism, we shall
+ * give APM total control of the captured samples without
+ * additional gain scaler at all.
*/
software_gain_scaler =
- cras_iodev_get_ui_gain_scaler(idev) *
- input_data_get_software_gain_scaler(
- idev->input_data,
- idev->software_gain_scaler,
- stream->stream);
+ stream->stream->apm_list ?
+ 1.0f :
+ idev->software_gain_scaler *
+ cras_rstream_get_volume_scaler(
+ stream->stream);
this_read =
dev_stream_capture(stream, area, area_offset,
@@ -625,8 +548,7 @@ static int capture_to_streams(struct open_dev *adev, struct open_dev *odev_list)
break;
}
- ATLOG(atlog, AUDIO_THREAD_READ_AUDIO_DONE, remainder,
- get_ewma_power_as_int(&idev->ewma), 0);
+ ATLOG(atlog, AUDIO_THREAD_READ_AUDIO_DONE, remainder, 0, 0);
return 0;
}
@@ -640,13 +562,12 @@ static int capture_to_streams(struct open_dev *adev, struct open_dev *odev_list)
* write_limit - The maximum number of frames to write to dst.
*
* Returns:
- * The number of frames rendered on success.
+ * The number of frames rendered on success, a negative error code otherwise.
* This number of frames is the minimum of the amount of frames each stream
* could provide which is the maximum that can currently be rendered.
*/
-static unsigned int write_streams(struct open_dev **odevs,
- struct open_dev *adev, uint8_t *dst,
- size_t write_limit)
+static int write_streams(struct open_dev **odevs, struct open_dev *adev,
+ uint8_t *dst, size_t write_limit)
{
struct cras_iodev *odev = adev->dev;
struct dev_stream *curr;
@@ -808,10 +729,9 @@ int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
adev->coarse_rate_adjust = 0;
if (cras_iodev_update_rate(odev, hw_level, &hw_tstamp))
- update_estimated_rate(adev, NULL, true);
+ update_estimated_rate(adev);
}
- ATLOG(atlog, AUDIO_THREAD_FILL_AUDIO, adev->dev->info.idx, hw_level,
- odev->min_cb_level);
+ ATLOG(atlog, AUDIO_THREAD_FILL_AUDIO, adev->dev->info.idx, hw_level, 0);
/* Don't request more than hardware can hold. Note that min_buffer_level
* has been subtracted from the actual hw_level so we need to take it
@@ -830,6 +750,9 @@ int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
/* TODO(dgreid) - This assumes interleaved audio. */
dst = area->channels[0].buf;
written = write_streams(odevs, adev, dst, frames);
+ if (written < 0) /* pcm has been closed */
+ return (int)written;
+
if (written < (snd_pcm_sframes_t)frames)
/* Got all the samples from client that we can, but it
* won't fill the request. */
@@ -872,7 +795,7 @@ int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
}
ATLOG(atlog, AUDIO_THREAD_FILL_AUDIO_DONE, hw_level, total_written,
- get_ewma_power_as_int(&odev->ewma));
+ odev->min_cb_level);
return total_written;
}
@@ -928,7 +851,7 @@ static void get_input_devices_drop_time(struct open_dev *idev_list,
static void dev_io_drop_samples(struct open_dev *idev_list)
{
struct open_dev *adev;
- struct timespec drop_time = {};
+ struct timespec drop_time;
int rc;
get_input_devices_drop_time(idev_list, &drop_time);
@@ -993,46 +916,26 @@ int dev_io_send_captured_samples(struct open_dev *idev_list)
static void handle_dev_err(int err_rc, struct open_dev **odevs,
struct open_dev *adev)
{
- struct timespec diff, now;
if (err_rc == -EPIPE) {
/* Handle severe underrun. */
ATLOG(atlog, AUDIO_THREAD_SEVERE_UNDERRUN, adev->dev->info.idx,
0, 0);
cras_iodev_reset_request(adev->dev);
- cras_audio_thread_event_severe_underrun();
- } else if (err_rc == -EIO) {
- syslog(LOG_WARNING, "I/O err, reseting %s dev %s",
- adev->dev->direction == CRAS_STREAM_OUTPUT ? "output" :
- "input",
- adev->dev->info.name);
- clock_gettime(CLOCK_REALTIME, &now);
- subtract_timespecs(&now, &last_io_err_time, &diff);
- if ((last_io_err_time.tv_sec == 0 &&
- last_io_err_time.tv_nsec == 0) ||
- diff.tv_sec > ERROR_CLOSE_GAP_TIME_SECS)
- cras_iodev_reset_request(adev->dev);
- else
- cras_device_monitor_error_close(adev->dev->info.idx);
-
- last_io_err_time = now;
- } else {
- syslog(LOG_ERR, "Dev %s err %d", adev->dev->info.name, err_rc);
}
/* Device error, remove it. */
dev_io_rm_open_dev(odevs, adev);
}
-int dev_io_capture(struct open_dev **list, struct open_dev **olist)
+int dev_io_capture(struct open_dev **list)
{
struct open_dev *idev_list = *list;
- struct open_dev *odev_list = *olist;
struct open_dev *adev;
int rc;
DL_FOREACH (idev_list, adev) {
if (!cras_iodev_is_open(adev->dev))
continue;
- rc = capture_to_streams(adev, odev_list);
+ rc = capture_to_streams(adev);
if (rc < 0)
handle_dev_err(rc, list, adev);
}
@@ -1125,8 +1028,10 @@ int dev_io_playback_write(struct open_dev **odevs,
* we should handle it.
*/
if (hw_level <= total_written) {
- rc = cras_iodev_output_underrun(
- adev->dev, hw_level, total_written);
+ ATLOG(atlog, AUDIO_THREAD_UNDERRUN,
+ adev->dev->info.idx, hw_level,
+ total_written);
+ rc = cras_iodev_output_underrun(adev->dev);
if (rc < 0) {
handle_dev_err(rc, odevs, adev);
} else {
@@ -1183,9 +1088,11 @@ void dev_io_run(struct open_dev **odevs, struct open_dev **idevs,
update_longest_wake(*idevs, &now);
dev_io_playback_fetch(*odevs);
- dev_io_capture(idevs, odevs);
+ dev_io_capture(idevs);
dev_io_send_captured_samples(*idevs);
dev_io_playback_write(odevs, output_converter);
+
+ check_non_empty_state_transition(*odevs);
}
static int input_adev_ignore_wake(const struct open_dev *adev)
@@ -1252,7 +1159,8 @@ static int get_next_stream_wake_from_list(struct dev_stream *streams,
return ret;
}
-int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts)
+int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts,
+ const struct timespec *now)
{
struct open_dev *adev;
int ret = 0;
@@ -1311,7 +1219,7 @@ void dev_io_rm_open_dev(struct open_dev **odev_list, struct open_dev *dev_to_rm)
cras_server_metrics_highest_hw_level(dev_to_rm->dev->highest_hw_level,
dev_to_rm->dev->direction);
- dev_io_check_non_empty_state_transition(*odev_list);
+ check_non_empty_state_transition(*odev_list);
ATLOG(atlog, AUDIO_THREAD_DEV_REMOVED, dev_to_rm->dev->info.idx, 0, 0);
@@ -1337,61 +1245,14 @@ static void delete_stream_from_dev(struct cras_iodev *dev,
dev_stream_destroy(out);
}
-/*
- * Finds a matched input stream from open device list.
- * The definition of the matched streams: Two streams having
- * the same sampling rate and the same cb_threshold.
- * This means their sleep time intervals should be very close
- * if we neglect device estimated rate.
- */
-static struct dev_stream *
-find_matched_input_stream(const struct cras_rstream *out_stream,
- struct open_dev *odev_list)
-{
- struct open_dev *odev;
- struct dev_stream *dev_stream;
- size_t out_rate = out_stream->format.frame_rate;
- size_t out_cb_threshold = cras_rstream_get_cb_threshold(out_stream);
-
- DL_FOREACH (odev_list, odev) {
- DL_FOREACH (odev->dev->streams, dev_stream) {
- if (dev_stream->stream->format.frame_rate != out_rate)
- continue;
- if (cras_rstream_get_cb_threshold(dev_stream->stream) !=
- out_cb_threshold)
- continue;
- return dev_stream;
- }
- }
- return NULL;
-}
-
-static bool
-find_matched_input_stream_next_cb_ts(const struct cras_rstream *stream,
- struct open_dev *odev_list,
- const struct timespec **next_cb_ts,
- const struct timespec **sleep_interval_ts)
-{
- struct dev_stream *dev_stream =
- find_matched_input_stream(stream, odev_list);
- if (dev_stream) {
- *next_cb_ts = dev_stream_next_cb_ts(dev_stream);
- *sleep_interval_ts = dev_stream_sleep_interval_ts(dev_stream);
- return *next_cb_ts != NULL;
- }
- return false;
-}
-
-int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
+int dev_io_append_stream(struct open_dev **dev_list,
struct cras_rstream *stream,
struct cras_iodev **iodevs, unsigned int num_iodevs)
{
- struct open_dev **dev_list;
struct open_dev *open_dev;
struct cras_iodev *dev;
struct dev_stream *out;
struct timespec init_cb_ts;
- const struct timespec *init_sleep_interval_ts = NULL;
struct timespec extra_sleep;
const struct timespec *stream_ts;
unsigned int i;
@@ -1399,11 +1260,6 @@ int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
int level;
int rc = 0;
- if (stream->direction == CRAS_STREAM_OUTPUT)
- dev_list = odevs;
- else
- dev_list = idevs;
-
for (i = 0; i < num_iodevs; i++) {
DL_SEARCH_SCALAR(*dev_list, open_dev, dev, iodevs[i]);
if (!open_dev)
@@ -1448,55 +1304,35 @@ int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
* may cause device buffer level stack up.
*/
if (stream->direction == CRAS_STREAM_OUTPUT) {
- /*
- * If there is a matched input stream, find its next cb time.
- * Use that as the initial cb time for this output stream.
- */
- const struct timespec *in_stream_ts;
- const struct timespec *in_stream_sleep_interval_ts;
- bool found_matched_input;
- found_matched_input =
- find_matched_input_stream_next_cb_ts(
- stream, *idevs, &in_stream_ts,
- &in_stream_sleep_interval_ts);
- if (found_matched_input) {
- init_cb_ts = *in_stream_ts;
- init_sleep_interval_ts =
- in_stream_sleep_interval_ts;
- } else {
- DL_FOREACH (dev->streams, out) {
- stream_ts = dev_stream_next_cb_ts(out);
- if (stream_ts &&
- (!cb_ts_set ||
- timespec_after(&init_cb_ts,
- stream_ts))) {
- init_cb_ts = *stream_ts;
- cb_ts_set = true;
- }
+ DL_FOREACH (dev->streams, out) {
+ stream_ts = dev_stream_next_cb_ts(out);
+ if (stream_ts &&
+ (!cb_ts_set ||
+ timespec_after(&init_cb_ts, stream_ts))) {
+ init_cb_ts = *stream_ts;
+ cb_ts_set = true;
}
- if (!cb_ts_set) {
- level = cras_iodev_get_valid_frames(
- dev, &init_cb_ts);
- if (level < 0) {
- syslog(LOG_ERR,
- "Failed to set output init_cb_ts, rc = %d",
- level);
- rc = -EINVAL;
- break;
- }
- level -= cras_frames_at_rate(
- stream->format.frame_rate,
- cras_rstream_get_cb_threshold(
- stream),
- dev->format->frame_rate);
- if (level < 0)
- level = 0;
- cras_frames_to_time(
- level, dev->format->frame_rate,
- &extra_sleep);
- add_timespecs(&init_cb_ts,
- &extra_sleep);
+ }
+ if (!cb_ts_set) {
+ level = cras_iodev_get_valid_frames(
+ dev, &init_cb_ts);
+ if (level < 0) {
+ syslog(LOG_ERR,
+ "Failed to set output init_cb_ts, rc = %d",
+ level);
+ rc = -EINVAL;
+ break;
}
+ level -= cras_frames_at_rate(
+ stream->format.frame_rate,
+ cras_rstream_get_cb_threshold(stream),
+ dev->format->frame_rate);
+ if (level < 0)
+ level = 0;
+ cras_frames_to_time(level,
+ dev->format->frame_rate,
+ &extra_sleep);
+ add_timespecs(&init_cb_ts, &extra_sleep);
}
} else {
/*
@@ -1515,7 +1351,7 @@ int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
}
out = dev_stream_create(stream, dev->info.idx, dev->format, dev,
- &init_cb_ts, init_sleep_interval_ts);
+ &init_cb_ts);
if (!out) {
rc = -EINVAL;
break;
@@ -1568,6 +1404,20 @@ int dev_io_remove_stream(struct open_dev **dev_list,
struct cras_rstream *stream, struct cras_iodev *dev)
{
struct open_dev *open_dev;
+ struct timespec delay;
+ unsigned fetch_delay_msec;
+
+ /* Metrics log the longest fetch delay of this stream. */
+ if (timespec_after(&stream->longest_fetch_interval,
+ &stream->sleep_interval_ts)) {
+ subtract_timespecs(&stream->longest_fetch_interval,
+ &stream->sleep_interval_ts, &delay);
+ fetch_delay_msec =
+ delay.tv_sec * 1000 + delay.tv_nsec / 1000000;
+ if (fetch_delay_msec)
+ cras_server_metrics_longest_fetch_delay(
+ fetch_delay_msec);
+ }
ATLOG(atlog, AUDIO_THREAD_STREAM_REMOVED, stream->stream_id, 0, 0);
diff --git a/cras/src/server/dev_io.h b/cras/src/server/dev_io.h
index ca71a809..3184e4c8 100644
--- a/cras/src/server/dev_io.h
+++ b/cras/src/server/dev_io.h
@@ -58,9 +58,8 @@ int write_output_samples(struct open_dev **odevs, struct open_dev *adev,
* Captures samples from each device in the list.
* list - Pointer to the list of input devices. Devices that fail to read
* will be removed from the list.
- * olist - Pointer to the list of output devices.
*/
-int dev_io_capture(struct open_dev **list, struct open_dev **olist);
+int dev_io_capture(struct open_dev **list);
/*
* Send samples that have been captured to their streams.
@@ -72,12 +71,6 @@ void dev_io_run(struct open_dev **odevs, struct open_dev **idevs,
struct cras_fmt_conv *output_converter);
/*
- * Checks the non-empty device state in active output lists and return
- * if there's at least one non-empty device.
- */
-int dev_io_check_non_empty_state_transition(struct open_dev *adevs);
-
-/*
* Fills min_ts with the next time the system should wake to service input.
* Returns the number of devices waiting.
*/
@@ -87,7 +80,8 @@ int dev_io_next_input_wake(struct open_dev **idevs, struct timespec *min_ts);
* Fills min_ts with the next time the system should wake to service output.
* Returns the number of devices waiting.
*/
-int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts);
+int dev_io_next_output_wake(struct open_dev **odevs, struct timespec *min_ts,
+ const struct timespec *now);
/*
* Removes a device from a list of devices.
@@ -102,7 +96,7 @@ struct open_dev *dev_io_find_open_dev(struct open_dev *odev_list,
unsigned int dev_idx);
/* Append a new stream to a specified set of iodevs. */
-int dev_io_append_stream(struct open_dev **odevs, struct open_dev **idevs,
+int dev_io_append_stream(struct open_dev **dev_list,
struct cras_rstream *stream,
struct cras_iodev **iodevs, unsigned int num_iodevs);
diff --git a/cras/src/server/dev_stream.c b/cras/src/server/dev_stream.c
index be5a6dab..878bb8a7 100644
--- a/cras/src/server/dev_stream.c
+++ b/cras/src/server/dev_stream.c
@@ -63,8 +63,7 @@ unsigned int max_frames_for_conversion(unsigned int stream_frames,
struct dev_stream *dev_stream_create(struct cras_rstream *stream,
unsigned int dev_id,
const struct cras_audio_format *dev_fmt,
- void *dev_ptr, struct timespec *cb_ts,
- const struct timespec *sleep_interval_ts)
+ void *dev_ptr, struct timespec *cb_ts)
{
struct dev_stream *out;
struct cras_audio_format *stream_fmt = &stream->format;
@@ -88,12 +87,9 @@ struct dev_stream *dev_stream_create(struct cras_rstream *stream,
} else {
/*
* For input, take into account the stream specific processing
- * like AEC. APM exists only in input path, and has no dependency
- * to dev_stream. Starts APM in dev_stream's constructor just to
- * align with its life cycle, and then gets the post processing
- * format to configure format converter.
+ * like AEC. Use the post processing format to configure format
+ * converter.
*/
- cras_apm_list_start_apm(stream->apm_list, dev_ptr);
ofmt = cras_rstream_post_processing_format(stream, dev_ptr) ?:
dev_fmt,
rc = config_format_converter(&out->conv, stream->direction,
@@ -123,18 +119,10 @@ struct dev_stream *dev_stream_create(struct cras_rstream *stream,
out->conv_buffer = byte_buffer_create(buf_bytes);
out->conv_area = cras_audio_area_create(ofmt->num_channels);
- /* Use sleep interval hint from argument if it is provided */
- if (sleep_interval_ts) {
- stream->sleep_interval_ts = *sleep_interval_ts;
- } else {
- cras_frames_to_time(cras_rstream_get_cb_threshold(stream),
- stream_fmt->frame_rate,
- &stream->sleep_interval_ts);
- }
-
+ cras_frames_to_time(cras_rstream_get_cb_threshold(stream),
+ stream_fmt->frame_rate, &stream->sleep_interval_ts);
stream->next_cb_ts = *cb_ts;
- /* Sets up the stream & dev pair. */
cras_rstream_dev_attach(stream, dev_id, dev_ptr);
return out;
@@ -142,10 +130,6 @@ struct dev_stream *dev_stream_create(struct cras_rstream *stream,
void dev_stream_destroy(struct dev_stream *dev_stream)
{
- void *dev_ptr =
- cras_rstream_dev_ptr(dev_stream->stream, dev_stream->dev_id);
- /* Stops the APM and then unlink the dev stream pair. */
- cras_apm_list_stop_apm(dev_stream->stream->apm_list, dev_ptr);
cras_rstream_dev_detach(dev_stream->stream, dev_stream->dev_id);
if (dev_stream->conv) {
cras_audio_area_destroy(dev_stream->conv_area);
@@ -157,9 +141,9 @@ void dev_stream_destroy(struct dev_stream *dev_stream)
void dev_stream_set_dev_rate(struct dev_stream *dev_stream,
unsigned int dev_rate, double dev_rate_ratio,
- double main_rate_ratio, int coarse_rate_adjust)
+ double master_rate_ratio, int coarse_rate_adjust)
{
- if (dev_stream->dev_id == dev_stream->stream->main_dev.dev_id) {
+ if (dev_stream->dev_id == dev_stream->stream->master_dev.dev_id) {
cras_fmt_conv_set_linear_resample_rates(dev_stream->conv,
dev_rate, dev_rate);
cras_frames_to_time_precise(
@@ -167,8 +151,9 @@ void dev_stream_set_dev_rate(struct dev_stream *dev_stream,
dev_stream->stream->format.frame_rate * dev_rate_ratio,
&dev_stream->stream->sleep_interval_ts);
} else {
- double new_rate = dev_rate * dev_rate_ratio / main_rate_ratio +
- coarse_rate_adjust_step * coarse_rate_adjust;
+ double new_rate =
+ dev_rate * dev_rate_ratio / master_rate_ratio +
+ coarse_rate_adjust_step * coarse_rate_adjust;
cras_fmt_conv_set_linear_resample_rates(dev_stream->conv,
dev_rate, new_rate);
}
@@ -268,8 +253,7 @@ static unsigned int capture_with_fmt_conv(struct dev_stream *dev_stream,
total_read += read_frames;
source_samples += read_frames * source_frame_bytes;
buf_increment_write(dev_stream->conv_buffer,
- (size_t)write_frames *
- (size_t)dst_frame_bytes);
+ write_frames * dst_frame_bytes);
}
return total_read;
@@ -327,7 +311,7 @@ capture_copy_converted_to_stream(struct dev_stream *dev_stream,
software_gain_scaler);
buf_increment_read(dev_stream->conv_buffer,
- (size_t)write_frames * (size_t)frame_bytes);
+ write_frames * frame_bytes);
total_written += write_frames;
cras_rstream_dev_offset_update(rstream, write_frames,
dev_stream->dev_id);
diff --git a/cras/src/server/dev_stream.h b/cras/src/server/dev_stream.h
index 6b34d5d7..c39a8017 100644
--- a/cras/src/server/dev_stream.h
+++ b/cras/src/server/dev_stream.h
@@ -46,47 +46,30 @@ struct dev_stream {
int is_running;
};
-/*
- * Creates a dev_stream.
- *
- * Args:
- * stream - The associated rstream.
- * dev_id - Index of the device.
- * dev_fmt - The format of the device.
- * dev_ptr - A pointer to the device
- * cb_ts - A pointer to the initial callback time.
- * sleep_interval_ts - A pointer to the initial sleep interval.
- * Set to null to calculate the value from device rate and block size.
- * Note that we need this argument so that output device sleep interval
- * can use input device sleep interval in the beginning to have perfect
- * alignment in WebRTC use case.
- * Returns the pointer to the created dev_stream.
- */
struct dev_stream *dev_stream_create(struct cras_rstream *stream,
unsigned int dev_id,
const struct cras_audio_format *dev_fmt,
- void *dev_ptr, struct timespec *cb_ts,
- const struct timespec *sleep_interval_ts);
+ void *dev_ptr, struct timespec *cb_ts);
void dev_stream_destroy(struct dev_stream *dev_stream);
/*
* Update the estimated sample rate of the device. For multiple active
* devices case, the linear resampler will be configured by the estimated
- * rate ration of the main device and the current active device the
+ * rate ration of the master device and the current active device the
* rstream attaches to.
*
* Args:
* dev_stream - The structure holding the stream.
* dev_rate - The sample rate device is using.
* dev_rate_ratio - The ratio of estimated rate and used rate.
- * main_rate_ratio - The ratio of estimated rate and used rate of
- * main device.
+ * master_rate_ratio - The ratio of estimated rate and used rate of
+ * master device.
* coarse_rate_adjust - The flag to indicate the direction device
* sample rate should adjust to.
*/
void dev_stream_set_dev_rate(struct dev_stream *dev_stream,
unsigned int dev_rate, double dev_rate_ratio,
- double main_rate_ratio, int coarse_rate_adjust);
+ double master_rate_ratio, int coarse_rate_adjust);
/*
* Renders count frames from shm into dst. Updates count if anything is
diff --git a/cras/src/server/ewma_power.c b/cras/src/server/ewma_power.c
deleted file mode 100644
index 5270ef0e..00000000
--- a/cras/src/server/ewma_power.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "ewma_power.h"
-#include "math.h"
-
-/* One sample per 1ms. */
-#define EWMA_SAMPLE_RATE 1000
-
-/* Smooth factor for EWMA, 1 - expf(-1.0/(rate * 0.01))
- * where the 0.01 corresponds to 10ms interval that is chosen and
- * being used in Chrome for a long time.
- * Here the |rate| is set to the down sampled EWMA_SAMPLE_RATE and
- * whenever it changes the calculated |smooth_factor| should be updated
- * accordingly.
- */
-const static float smooth_factor = 0.095;
-
-void ewma_power_disable(struct ewma_power *ewma)
-{
- ewma->enabled = 0;
-}
-
-void ewma_power_init(struct ewma_power *ewma, unsigned int rate)
-{
- ewma->enabled = 1;
- ewma->power_set = 0;
- ewma->step_fr = rate / EWMA_SAMPLE_RATE;
-}
-
-void ewma_power_calculate(struct ewma_power *ewma, const int16_t *buf,
- unsigned int channels, unsigned int size)
-{
- int i, ch;
- float power, f;
-
- if (!ewma->enabled)
- return;
- for (i = 0; i < size; i += ewma->step_fr * channels) {
- power = 0.0f;
- for (ch = 0; ch < channels; ch++) {
- f = buf[i + ch] / 32768.0f;
- power += f * f / channels;
- }
- if (!ewma->power_set) {
- ewma->power = power;
- ewma->power_set = 1;
- } else {
- ewma->power = smooth_factor * power +
- (1 - smooth_factor) * ewma->power;
- }
- }
-}
-
-void ewma_power_calculate_area(struct ewma_power *ewma, const int16_t *buf,
- struct cras_audio_area *area, unsigned int size)
-{
- int i, ch;
- float power, f;
-
- if (!ewma->enabled)
- return;
- for (i = 0; i < size; i += ewma->step_fr * area->num_channels) {
- power = 0.0f;
- for (ch = 0; ch < area->num_channels; ch++) {
- if (area->channels[ch].ch_set == 0)
- continue;
- f = buf[i + ch] / 32768.0f;
- power += f * f / area->num_channels;
- }
- if (!ewma->power_set) {
- ewma->power = power;
- ewma->power_set = 1;
- } else {
- ewma->power = smooth_factor * power +
- (1 - smooth_factor) * ewma->power;
- }
- }
-}
diff --git a/cras/src/server/ewma_power.h b/cras/src/server/ewma_power.h
deleted file mode 100644
index 78d2e504..00000000
--- a/cras/src/server/ewma_power.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2020 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef EWMA_POWER_H_
-#define EWMA_POWER_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "cras_audio_area.h"
-
-/*
- * The exponentially weighted moving average power module used to
- * calculate the energe level in audio stream.
- * Members:
- * power_set - Flag to note if the first power value has set.
- * enabled - Flag to enable ewma calculation. Set to false to
- * make all calculations no-ops.
- * power - The power value.
- * step_fr - How many frames to sample one for EWMA calculation.
- */
-struct ewma_power {
- bool power_set;
- bool enabled;
- float power;
- unsigned int step_fr;
-};
-
-/*
- * Disables the ewma instance.
- */
-void ewma_power_disable(struct ewma_power *ewma);
-
-/*
- * Initializes the ewma_power object.
- * Args:
- * ewma - The ewma_power object to initialize.
- * rate - The sample rate of the audio data that the ewma object
- * will calculate power from.
- */
-void ewma_power_init(struct ewma_power *ewma, unsigned int rate);
-
-/*
- * Feeds an audio buffer to ewma_power object to calculate the
- * latest power value.
- * Args:
- * ewma - The ewma_power object to calculate power.
- * buf - Pointer to the audio data.
- * channels - Number of channels of the audio data.
- * size - Length in frames of the audio data.
- */
-void ewma_power_calculate(struct ewma_power *ewma, const int16_t *buf,
- unsigned int channels, unsigned int size);
-
-/*
- * Feeds non-interleaved audio data to ewma_power to calculate the
- * latest power value. This is similar to ewma_power_calculate but
- * accepts cras_audio_area.
- */
-void ewma_power_calculate_area(struct ewma_power *ewma, const int16_t *buf,
- struct cras_audio_area *area, unsigned int size);
-
-#endif /* EWMA_POWER_H_ */
diff --git a/cras/src/server/float_buffer.h b/cras/src/server/float_buffer.h
index ba3523d9..39a0187d 100644
--- a/cras/src/server/float_buffer.h
+++ b/cras/src/server/float_buffer.h
@@ -37,7 +37,7 @@ float_buffer_create(unsigned int max_size, unsigned int num_channels)
b->fp = (float **)malloc(num_channels * sizeof(float *));
b->buf = (struct byte_buffer *)calloc(
1, sizeof(struct byte_buffer) +
- sizeof(float) * max_size * num_channels);
+ max_size * num_channels * sizeof(float));
b->buf->max_size = max_size;
b->buf->used_size = max_size;
return b;
diff --git a/cras/src/server/iniparser_wrapper.h b/cras/src/server/iniparser_wrapper.h
index 89a213bb..b6d32f97 100644
--- a/cras/src/server/iniparser_wrapper.h
+++ b/cras/src/server/iniparser_wrapper.h
@@ -5,19 +5,11 @@
#ifndef INIPARSER_WRAPPER_H_
#define INIPARSER_WRAPPER_H_
-#ifdef HAVE_INIPARSER_INIPARSER_H
-#include <iniparser/iniparser.h>
-#else
#include <iniparser.h>
-#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-/* Allocate 63 chars + 1 for null where declared. */
-#define MAX_INI_NAME_LENGTH 63
-#define MAX_INI_KEY_LENGTH 63 /* names like "output_source:output_0" */
-
static inline dictionary *iniparser_load_wrapper(const char *ini_name)
{
struct stat st;
diff --git a/cras/src/server/input_data.c b/cras/src/server/input_data.c
index cc0f10ba..b52c1668 100644
--- a/cras/src/server/input_data.c
+++ b/cras/src/server/input_data.c
@@ -151,7 +151,7 @@ int input_data_get_for_stream(struct input_data *data,
struct cras_apm *apm;
int stream_offset = buffer_share_id_offset(offsets, stream->stream_id);
- apm = cras_apm_list_get_active_apm(stream, data->dev_ptr);
+ apm = cras_apm_list_get(stream->apm_list, data->dev_ptr);
if (apm == NULL) {
/*
* Case 1 and 2 from above example.
@@ -165,7 +165,7 @@ int input_data_get_for_stream(struct input_data *data,
apm_processed = cras_apm_list_process(apm, data->fbuffer,
stream_offset);
if (apm_processed < 0) {
- cras_apm_list_remove_apm(stream->apm_list, apm);
+ cras_apm_list_remove(stream->apm_list, apm);
return 0;
}
buffer_share_offset_update(offsets, stream->stream_id,
@@ -182,7 +182,7 @@ int input_data_put_for_stream(struct input_data *data,
struct buffer_share *offsets, unsigned int frames)
{
struct cras_apm *apm =
- cras_apm_list_get_active_apm(stream, data->dev_ptr);
+ cras_apm_list_get(stream->apm_list, data->dev_ptr);
if (apm)
cras_apm_list_put_processed(apm, frames);
@@ -191,20 +191,3 @@ int input_data_put_for_stream(struct input_data *data,
return 0;
}
-
-float input_data_get_software_gain_scaler(struct input_data *data,
- float idev_sw_gain_scaler,
- struct cras_rstream *stream)
-{
- struct cras_apm *apm;
- /*
- * APM has more advanced gain control mechanism. If it is using tuned
- * settings, give APM total control of the captured samples without
- * additional gain scaler at all.
- */
- apm = cras_apm_list_get_active_apm(stream, data->dev_ptr);
- if (apm && cras_apm_list_get_use_tuned_settings(apm))
- return 1.0f;
-
- return idev_sw_gain_scaler * cras_rstream_get_volume_scaler(stream);
-}
diff --git a/cras/src/server/input_data.h b/cras/src/server/input_data.h
index 7ac80be4..bb120b4f 100644
--- a/cras/src/server/input_data.h
+++ b/cras/src/server/input_data.h
@@ -75,21 +75,4 @@ int input_data_put_for_stream(struct input_data *data,
struct buffer_share *offsets,
unsigned int frames);
-/*
- * The software gain scaler of input path consist of two parts:
- * (1) The device gain scaler used when lack of hardware gain control.
- * Configured by the IntrinsicSensitivity label in alsa UCM config.
- * (2) The gain scaler in cras_rstream set by app, for example the AGC
- * module in Chrome.
- * Args:
- * data - The input data that holds pointer to APM instance.
- * idev_sw_agin_scaler - The gain scaler configured on input iodev.
- * stream - To provide stream layer software gain.
- * Returns:
- * 1.0 if tuned APM in use, otherwise |iodev gain| * |cras_rstream gain|
- */
-float input_data_get_software_gain_scaler(struct input_data *data,
- float idev_sw_gain_scaler,
- struct cras_rstream *stream);
-
#endif /* INPUT_DATA_H_ */
diff --git a/cras/src/server/rate_estimator.c b/cras/src/server/rate_estimator.c
new file mode 100644
index 00000000..4b1277e3
--- /dev/null
+++ b/cras/src/server/rate_estimator.c
@@ -0,0 +1,109 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include "math.h"
+
+#include "cras_util.h"
+#include "rate_estimator.h"
+
+/* The max rate skew that considered reasonable */
+#define MAX_RATE_SKEW 100
+
+static void least_square_reset(struct least_square *lsq)
+{
+ memset(lsq, 0, sizeof(*lsq));
+}
+
+void least_square_add_sample(struct least_square *lsq, double x, double y)
+{
+ lsq->sum_x += x;
+ lsq->sum_y += y;
+ lsq->sum_xy += x * y;
+ lsq->sum_x2 += x * x;
+ lsq->num_samples++;
+}
+
+double least_square_best_fit_slope(struct least_square *lsq)
+{
+ double num, denom;
+ num = lsq->num_samples * lsq->sum_xy - lsq->sum_x * lsq->sum_y;
+ denom = lsq->num_samples * lsq->sum_x2 - lsq->sum_x * lsq->sum_x;
+ return num / denom;
+}
+
+void rate_estimator_destroy(struct rate_estimator *re)
+{
+ if (re)
+ free(re);
+}
+
+struct rate_estimator *rate_estimator_create(unsigned int rate,
+ const struct timespec *window_size,
+ double smooth_factor)
+{
+ struct rate_estimator *re;
+
+ re = (struct rate_estimator *)calloc(1, sizeof(*re));
+ if (re == NULL)
+ return NULL;
+
+ re->window_size = *window_size;
+ re->estimated_rate = rate;
+ re->smooth_factor = smooth_factor;
+
+ return re;
+}
+
+void rate_estimator_add_frames(struct rate_estimator *re, int fr)
+{
+ re->level_diff += fr;
+}
+
+double rate_estimator_get_rate(struct rate_estimator *re)
+{
+ return re->estimated_rate;
+}
+
+void rate_estimator_reset_rate(struct rate_estimator *re, unsigned int rate)
+{
+ re->estimated_rate = rate;
+ least_square_reset(&re->lsq);
+ re->window_start_ts.tv_sec = 0;
+ re->window_start_ts.tv_nsec = 0;
+ re->window_frames = 0;
+ re->level_diff = 0;
+ re->last_level = 0;
+}
+
+int rate_estimator_check(struct rate_estimator *re, int level,
+ struct timespec *now)
+{
+ struct timespec td;
+
+ if (re->window_start_ts.tv_sec == 0) {
+ re->window_start_ts = *now;
+ return 0;
+ }
+
+ subtract_timespecs(now, &re->window_start_ts, &td);
+ re->window_frames += abs(re->last_level - level + re->level_diff);
+ re->level_diff = 0;
+ re->last_level = level;
+
+ least_square_add_sample(&re->lsq,
+ td.tv_sec + (double)td.tv_nsec / 1000000000L,
+ re->window_frames);
+ if (timespec_after(&td, &re->window_size) && re->lsq.num_samples > 1) {
+ double rate = least_square_best_fit_slope(&re->lsq);
+ if (fabs(re->estimated_rate - rate) < MAX_RATE_SKEW)
+ re->estimated_rate =
+ rate * (1 - re->smooth_factor) +
+ re->smooth_factor * re->estimated_rate;
+ least_square_reset(&re->lsq);
+ re->window_start_ts = *now;
+ re->window_frames = 0;
+ return 1;
+ }
+ return 0;
+}
diff --git a/cras/src/server/rate_estimator.h b/cras/src/server/rate_estimator.h
new file mode 100644
index 00000000..c9a5aff9
--- /dev/null
+++ b/cras/src/server/rate_estimator.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef RATE_ESTIMATOR_H_
+#define RATE_ESTIMATOR_H_
+
+#include <time.h>
+
+/* Hold information to calculate linear least square from
+ * several (x, y) samples.
+ */
+struct least_square {
+ double sum_x;
+ double sum_y;
+ double sum_xy;
+ double sum_x2;
+ int num_samples;
+};
+
+/* An estimator holding the required information to determine the actual frame
+ * rate of an audio device.
+ * Members:
+ * last_level - Buffer level of the audio device at last check time.
+ * level_diff - Number of frames written to or read from audio device since
+ * the last check time. Rate estimator will use this change plus the
+ * difference of buffer level to derive the number of frames audio
+ * device has actually processed.
+ * window_start_ts - The start time of the current window.
+ * window_size - The size of the window.
+ * window_frames - The number of frames accumulated in current window.
+ * lsq - The helper used to estimate sample rate.
+ */
+struct rate_estimator {
+ int last_level;
+ int level_diff;
+ struct timespec window_start_ts;
+ struct timespec window_size;
+ int window_frames;
+ struct least_square lsq;
+ double smooth_factor;
+ double estimated_rate;
+};
+
+/* Creates a rate estimator.
+ * Args:
+ * rate - The initial value to estimate rate from.
+ * window_size - The window size of the rate estimator.
+ * smooth_factor - The coefficient used to calculate moving average
+ * from old estimated rate values.
+ */
+struct rate_estimator *rate_estimator_create(unsigned int rate,
+ const struct timespec *window_size,
+ double smooth_factor);
+/* Destroy a rate estimator. */
+void rate_estimator_destroy(struct rate_estimator *re);
+
+/* Adds additional frames transmitted to/from audio device.
+ * Args:
+ * re - The rate estimator.
+ * fr - The number of frames written to the device. For input, this should
+ * be negative to indicate how many samples were read.
+ */
+void rate_estimator_add_frames(struct rate_estimator *re, int fr);
+
+/* Checks the timestamp and buffer level difference since last check time,
+ * and use them as a new sample to update the estimated rate.
+ * Args:
+ * re - The rate estimator.
+ * level - The current buffer level of audio device.
+ * now - The time at which this function is called.
+ * Returns:
+ * True if the estimated rate is updated and window is reset,
+ * otherwise false.
+ */
+int rate_estimator_check(struct rate_estimator *re, int level,
+ struct timespec *now);
+
+/* Gets the estimated rate. */
+double rate_estimator_get_rate(struct rate_estimator *re);
+
+/* Resets the estimated rate. */
+void rate_estimator_reset_rate(struct rate_estimator *re, unsigned int rate);
+
+#endif /* RATE_ESTIMATOR_H_ */
diff --git a/cras/src/server/rust/.gitignore b/cras/src/server/rust/.gitignore
deleted file mode 100644
index 2f7896d1..00000000
--- a/cras/src/server/rust/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-target/
diff --git a/cras/src/server/rust/Cargo.toml b/cras/src/server/rust/Cargo.toml
deleted file mode 100644
index afebda83..00000000
--- a/cras/src/server/rust/Cargo.toml
+++ /dev/null
@@ -1,17 +0,0 @@
-[package]
-name = "cras_rust"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-
-[lib]
-path = "src/rate_estimator.rs"
-crate-type = ["staticlib"]
-
-[dependencies]
-libc = "0.2.44"
-
-[profile.release]
-lto = true
-panic = "abort"
-overflow-checks = true
diff --git a/cras/src/server/rust/binding_generator/Cargo.toml b/cras/src/server/rust/binding_generator/Cargo.toml
deleted file mode 100644
index 1ec73483..00000000
--- a/cras/src/server/rust/binding_generator/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "binding_generator"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-
-[dependencies]
-cbindgen = "*"
diff --git a/cras/src/server/rust/binding_generator/src/main.rs b/cras/src/server/rust/binding_generator/src/main.rs
deleted file mode 100644
index f7803968..00000000
--- a/cras/src/server/rust/binding_generator/src/main.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-extern crate cbindgen;
-
-use cbindgen::Builder;
-
-const HEADER: &str = "// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Generated from files in cras/src/server/rust/src in adhd.";
-
-fn main() {
- Builder::new()
- .with_src("../src/rate_estimator.rs")
- .rename_item("RateEstimator", "rate_estimator")
- .rename_item("timespec", "struct timespec")
- .with_no_includes()
- .with_sys_include("time.h")
- .with_include_guard("RATE_ESTIMATOR_H_")
- .with_language(cbindgen::Language::C)
- .with_header(HEADER)
- .generate()
- .expect("Unable to generate bindings")
- .write_to_file("../src/headers/rate_estimator.h");
-}
diff --git a/cras/src/server/rust/src/headers/rate_estimator.h b/cras/src/server/rust/src/headers/rate_estimator.h
deleted file mode 100644
index 3ac9cfa9..00000000
--- a/cras/src/server/rust/src/headers/rate_estimator.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Generated from files in cras/src/server/rust/src in adhd.
-
-#ifndef RATE_ESTIMATOR_H_
-#define RATE_ESTIMATOR_H_
-
-#include <time.h>
-
-/**
- * An estimator holding the required information to determine the actual frame
- * rate of an audio device.
- *
- * # Members
- * * `last_level` - Buffer level of the audio device at last check time.
- * * `level_diff` - Number of frames written to or read from audio device
- * since the last check time. Rate estimator will use this
- * change plus the difference of buffer level to derive the
- * number of frames audio device has actually processed.
- * * `window_start` - The start time of the current window.
- * * `window_size` - The size of the window.
- * * `window_frames` - The number of frames accumulated in current window.
- * * `lsq` - The helper used to estimate sample rate.
- * * `smooth_factor` - A scaling factor used to average the previous and new
- * rate estimates to ensure that estimates do not change
- * too quickly.
- * * `estimated_rate` - The estimated rate at which samples are consumed.
- */
-typedef struct rate_estimator rate_estimator;
-
-/**
- * # Safety
- *
- * To use this function safely, `re` must be a pointer returned from
- * rate_estimator_create, or null.
- */
-void rate_estimator_add_frames(rate_estimator *re, int frames);
-
-/**
- * # Safety
- *
- * To use this function safely, `re` must be a pointer returned from
- * rate_estimator_create, or null, and `now` must be a valid pointer to a
- * timespec.
- */
-int32_t rate_estimator_check(rate_estimator *re, int level,
- const struct timespec *now);
-
-/**
- * # Safety
- *
- * To use this function safely, `window_size` must be a valid pointer to a
- * timespec.
- */
-rate_estimator *rate_estimator_create(unsigned int rate,
- const struct timespec *window_size,
- double smooth_factor);
-
-/**
- * # Safety
- *
- * To use this function safely, `re` must be a pointer returned from
- * rate_estimator_create, or null.
- */
-void rate_estimator_destroy(rate_estimator *re);
-
-/**
- * # Safety
- *
- * To use this function safely, `re` must be a pointer returned from
- * rate_estimator_create, or null.
- */
-double rate_estimator_get_rate(const rate_estimator *re);
-
-/**
- * # Safety
- *
- * To use this function safely, `re` must be a pointer returned from
- * rate_estimator_create, or null.
- */
-void rate_estimator_reset_rate(rate_estimator *re, unsigned int rate);
-
-#endif /* RATE_ESTIMATOR_H_ */
diff --git a/cras/src/server/rust/src/rate_estimator.rs b/cras/src/server/rust/src/rate_estimator.rs
deleted file mode 100644
index 585f346b..00000000
--- a/cras/src/server/rust/src/rate_estimator.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-pub mod rate_estimator_bindings;
-
-use std::error;
-use std::fmt;
-use std::time::Duration;
-
-#[derive(Debug)]
-pub enum Error {
- InvalidSmoothFactor(f64),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- InvalidSmoothFactor(sf) => write!(f, "Smooth factor {} is not between 0.0 and 1.0", sf),
- }
- }
-}
-
-type Result<T> = std::result::Result<T, Error>;
-
-const MAX_RATE_SKEW: f64 = 100.0;
-
-/// Hold information to calculate linear least square from
-/// several (x, y) samples.
-#[derive(Debug, Default)]
-struct LeastSquares {
- sum_x: f64,
- sum_y: f64,
- sum_xy: f64,
- sum_x2: f64,
- num_samples: u32,
-}
-
-impl LeastSquares {
- fn new() -> Self {
- Self::default()
- }
-
- fn add_sample(&mut self, x: f64, y: f64) {
- self.sum_x += x;
- self.sum_y += y;
- self.sum_xy += x * y;
- self.sum_x2 += x * x;
- self.num_samples += 1;
- }
-
- fn best_fit_slope(&self) -> f64 {
- let num = self.num_samples as f64 * self.sum_xy - self.sum_x * self.sum_y;
- let den = self.num_samples as f64 * self.sum_x2 - self.sum_x * self.sum_x;
- num / den
- }
-}
-
-/// An estimator holding the required information to determine the actual frame
-/// rate of an audio device.
-///
-/// # Members
-/// * `last_level` - Buffer level of the audio device at last check time.
-/// * `level_diff` - Number of frames written to or read from audio device
-/// since the last check time. Rate estimator will use this
-/// change plus the difference of buffer level to derive the
-/// number of frames audio device has actually processed.
-/// * `window_start` - The start time of the current window.
-/// * `window_size` - The size of the window.
-/// * `window_frames` - The number of frames accumulated in current window.
-/// * `lsq` - The helper used to estimate sample rate.
-/// * `smooth_factor` - A scaling factor used to average the previous and new
-/// rate estimates to ensure that estimates do not change
-/// too quickly.
-/// * `estimated_rate` - The estimated rate at which samples are consumed.
-pub struct RateEstimator {
- last_level: i32,
- level_diff: i32,
- window_start: Option<Duration>,
- window_size: Duration,
- window_frames: u32,
- lsq: LeastSquares,
- smooth_factor: f64,
- estimated_rate: f64,
-}
-
-impl RateEstimator {
- /// Creates a rate estimator.
- ///
- /// # Arguments
- /// * `rate` - The initial value to estimate rate from.
- /// * `window_size` - The window size of the rate estimator.
- /// * `smooth_factor` - The coefficient used to calculate moving average
- /// from old estimated rate values. Must be between
- /// 0.0 and 1.0
- ///
- /// # Errors
- /// * If `smooth_factor` is not between 0.0 and 1.0
- pub fn try_new(rate: u32, window_size: Duration, smooth_factor: f64) -> Result<Self> {
- if smooth_factor < 0.0 || smooth_factor > 1.0 {
- return Err(Error::InvalidSmoothFactor(smooth_factor));
- }
-
- Ok(RateEstimator {
- last_level: 0,
- level_diff: 0,
- window_start: None,
- window_size,
- window_frames: 0,
- lsq: LeastSquares::new(),
- smooth_factor,
- estimated_rate: rate as f64,
- })
- }
-
- /// Resets the estimated rate
- ///
- /// Reset the estimated rate to `rate`, and erase all collected data.
- pub fn reset_rate(&mut self, rate: u32) {
- self.last_level = 0;
- self.level_diff = 0;
- self.window_start = None;
- self.window_frames = 0;
- self.lsq = LeastSquares::new();
- self.estimated_rate = rate as f64;
- }
-
- /// Adds additional frames transmitted to/from audio device.
- ///
- /// # Arguments
- /// * `frames` - The number of frames written to the device. For input,
- /// this should be negative to indicate how many samples
- /// were read.
- pub fn add_frames(&mut self, frames: i32) {
- self.level_diff += frames;
- }
-
- /// Gets the estimated rate.
- pub fn get_estimated_rate(&self) -> f64 {
- self.estimated_rate
- }
-
- /// Check the timestamp and buffer level difference since last check time,
- /// and use them as a new sample to update the estimated rate.
- ///
- /// # Arguments
- /// * `level` - The current buffer level of audio device.
- /// * `now` - The time at which this function is called.
- ///
- /// # Returns
- /// True if the estimated rate is updated and window is reset,
- /// otherwise false.
- pub fn update_estimated_rate(&mut self, level: i32, now: Duration) -> bool {
- let start = match self.window_start {
- None => {
- self.window_start = Some(now);
- return false;
- }
- Some(t) => t,
- };
-
- let delta = match now.checked_sub(start) {
- Some(d) => d,
- None => return false,
- };
- self.window_frames += (self.last_level - level + self.level_diff).abs() as u32;
- self.level_diff = 0;
- self.last_level = level;
-
- let secs = (delta.as_secs() as f64) + delta.subsec_nanos() as f64 / 1_000_000_000.0;
- self.lsq.add_sample(secs, self.window_frames as f64);
- if delta > self.window_size && self.lsq.num_samples > 1 {
- let rate = self.lsq.best_fit_slope();
- if (self.estimated_rate - rate).abs() < MAX_RATE_SKEW {
- self.estimated_rate =
- rate * (1.0 - self.smooth_factor) + self.estimated_rate * self.smooth_factor;
- }
- self.lsq = LeastSquares::new();
- self.window_start = Some(now);
- self.window_frames = 0;
- return true;
- }
- false
- }
-}
diff --git a/cras/src/server/rust/src/rate_estimator_bindings.rs b/cras/src/server/rust/src/rate_estimator_bindings.rs
deleted file mode 100644
index 3073ba73..00000000
--- a/cras/src/server/rust/src/rate_estimator_bindings.rs
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std::time::Duration;
-
-use libc;
-
-use crate::RateEstimator;
-
-/// # Safety
-///
-/// To use this function safely, `window_size` must be a valid pointer to a
-/// timespec.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_create(
- rate: libc::c_uint,
- window_size: *const libc::timespec,
- smooth_factor: libc::c_double,
-) -> *mut RateEstimator {
- if window_size.is_null() {
- return std::ptr::null_mut::<RateEstimator>();
- }
-
- let ts = &*window_size;
- let window = Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32);
-
- match RateEstimator::try_new(rate, window, smooth_factor) {
- Ok(re) => Box::into_raw(Box::new(re)),
- Err(_) => std::ptr::null_mut::<RateEstimator>(),
- }
-}
-
-/// # Safety
-///
-/// To use this function safely, `re` must be a pointer returned from
-/// rate_estimator_create, or null.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_destroy(re: *mut RateEstimator) {
- if re.is_null() {
- return;
- }
-
- drop(Box::from_raw(re));
-}
-
-/// # Safety
-///
-/// To use this function safely, `re` must be a pointer returned from
-/// rate_estimator_create, or null.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_add_frames(re: *mut RateEstimator, frames: libc::c_int) {
- if re.is_null() {
- return;
- }
-
- (*re).add_frames(frames)
-}
-
-/// # Safety
-///
-/// To use this function safely, `re` must be a pointer returned from
-/// rate_estimator_create, or null, and `now` must be a valid pointer to a
-/// timespec.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_check(
- re: *mut RateEstimator,
- level: libc::c_int,
- now: *const libc::timespec,
-) -> i32 {
- if re.is_null() || now.is_null() {
- return 0;
- }
-
- let ts = &*now;
- if ts.tv_sec < 0 || ts.tv_nsec < 0 {
- return 0;
- }
- let secs = ts.tv_sec as u64 + (ts.tv_nsec / 1_000_000_000) as u64;
- let nsecs = (ts.tv_nsec % 1_000_000_000) as u32;
- let now = Duration::new(secs, nsecs);
-
- (*re).update_estimated_rate(level, now) as i32
-}
-
-/// # Safety
-///
-/// To use this function safely, `re` must be a pointer returned from
-/// rate_estimator_create, or null.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_get_rate(re: *const RateEstimator) -> libc::c_double {
- if re.is_null() {
- return 0.0;
- }
-
- (*re).get_estimated_rate()
-}
-
-/// # Safety
-///
-/// To use this function safely, `re` must be a pointer returned from
-/// rate_estimator_create, or null.
-#[no_mangle]
-pub unsafe extern "C" fn rate_estimator_reset_rate(re: *mut RateEstimator, rate: libc::c_uint) {
- if re.is_null() {
- return;
- }
-
- (*re).reset_rate(rate)
-}
diff --git a/cras/src/server/server_stream.c b/cras/src/server/server_stream.c
index 36d5496e..cc16cd8c 100644
--- a/cras/src/server/server_stream.c
+++ b/cras/src/server/server_stream.c
@@ -16,6 +16,18 @@
static unsigned int server_stream_block_size = 480;
/*
+ * Server stream doesn't care what format is used, because no
+ * client is reading data from stream. The main point is to
+ * make pinned device open and let data flow through its dsp
+ * pipeline.
+ */
+static struct cras_audio_format format = {
+ SND_PCM_FORMAT_S16_LE,
+ 48000,
+ 2,
+};
+
+/*
* Information of a stream created by server. Currently only
* one server stream is allowed, for echo reference use.
*/
@@ -33,12 +45,10 @@ static void server_stream_add_cb(void *data)
stream_list_add(stream_list, stream_config, &stream);
}
-void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx,
- struct cras_audio_format *format)
+void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx)
{
int audio_fd = -1;
int client_shm_fd = -1;
- uint64_t buffer_offsets[2] = { 0, 0 };
if (stream_config) {
syslog(LOG_ERR, "server stream already exists, dev %u",
@@ -53,9 +63,9 @@ void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx,
CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_SERVER_STREAM,
CRAS_STREAM_INPUT, dev_idx,
/*flags=*/SERVER_ONLY,
- /*effects=*/0, format, server_stream_block_size,
+ /*effects=*/0, &format, server_stream_block_size,
server_stream_block_size, &audio_fd, &client_shm_fd,
- /*client_shm_size=*/0, buffer_offsets, stream_config);
+ /*client_shm_size=*/0, stream_config);
/* Schedule add stream in next main thread loop. */
cras_system_add_task(server_stream_add_cb, stream_list);
@@ -83,5 +93,6 @@ void server_stream_destroy(struct stream_list *stream_list,
syslog(LOG_ERR, "No server stream to destroy");
return;
}
- server_stream_rm_cb(stream_list);
+ /* Schedule remove stream in next main thread loop. */
+ cras_system_add_task(server_stream_rm_cb, stream_list);
}
diff --git a/cras/src/server/server_stream.h b/cras/src/server/server_stream.h
index e1eb8e10..595987cb 100644
--- a/cras/src/server/server_stream.h
+++ b/cras/src/server/server_stream.h
@@ -14,8 +14,8 @@ struct stream_list;
* stream_list - List of stream to add new server stream to.
* dev_idx - The id of the device that new server stream will pin to.
*/
-void server_stream_create(struct stream_list *stream_list, unsigned int dev_idx,
- struct cras_audio_format *format);
+void server_stream_create(struct stream_list *stream_list,
+ unsigned int dev_idx);
/*
* Asynchronously destroys existing server stream pinned to device of given idx.
diff --git a/cras/src/server/stream_list.c b/cras/src/server/stream_list.c
index 04ef9fe1..d247ec89 100644
--- a/cras/src/server/stream_list.c
+++ b/cras/src/server/stream_list.c
@@ -3,19 +3,12 @@
* found in the LICENSE file.
*/
-#include <syslog.h>
#include "cras_rstream.h"
#include "cras_tm.h"
#include "cras_types.h"
#include "stream_list.h"
#include "utlist.h"
-/*
- * If the time difference of two streams is short than 10s, they may be the RTC
- * streams.
- */
-static const struct timespec RTC_STREAM_THRESHOLD = { 10, 0 };
-
struct stream_list {
struct cras_rstream *streams;
struct cras_rstream *streams_to_delete;
@@ -88,19 +81,12 @@ int stream_list_add(struct stream_list *list,
struct cras_rstream **stream)
{
int rc;
- struct cras_rstream *next_stream;
rc = list->stream_create_cb(stream_config, stream);
if (rc)
return rc;
- /* Keep stream list in descending order by channel count. */
- DL_FOREACH (list->streams, next_stream) {
- if ((*stream)->format.num_channels >=
- next_stream->format.num_channels)
- break;
- }
- DL_INSERT(list->streams, next_stream, *stream);
+ DL_APPEND(list->streams, *stream);
rc = list->stream_added_cb(*stream);
if (rc) {
DL_DELETE(list->streams, *stream);
@@ -161,28 +147,3 @@ bool stream_list_has_pinned_stream(struct stream_list *list,
}
return false;
}
-
-void detect_rtc_stream_pair(struct stream_list *list,
- struct cras_rstream *stream)
-{
- struct cras_rstream *next_stream;
- if (stream->cb_threshold != 480)
- return;
- if (stream->client_type != CRAS_CLIENT_TYPE_CHROME &&
- stream->client_type != CRAS_CLIENT_TYPE_LACROS)
- return;
- DL_FOREACH (list->streams, next_stream) {
- if (next_stream->cb_threshold == 480 &&
- next_stream->direction != stream->direction &&
- next_stream->client_type == stream->client_type &&
- timespec_diff_shorter_than(&stream->start_ts,
- &next_stream->start_ts,
- &RTC_STREAM_THRESHOLD)) {
- stream->stream_type =
- CRAS_STREAM_TYPE_VOICE_COMMUNICATION;
- next_stream->stream_type =
- CRAS_STREAM_TYPE_VOICE_COMMUNICATION;
- return;
- }
- }
-}
diff --git a/cras/src/server/stream_list.h b/cras/src/server/stream_list.h
index a527bc97..ae77a333 100644
--- a/cras/src/server/stream_list.h
+++ b/cras/src/server/stream_list.h
@@ -30,8 +30,8 @@ void stream_list_destroy(struct stream_list *list);
struct cras_rstream *stream_list_get(struct stream_list *list);
-/* Creates a cras_rstream from cras_rstream_config and inserts the cras_rstream
- * to stream_list in descending order by channel count.
+/* Creates a cras_rstream from cras_rstreaem_config and adds the cras_rstream
+ * to stream_list.
*
* Args:
* list - stream_list to add streams.
@@ -55,14 +55,3 @@ int stream_list_rm_all_client_streams(struct stream_list *list,
*/
bool stream_list_has_pinned_stream(struct stream_list *list,
unsigned int dev_idx);
-
-/*
- * Detects whether there is a RTC stream pair based on these rules:
- * 1. The cb_threshold is 480.
- * 2. The direction of two streams are opposite.
- * 3. Two streams are from the same client. (Chrome or LaCrOS)
- * 4. The start time of two streams are close enough. (shorter than 1s)
- * If all rules are passed, set the stream type to the voice communication.
- */
-void detect_rtc_stream_pair(struct stream_list *list,
- struct cras_rstream *stream);
diff --git a/cras/src/server/test_iodev.c b/cras/src/server/test_iodev.c
index cb7d5f3a..47ff3363 100644
--- a/cras/src/server/test_iodev.c
+++ b/cras/src/server/test_iodev.c
@@ -102,8 +102,7 @@ static int put_buffer(struct cras_iodev *iodev, unsigned frames)
struct test_iodev *testio = (struct test_iodev *)iodev;
/* Input */
- buf_increment_read(testio->audbuff,
- (size_t)frames * (size_t)testio->fmt_bytes);
+ buf_increment_read(testio->audbuff, frames * testio->fmt_bytes);
return 0;
}
@@ -195,13 +194,7 @@ struct cras_iodev *test_iodev_create(enum CRAS_STREAM_DIRECTION direction,
iodev->put_buffer = put_buffer;
iodev->update_active_node = update_active_node;
- /*
- * Record max supported channels into cras_iodev_info.
- * The value is the max of test_supported_channel_counts.
- */
- iodev->info.max_supported_channels = 1;
-
- /* Create an empty ionode */
+ /* Create a dummy ionode */
node = (struct cras_ionode *)calloc(1, sizeof(*node));
node->dev = iodev;
node->plugged = 1;
@@ -211,7 +204,7 @@ struct cras_iodev *test_iodev_create(enum CRAS_STREAM_DIRECTION direction,
node->type = CRAS_NODE_TYPE_UNKNOWN;
node->volume = 100;
node->software_volume_needed = 0;
- node->ui_gain_scaler = 1.0f;
+ node->max_software_gain = 0;
strcpy(node->name, "(default)");
cras_iodev_add_node(iodev, node);
cras_iodev_set_active_node(iodev, node);
@@ -242,9 +235,8 @@ unsigned int test_iodev_add_samples(struct test_iodev *testio, uint8_t *samples,
write_ptr = buf_write_pointer_size(testio->audbuff, &avail);
count = MIN(count, avail);
- memcpy(write_ptr, samples, (size_t)count * (size_t)testio->fmt_bytes);
- buf_increment_write(testio->audbuff,
- (size_t)count * (size_t)testio->fmt_bytes);
+ memcpy(write_ptr, samples, count * testio->fmt_bytes);
+ buf_increment_write(testio->audbuff, count * testio->fmt_bytes);
return count;
}
diff --git a/cras/src/tests/a2dp_info_unittest.cc b/cras/src/tests/a2dp_info_unittest.cc
index eb082b0c..4858c460 100644
--- a/cras/src/tests/a2dp_info_unittest.cc
+++ b/cras/src/tests/a2dp_info_unittest.cc
@@ -80,7 +80,7 @@ TEST(A2dpInfoInit, DestroyA2dp) {
ASSERT_EQ(1, get_sbc_codec_destroy_called());
}
-TEST(A2dpInfoInit, ResetA2dp) {
+TEST(A2dpInfoInit, DrainA2dp) {
ResetStubData();
init_a2dp(&a2dp, &sbc);
a2dp.a2dp_buf_used = 99;
@@ -88,7 +88,7 @@ TEST(A2dpInfoInit, ResetA2dp) {
a2dp.seq_num = 11;
a2dp.frame_count = 12;
- a2dp_reset(&a2dp);
+ a2dp_drain(&a2dp);
ASSERT_EQ(a2dp.a2dp_buf_used, 13);
ASSERT_EQ(a2dp.frame_count, 0);
diff --git a/cras/src/tests/a2dp_iodev_unittest.cc b/cras/src/tests/a2dp_iodev_unittest.cc
index 06c1cd3c..c85b9d67 100644
--- a/cras/src/tests/a2dp_iodev_unittest.cc
+++ b/cras/src/tests/a2dp_iodev_unittest.cc
@@ -7,10 +7,11 @@
#include <stdio.h>
extern "C" {
-#include "cras_a2dp_iodev.c"
+#include "a2dp-codecs.h"
#include "audio_thread.h"
#include "audio_thread_log.h"
+#include "cras_a2dp_iodev.h"
#include "cras_audio_area.h"
#include "cras_bt_transport.h"
#include "cras_iodev.h"
@@ -21,15 +22,12 @@ extern "C" {
#define MAX_A2DP_ENCODE_CALLS 8
#define MAX_A2DP_WRITE_CALLS 4
-/* Fake the codec to encode (512/4) frames into 128 bytes. */
-#define FAKE_A2DP_CODE_SIZE 512
-#define FAKE_A2DP_FRAME_LENGTH 128
-
static struct cras_bt_transport* fake_transport;
static cras_audio_format format;
static size_t cras_bt_device_append_iodev_called;
static size_t cras_bt_device_rm_iodev_called;
static size_t cras_iodev_add_node_called;
+static int cras_iodev_frames_queued_called;
static size_t cras_iodev_rm_node_called;
static size_t cras_iodev_set_active_node_called;
static size_t cras_bt_transport_acquire_called;
@@ -38,28 +36,28 @@ static size_t cras_bt_transport_release_called;
static size_t init_a2dp_called;
static int init_a2dp_return_val;
static size_t destroy_a2dp_called;
-static size_t a2dp_reset_called;
+static size_t drain_a2dp_called;
+static size_t a2dp_block_size_called;
+static size_t a2dp_queued_frames_val;
static size_t cras_iodev_free_format_called;
static size_t cras_iodev_free_resources_called;
+static int pcm_buf_size_val[MAX_A2DP_ENCODE_CALLS];
+static unsigned int a2dp_encode_processed_bytes_val[MAX_A2DP_ENCODE_CALLS];
+static unsigned int a2dp_encode_index;
static int a2dp_write_return_val[MAX_A2DP_WRITE_CALLS];
static unsigned int a2dp_write_index;
-static int a2dp_encode_called;
-static cras_audio_area* mock_audio_area;
+static cras_audio_area* dummy_audio_area;
static thread_callback write_callback;
static void* write_callback_data;
static const char* fake_device_name = "fake device name";
static const char* cras_bt_device_name_ret;
static unsigned int cras_bt_transport_write_mtu_ret;
-static int cras_iodev_fill_odev_zeros_called;
-static unsigned int cras_iodev_fill_odev_zeros_frames;
-static int audio_thread_config_events_callback_called;
-static enum AUDIO_THREAD_EVENTS_CB_TRIGGER
- audio_thread_config_events_callback_trigger;
void ResetStubData() {
cras_bt_device_append_iodev_called = 0;
cras_bt_device_rm_iodev_called = 0;
cras_iodev_add_node_called = 0;
+ cras_iodev_frames_queued_called = 0;
cras_iodev_rm_node_called = 0;
cras_iodev_set_active_node_called = 0;
cras_bt_transport_acquire_called = 0;
@@ -68,20 +66,22 @@ void ResetStubData() {
init_a2dp_called = 0;
init_a2dp_return_val = 0;
destroy_a2dp_called = 0;
- a2dp_reset_called = 0;
+ drain_a2dp_called = 0;
+ a2dp_block_size_called = 0;
+ a2dp_queued_frames_val = 0;
cras_iodev_free_format_called = 0;
cras_iodev_free_resources_called = 0;
+ memset(a2dp_encode_processed_bytes_val, 0,
+ sizeof(a2dp_encode_processed_bytes_val));
+ a2dp_encode_index = 0;
a2dp_write_index = 0;
- a2dp_encode_called = 0;
- /* Fake the MTU value. min_buffer_level will be derived from this value. */
- cras_bt_transport_write_mtu_ret = 950;
- cras_iodev_fill_odev_zeros_called = 0;
+ cras_bt_transport_write_mtu_ret = 800;
fake_transport = reinterpret_cast<struct cras_bt_transport*>(0x123);
- if (!mock_audio_area) {
- mock_audio_area = (cras_audio_area*)calloc(
- 1, sizeof(*mock_audio_area) + sizeof(cras_channel_area) * 2);
+ if (!dummy_audio_area) {
+ dummy_audio_area = (cras_audio_area*)calloc(
+ 1, sizeof(*dummy_audio_area) + sizeof(cras_channel_area) * 2);
}
write_callback = NULL;
@@ -102,14 +102,12 @@ class A2dpIodev : public testing::Test {
protected:
virtual void SetUp() {
ResetStubData();
- time_now.tv_sec = 0;
- time_now.tv_nsec = 0;
atlog = (audio_thread_event_log*)calloc(1, sizeof(audio_thread_event_log));
}
virtual void TearDown() {
- free(mock_audio_area);
- mock_audio_area = NULL;
+ free(dummy_audio_area);
+ dummy_audio_area = NULL;
free(atlog);
}
};
@@ -169,14 +167,12 @@ TEST_F(A2dpIodev, OpenIodev) {
iodev_set_format(iodev, &format);
iodev->configure_dev(iodev);
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
ASSERT_EQ(1, cras_bt_transport_acquire_called);
iodev->close_dev(iodev);
ASSERT_EQ(1, cras_bt_transport_release_called);
- ASSERT_EQ(1, a2dp_reset_called);
+ ASSERT_EQ(1, drain_a2dp_called);
ASSERT_EQ(1, cras_iodev_free_format_called);
a2dp_iodev_destroy(iodev);
@@ -185,74 +181,58 @@ TEST_F(A2dpIodev, OpenIodev) {
TEST_F(A2dpIodev, GetPutBuffer) {
struct cras_iodev* iodev;
struct cras_audio_area *area1, *area2, *area3;
- uint8_t* last_buf_head;
+ uint8_t* area1_buf;
unsigned frames;
- struct timespec tstamp;
- struct a2dp_io* a2dpio;
iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
iodev_set_format(iodev, &format);
iodev->configure_dev(iodev);
ASSERT_NE(write_callback, (void*)NULL);
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ frames = 256;
+ iodev->get_buffer(iodev, &area1, &frames);
+ ASSERT_EQ(256, frames);
+ ASSERT_EQ(256, area1->frames);
+ area1_buf = area1->channels[0].buf;
- /* (950 - 13) / 128 * 512 / 4 */
- ASSERT_EQ(iodev->min_buffer_level, 896);
+ /* Test 100 frames(400 bytes) put and all processed. */
+ a2dp_encode_processed_bytes_val[0] = 400;
+ a2dp_write_index = 0;
+ a2dp_write_return_val[0] = 400;
+ iodev->put_buffer(iodev, 100);
+ write_callback(write_callback_data);
+ // Start with 4k frames.
+ EXPECT_EQ(400, pcm_buf_size_val[0]);
- frames = 1500;
- iodev->get_buffer(iodev, &area1, &frames);
- ASSERT_EQ(1500, frames);
- ASSERT_EQ(1500, area1->frames);
- last_buf_head = area1->channels[0].buf;
- iodev->put_buffer(iodev, 1000);
- /* 1000 frames takes 8 encode call, FAKE_A2DP_CODE_SIZE / 4 = 128
- * and 7 * 128 < 1000 < 8 * 128
- */
- EXPECT_EQ(8, a2dp_encode_called);
- /* Expect flushed one block, leaving 1000 - 896 = 104 queued and
- * next_flush_time has shifted. */
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
- EXPECT_GT(a2dpio->next_flush_time.tv_nsec, 0);
-
- /* Assert buffer possition shifted 1000 * 4 bytes */
- frames = 1000;
iodev->get_buffer(iodev, &area2, &frames);
- ASSERT_EQ(1000, frames);
- ASSERT_EQ(1000, area2->frames);
- ASSERT_EQ(4000, area2->channels[0].buf - last_buf_head);
- last_buf_head = area2->channels[0].buf;
+ ASSERT_EQ(256, frames);
+ ASSERT_EQ(256, area2->frames);
- iodev->put_buffer(iodev, 700);
- EXPECT_EQ(804, iodev->frames_queued(iodev, &tstamp));
- /* Assert that even next_flush_time is not met, pcm data still processed.
- * Expect to takes 7 more encode calls to process the 804 frames of data.
- * and 6 * 128 < 804 < 7 * 128
+ /* Assert buf2 points to the same position as buf1 */
+ ASSERT_EQ(400, area2->channels[0].buf - area1_buf);
+
+ /* Test 100 frames(400 bytes) put, only 360 bytes processed,
+ * 40 bytes left in pcm buffer.
*/
- EXPECT_EQ(15, a2dp_encode_called);
- EXPECT_EQ(768, a2dpio->a2dp.samples);
+ a2dp_encode_index = 0;
+ a2dp_encode_processed_bytes_val[0] = 360;
+ a2dp_encode_processed_bytes_val[1] = 0;
+ a2dp_write_index = 0;
+ a2dp_write_return_val[0] = 360;
+ a2dp_write_return_val[1] = 0;
+ iodev->put_buffer(iodev, 100);
+ write_callback(write_callback_data);
+ EXPECT_EQ(400, pcm_buf_size_val[0]);
+ ASSERT_EQ(40, pcm_buf_size_val[1]);
- time_now.tv_nsec = 25000000;
- frames = 50;
iodev->get_buffer(iodev, &area3, &frames);
- ASSERT_EQ(50, frames);
- /* Assert buffer possition shifted 700 * 4 bytes */
- EXPECT_EQ(2800, area3->channels[0].buf - last_buf_head);
-
- iodev->put_buffer(iodev, 50);
- /* 804 + 50 = 854 queued, 768 of them are encoded. */
- EXPECT_EQ(854, iodev->frames_queued(iodev, &tstamp));
- EXPECT_EQ(768, a2dpio->a2dp.samples);
- /* Expect one a2dp encode call was executed for the left un-encoded frames.
- * 854 - 768 = 86 < 128 */
- EXPECT_EQ(16, a2dp_encode_called);
- /* Even time now has passed next_flush_time, no a2dp write gets called
- * because the number of encoded samples is not sufficient for a flush. */
- EXPECT_EQ(1, a2dp_write_index);
+
+ /* Existing buffer not completed processed, assert new buffer starts from
+ * current write pointer.
+ */
+ ASSERT_EQ(256, frames);
+ EXPECT_EQ(800, area3->channels[0].buf - area1_buf);
iodev->close_dev(iodev);
a2dp_iodev_destroy(iodev);
@@ -263,260 +243,70 @@ TEST_F(A2dpIodev, FramesQueued) {
struct cras_audio_area* area;
struct timespec tstamp;
unsigned frames;
- struct a2dp_io* a2dpio;
iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
iodev_set_format(iodev, &format);
time_now.tv_sec = 0;
time_now.tv_nsec = 0;
iodev->configure_dev(iodev);
ASSERT_NE(write_callback, (void*)NULL);
- /* a2dp_block_size(mtu) / format_bytes
- * (950 - 13) / 128 * 512 / 4 = 896 */
- EXPECT_EQ(896, a2dpio->write_block);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
frames = 256;
iodev->get_buffer(iodev, &area, &frames);
ASSERT_EQ(256, frames);
ASSERT_EQ(256, area->frames);
- /* Data less than write_block hence not written. */
+ /* Put 100 frames, proccessed 400 bytes to a2dp buffer.
+ * Assume 200 bytes written out, queued 50 frames in a2dp buffer.
+ */
+ a2dp_encode_processed_bytes_val[0] = 400;
+ a2dp_write_return_val[0] = 50;
+ a2dp_queued_frames_val = 50;
+ time_now.tv_sec = 0;
+ time_now.tv_nsec = 1000000;
iodev->put_buffer(iodev, 200);
+ write_callback(write_callback_data);
EXPECT_EQ(200, iodev->frames_queued(iodev, &tstamp));
EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
- /* 200 + 800 - 896 = 104 */
- a2dp_write_return_val[0] = 0;
- frames = 800;
- iodev->get_buffer(iodev, &area, &frames);
- iodev->put_buffer(iodev, 800);
- EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
-
- /* Some time has passed, same amount of frames are queued. */
- time_now.tv_nsec = 15000000;
- write_callback(write_callback_data, POLLOUT);
- EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
-
- /* Put 900 more frames. next_flush_time not yet passed so expect
- * total 900 + 104 = 1004 are queued. */
- frames = 900;
- iodev->get_buffer(iodev, &area, &frames);
- iodev->put_buffer(iodev, 900);
- EXPECT_EQ(1004, iodev->frames_queued(iodev, &tstamp));
-
- /* Time passes next_flush_time, 1004 + 300 - 896 = 408 */
- time_now.tv_nsec = 25000000;
- frames = 300;
- iodev->get_buffer(iodev, &area, &frames);
- iodev->put_buffer(iodev, 300);
- EXPECT_EQ(408, iodev->frames_queued(iodev, &tstamp));
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
-}
-
-TEST_F(A2dpIodev, SleepTimeWithWriteThrottle) {
- struct cras_iodev* iodev;
- struct cras_audio_area* area;
- unsigned frames;
- unsigned int level;
- unsigned long target;
- struct timespec tstamp;
- struct a2dp_io* a2dpio;
-
- iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
-
- iodev_set_format(iodev, &format);
- iodev->configure_dev(iodev);
- ASSERT_NE(write_callback, (void*)NULL);
- /* a2dp_block_size(mtu) / format_bytes
- * 900 / 128 * 512 / 4 = 896 */
- EXPECT_EQ(896, a2dpio->write_block);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
- /* Both time now and next_flush_time are at 0. Expect write_block of
- * time to sleep */
- EXPECT_EQ(a2dpio->write_block,
- iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
-
- /* Fake that 1000 frames are put and one block got flushed.
- * Expect next_wake_time be fast forward by one flush_period. */
- frames = 1000;
- iodev->get_buffer(iodev, &area, &frames);
- ASSERT_EQ(1000, frames);
- ASSERT_EQ(1000, area->frames);
-
- /* Expect the first block be flushed at time 0. */
- time_now.tv_nsec = 0;
- a2dp_write_return_val[0] = 0;
- EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
- EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp)); /* 1000 - 896 */
-
- /* Same amount of frames are queued after some time has passed. */
- time_now.tv_nsec = 10000000;
- EXPECT_EQ(104, iodev->frames_queued(iodev, &tstamp));
-
- /* Expect to sleep the time between now(10ms) and next_flush_time(~20.3ms). */
- frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
- target =
- a2dpio->write_block - time_now.tv_nsec * format.frame_rate / 1000000000;
- EXPECT_GE(frames + 1, target);
- EXPECT_GE(target + 1, frames);
-
- /* Time now has passed the next flush time(~20.3ms), expect to return
- * write_block of time to sleep. */
- time_now.tv_nsec = 25000000;
- EXPECT_EQ(a2dpio->write_block,
- iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
-
- a2dp_write_return_val[1] = 0;
- frames = 1000;
- iodev->get_buffer(iodev, &area, &frames);
- EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
- EXPECT_EQ(208, iodev->frames_queued(iodev, &tstamp)); /* 104 + 1000 - 896 */
-
- /* Flush another write_block of data, next_wake_time fast forward by
- * another flush_period. Expect to sleep the time between now(25ms)
- * and next_flush_time(~40.6ms). */
- frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
- target = a2dpio->write_block * 2 -
- time_now.tv_nsec * format.frame_rate / 1000000000;
- EXPECT_GE(frames + 1, target);
- EXPECT_GE(target + 1, frames);
-
- /* Put 1000 more frames, and make a fake failure to this flush. */
- time_now.tv_nsec = 45000000;
- a2dp_write_return_val[2] = -EAGAIN;
- frames = 1000;
- iodev->get_buffer(iodev, &area, &frames);
- EXPECT_EQ(0, iodev->put_buffer(iodev, 1000));
-
- /* Last a2dp write call failed with -EAGAIN, time now(45ms) is after
- * next_flush_time. Expect to return exact |write_block| equivalant
- * of time to sleep. */
- EXPECT_EQ(1208, iodev->frames_queued(iodev, &tstamp)); /* 208 + 1000 */
- EXPECT_EQ(a2dpio->write_block,
- iodev->frames_to_play_in_sleep(iodev, &level, &tstamp));
-
- /* Fake the event that socket becomes writable so data continues to flush.
- * next_flush_time fast forwards by another flush_period. */
- a2dp_write_return_val[3] = 0;
- write_callback(write_callback_data, POLLOUT);
- EXPECT_EQ(312, iodev->frames_queued(iodev, &tstamp)); /* 1208 - 896 */
-
- /* Expect to sleep the time between now and next_flush_time(~60.9ms). */
- frames = iodev->frames_to_play_in_sleep(iodev, &level, &tstamp);
- target = a2dpio->write_block * 3 -
- time_now.tv_nsec * format.frame_rate / 1000000000;
- EXPECT_GE(frames + 1, target);
- EXPECT_GE(target + 1, frames);
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
-}
-
-TEST_F(A2dpIodev, EnableThreadCallbackAtBufferFull) {
- struct cras_iodev* iodev;
- struct cras_audio_area* area;
- struct timespec tstamp;
- unsigned frames;
- struct a2dp_io* a2dpio;
-
- iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
-
- iodev_set_format(iodev, &format);
+ /* After writing another 200 frames, check for correct buffer level. */
time_now.tv_sec = 0;
- time_now.tv_nsec = 0;
- iodev->configure_dev(iodev);
- ASSERT_NE(write_callback, (void*)NULL);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
- audio_thread_config_events_callback_called = 0;
- a2dp_write_return_val[0] = 0;
- frames = iodev->buffer_size;
- iodev->get_buffer(iodev, &area, &frames);
- EXPECT_LE(frames, iodev->buffer_size);
- EXPECT_EQ(0, iodev->put_buffer(iodev, frames));
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
- EXPECT_EQ(1, audio_thread_config_events_callback_called);
- EXPECT_EQ(TRIGGER_NONE, audio_thread_config_events_callback_trigger);
-
- /* Fastfoward time 1ms, not yet reaches the next flush time. */
- time_now.tv_nsec = 1000000;
-
- /* Cram into iodev as much data as possible. Expect its buffer to
- * be full because flush time does not yet met. */
- frames = iodev->buffer_size;
- iodev->get_buffer(iodev, &area, &frames);
- EXPECT_LE(frames, iodev->buffer_size);
- EXPECT_EQ(0, iodev->put_buffer(iodev, frames));
- frames = iodev->frames_queued(iodev, &tstamp);
- EXPECT_EQ(frames, iodev->buffer_size);
-
- /* Expect a2dp_write didn't get called in last get/put buffer. And
- * audio thread callback has been enabled. */
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(2, audio_thread_config_events_callback_called);
- EXPECT_EQ(TRIGGER_WAKEUP, audio_thread_config_events_callback_trigger);
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
-}
-
-TEST_F(A2dpIodev, FlushAtLowBufferLevel) {
- struct cras_iodev* iodev;
- struct cras_audio_area* area;
- struct timespec tstamp;
- unsigned frames;
-
- iodev = a2dp_iodev_create(fake_transport);
-
- iodev_set_format(iodev, &format);
- iodev->configure_dev(iodev);
- ASSERT_NE(write_callback, (void*)NULL);
-
- /* (950 - 13)/ 128 * 512 / 4 */
- ASSERT_EQ(iodev->min_buffer_level, 896);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
- frames = 1500;
- iodev->get_buffer(iodev, &area, &frames);
- ASSERT_EQ(1500, frames);
- ASSERT_EQ(1500, area->frames);
+ time_now.tv_nsec = 2000000;
+ a2dp_encode_index = 0;
+ a2dp_write_index = 0;
+ a2dp_encode_processed_bytes_val[0] = 400;
+ write_callback(write_callback_data);
+ /* 1000000 nsec has passed, estimated queued frames adjusted by 44 */
+ EXPECT_EQ(156, iodev->frames_queued(iodev, &tstamp));
+ EXPECT_EQ(400, pcm_buf_size_val[0]);
+ EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
+ EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
- /*
- * Assert put_buffer shouldn't trigger the 2nd call to a2dp_encode()
- * because buffer is low: 896 < 1500 < 896 * 2
- */
- a2dp_write_return_val[0] = 0;
- EXPECT_EQ(0, iodev->put_buffer(iodev, 1500));
- EXPECT_EQ(1, a2dp_write_index);
+ /* Queued frames and new put buffer are all written */
+ a2dp_encode_processed_bytes_val[0] = 400;
+ a2dp_encode_processed_bytes_val[1] = 0;
+ a2dp_encode_index = 0;
+ a2dp_write_return_val[0] = 400;
+ a2dp_write_return_val[1] = -EAGAIN;
+ a2dp_write_index = 0;
- /* 1500 - 896 */
- time_now.tv_nsec = 25000000;
- EXPECT_EQ(604, iodev->frames_queued(iodev, &tstamp));
+ /* Add wnother 200 samples, get back to the original level. */
+ time_now.tv_sec = 0;
+ time_now.tv_nsec = 50000000;
+ a2dp_encode_processed_bytes_val[0] = 600;
+ a2dp_queued_frames_val = 50;
+ iodev->put_buffer(iodev, 200);
+ EXPECT_EQ(800, pcm_buf_size_val[0]);
+ EXPECT_EQ(100, iodev->frames_queued(iodev, &tstamp));
EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
iodev->close_dev(iodev);
a2dp_iodev_destroy(iodev);
}
-TEST_F(A2dpIodev, HandleUnderrun) {
+TEST_F(A2dpIodev, FlushAtLowBufferLevel) {
struct cras_iodev* iodev;
struct cras_audio_area* area;
struct timespec tstamp;
@@ -528,188 +318,74 @@ TEST_F(A2dpIodev, HandleUnderrun) {
time_now.tv_sec = 0;
time_now.tv_nsec = 0;
iodev->configure_dev(iodev);
- /* (950 - 13) / 128 * 512 / 4 */
- EXPECT_EQ(896, iodev->min_buffer_level);
+ ASSERT_NE(write_callback, (void*)NULL);
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ ASSERT_EQ(iodev->min_buffer_level, 400);
- frames = 300;
+ frames = 700;
iodev->get_buffer(iodev, &area, &frames);
- ASSERT_EQ(300, frames);
- ASSERT_EQ(300, area->frames);
- a2dp_write_return_val[0] = -EAGAIN;
-
- time_now.tv_nsec = 10000000;
- iodev->put_buffer(iodev, 300);
-
- time_now.tv_nsec = 20000000;
- EXPECT_EQ(300, iodev->frames_queued(iodev, &tstamp));
-
- /* Frames queued below min_buffer_level, which is derived from transport MTU.
- * Assert min_cb_level of zero frames are filled. */
- iodev->min_cb_level = 150;
- iodev->output_underrun(iodev);
- ASSERT_EQ(1, cras_iodev_fill_odev_zeros_called);
- EXPECT_EQ(150, cras_iodev_fill_odev_zeros_frames);
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
-}
+ ASSERT_EQ(700, frames);
+ ASSERT_EQ(700, area->frames);
-TEST_F(A2dpIodev, LeavingNoStreamStateWithSmallStreamDoesntUnderrun) {
- struct cras_iodev* iodev;
- struct cras_audio_area* area;
- struct timespec tstamp;
- unsigned frames;
- struct a2dp_io* a2dpio;
+ /* First call to a2dp_encode() processed 800 bytes. */
+ a2dp_encode_processed_bytes_val[0] = 800;
+ a2dp_encode_processed_bytes_val[1] = 0;
+ a2dp_write_return_val[0] = 200;
- iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
-
- iodev_set_format(iodev, &format);
- time_now.tv_sec = 0;
- time_now.tv_nsec = 0;
- iodev->configure_dev(iodev);
- ASSERT_NE(write_callback, (void*)NULL);
- /* (950 - 13)/ 128 * 512 / 4 */
- ASSERT_EQ(896, iodev->min_buffer_level);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ /* put_buffer shouldn't trigger the 2nd call to a2dp_encode() because
+ * buffer is low. Fake some data to make sure this test case will fail
+ * when a2dp_encode() called twice.
+ */
+ a2dp_encode_processed_bytes_val[2] = 800;
+ a2dp_encode_processed_bytes_val[3] = 0;
+ a2dp_write_return_val[1] = -EAGAIN;
- /* Put iodev in no_stream state. Verify it doesn't underrun after each
- * call of no_stream ops. */
- a2dp_write_return_val[0] = 0;
- iodev->no_stream(iodev, 1);
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
- frames = iodev->frames_queued(iodev, &tstamp);
- EXPECT_LE(iodev->min_buffer_level, frames);
+ time_now.tv_nsec = 10000000;
+ iodev->put_buffer(iodev, 700);
- /* Some time has passed and a small stream of 200 frames block is added.
- * Verify leaving no_stream state doesn't underrun immediately. */
time_now.tv_nsec = 20000000;
- iodev->no_stream(iodev, 1);
- frames = 200;
- iodev->get_buffer(iodev, &area, &frames);
- iodev->put_buffer(iodev, 200);
- frames = iodev->frames_queued(iodev, &tstamp);
- EXPECT_LE(iodev->min_buffer_level, frames);
-
+ EXPECT_EQ(500, iodev->frames_queued(iodev, &tstamp));
+ EXPECT_EQ(tstamp.tv_sec, time_now.tv_sec);
+ EXPECT_EQ(tstamp.tv_nsec, time_now.tv_nsec);
iodev->close_dev(iodev);
a2dp_iodev_destroy(iodev);
}
-TEST_F(A2dpIodev, NoStreamStateFillZerosToTargetLevel) {
+TEST_F(A2dpIodev, NoStreamState) {
struct cras_iodev* iodev;
struct cras_audio_area* area;
struct timespec tstamp;
unsigned frames;
- struct a2dp_io* a2dpio;
iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
-
iodev_set_format(iodev, &format);
time_now.tv_sec = 0;
time_now.tv_nsec = 0;
iodev->configure_dev(iodev);
ASSERT_NE(write_callback, (void*)NULL);
- /* (950 - 13)/ 128 * 512 / 4 */
- ASSERT_EQ(896, iodev->min_buffer_level);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ ASSERT_EQ(400, iodev->min_buffer_level);
iodev->min_cb_level = 480;
frames = 200;
iodev->get_buffer(iodev, &area, &frames);
iodev->put_buffer(iodev, 200);
- a2dp_write_return_val[0] = 0;
- iodev->no_stream(iodev, 1);
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
-
- /* Some time has passed but not yet reach next flush. Entering no_stream
- * fills buffer to 3 times of min_buffer_level. */
- time_now.tv_nsec = 10000000;
iodev->no_stream(iodev, 1);
- frames = iodev->frames_queued(iodev, &tstamp);
- EXPECT_EQ(3 * iodev->min_buffer_level, frames);
+ EXPECT_EQ(1, cras_iodev_frames_queued_called);
- /* Time has passed next flush time, expect one block is flushed. */
- a2dp_write_return_val[1] = 0;
- time_now.tv_nsec = 25000000;
- iodev->no_stream(iodev, 1);
+ /* no_stream will fill the buffer to hw_level = (441 (44100 * 0.01)) * 2
+ * frames, but 200 < min_buffer_level so cras_iodev_frames_queued will return
+ * 0 in no_stream and no_stream will fill 882 frames to device buffer.
+ */
frames = iodev->frames_queued(iodev, &tstamp);
- ASSERT_EQ(2 * iodev->min_buffer_level, frames);
- EXPECT_EQ(2, a2dp_write_index);
+ ASSERT_EQ(1082, frames);
- /* Leaving no_stream state fills buffer level back to 2 * min_buffer_level.
- */
- a2dp_write_return_val[2] = 0;
- time_now.tv_nsec = 30000000;
+ /* After leaving no stream state, output buffer won't be adjusted */
iodev->no_stream(iodev, 0);
frames = iodev->frames_queued(iodev, &tstamp);
- ASSERT_EQ(2 * iodev->min_buffer_level, frames);
- EXPECT_EQ(2, a2dp_write_index);
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
+ ASSERT_EQ(1082, frames);
}
-TEST_F(A2dpIodev, EnterNoStreamStateAtHighBufferLevelDoesntFillMore) {
- struct cras_iodev* iodev;
- struct cras_audio_area* area;
- struct timespec tstamp;
- unsigned frames, start_level;
- struct a2dp_io* a2dpio;
-
- iodev = a2dp_iodev_create(fake_transport);
- a2dpio = (struct a2dp_io*)iodev;
-
- iodev_set_format(iodev, &format);
- time_now.tv_sec = 0;
- time_now.tv_nsec = 0;
- iodev->configure_dev(iodev);
- ASSERT_NE(write_callback, (void*)NULL);
- /* (950 - 13)/ 128 * 512 / 4 */
- ASSERT_EQ(896, iodev->min_buffer_level);
-
- iodev->start(iodev);
- iodev->state = CRAS_IODEV_STATE_NORMAL_RUN;
-
- a2dp_write_return_val[0] = 0;
- start_level = 6000;
- frames = start_level;
- iodev->get_buffer(iodev, &area, &frames);
- iodev->put_buffer(iodev, frames);
- frames = iodev->frames_queued(iodev, &tstamp);
- /* Assert one block has fluxhed */
- EXPECT_EQ(start_level - iodev->min_buffer_level, frames);
- EXPECT_EQ(1, a2dp_write_index);
- EXPECT_EQ(a2dpio->flush_period.tv_nsec, a2dpio->next_flush_time.tv_nsec);
-
- a2dp_write_return_val[1] = 0;
- time_now.tv_nsec = 25000000;
- iodev->no_stream(iodev, 1);
- frames = iodev->frames_queued(iodev, &tstamp);
- /* Next flush time meets requirement so another block is flushed. */
- ASSERT_EQ(start_level - 2 * iodev->min_buffer_level, frames);
-
- a2dp_write_return_val[2] = 0;
- time_now.tv_nsec = 50000000;
- iodev->no_stream(iodev, 1);
- frames = iodev->frames_queued(iodev, &tstamp);
- /* Another block flushed at leaving no stream state. No more data
- * filled because level is high. */
- ASSERT_EQ(start_level - 3 * iodev->min_buffer_level, frames);
-
- iodev->close_dev(iodev);
- a2dp_iodev_destroy(iodev);
-}
} // namespace
int main(int argc, char** argv) {
@@ -722,7 +398,6 @@ extern "C" {
int cras_bt_transport_configuration(const struct cras_bt_transport* transport,
void* configuration,
int len) {
- memset(configuration, 0, len);
cras_bt_transport_configuration_called++;
return 0;
}
@@ -803,10 +478,6 @@ const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
return "/org/bluez/hci0/dev_1A_2B_3C_4D_5E_6F";
}
-int cras_bt_device_get_stable_id(const struct cras_bt_device* device) {
- return 123;
-}
-
void cras_bt_device_append_iodev(struct cras_bt_device* device,
struct cras_iodev* iodev,
enum cras_bt_device_profile profile) {
@@ -826,18 +497,13 @@ int cras_bt_device_cancel_suspend(struct cras_bt_device* device) {
return 0;
}
-int cras_bt_device_schedule_suspend(
- struct cras_bt_device* device,
- unsigned int msec,
- enum cras_bt_device_suspend_reason suspend_reason) {
+int cras_bt_device_schedule_suspend(struct cras_bt_device* device,
+ unsigned int msec) {
return 0;
}
int init_a2dp(struct a2dp_info* a2dp, a2dp_sbc_t* sbc) {
init_a2dp_called++;
- memset(a2dp, 0, sizeof(*a2dp));
- a2dp->frame_length = FAKE_A2DP_FRAME_LENGTH;
- a2dp->codesize = FAKE_A2DP_CODE_SIZE;
return init_a2dp_return_val;
}
@@ -846,20 +512,22 @@ void destroy_a2dp(struct a2dp_info* a2dp) {
}
int a2dp_codesize(struct a2dp_info* a2dp) {
- return a2dp->codesize;
+ return 512;
}
int a2dp_block_size(struct a2dp_info* a2dp, int encoded_bytes) {
- return encoded_bytes / a2dp->frame_length * a2dp->codesize;
+ a2dp_block_size_called++;
+
+ // Assumes a2dp block size is 1:1 before/after encode.
+ return encoded_bytes;
}
-int a2dp_queued_frames(const struct a2dp_info* a2dp) {
- return a2dp->samples;
+int a2dp_queued_frames(struct a2dp_info* a2dp) {
+ return a2dp_queued_frames_val;
}
-void a2dp_reset(struct a2dp_info* a2dp) {
- a2dp_reset_called++;
- a2dp->samples = 0;
+void a2dp_drain(struct a2dp_info* a2dp) {
+ drain_a2dp_called++;
}
int a2dp_encode(struct a2dp_info* a2dp,
@@ -867,34 +535,19 @@ int a2dp_encode(struct a2dp_info* a2dp,
int pcm_buf_size,
int format_bytes,
size_t link_mtu) {
- int processed = 0;
- a2dp_encode_called++;
+ unsigned int processed;
- if (a2dp->a2dp_buf_used + a2dp->frame_length > link_mtu)
- return 0;
- if (pcm_buf_size < a2dp->codesize)
+ if (a2dp_encode_index == MAX_A2DP_ENCODE_CALLS)
return 0;
-
- processed += a2dp->codesize;
- a2dp->a2dp_buf_used += a2dp->frame_length;
- a2dp->samples += processed / format_bytes;
-
+ processed = a2dp_encode_processed_bytes_val[a2dp_encode_index];
+ pcm_buf_size_val[a2dp_encode_index] = pcm_buf_size;
+ a2dp_encode_index++;
return processed;
}
int a2dp_write(struct a2dp_info* a2dp, int stream_fd, size_t link_mtu) {
- int ret, samples;
- if (a2dp->frame_length + a2dp->a2dp_buf_used < link_mtu)
- return 0;
-
- ret = a2dp_write_return_val[a2dp_write_index++];
- if (ret < 0)
- return ret;
-
- samples = a2dp->samples;
- a2dp->samples = 0;
- a2dp->a2dp_buf_used = 0;
- return samples;
+ return a2dp_write_return_val[a2dp_write_index++];
+ ;
}
int clock_gettime(clockid_t clk_id, struct timespec* tp) {
@@ -903,40 +556,38 @@ int clock_gettime(clockid_t clk_id, struct timespec* tp) {
}
void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
- iodev->area = mock_audio_area;
+ iodev->area = dummy_audio_area;
}
void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
-int cras_iodev_fill_odev_zeros(struct cras_iodev* odev, unsigned int frames) {
- struct cras_audio_area* area;
- cras_iodev_fill_odev_zeros_called++;
- cras_iodev_fill_odev_zeros_frames = frames;
+int cras_iodev_frames_queued(struct cras_iodev* iodev,
+ struct timespec* hw_tstamp) {
+ int rc;
+ cras_iodev_frames_queued_called++;
+ rc = iodev->frames_queued(iodev, hw_tstamp);
+ if (rc < 0)
+ return 0;
+ unsigned int num_queued = (unsigned int)rc;
+ if (num_queued < iodev->min_buffer_level)
+ return 0;
- odev->get_buffer(odev, &area, &frames);
- odev->put_buffer(odev, frames);
- return 0;
+ return num_queued - iodev->min_buffer_level;
}
void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
const struct cras_audio_format* fmt,
uint8_t* base_buffer) {
- mock_audio_area->channels[0].buf = base_buffer;
+ dummy_audio_area->channels[0].buf = base_buffer;
}
struct audio_thread* cras_iodev_list_get_audio_thread() {
return NULL;
}
-// From ewma_power
-void ewma_power_disable(struct ewma_power* ewma) {}
-
// From audio_thread
struct audio_thread_event_log* atlog;
-void audio_thread_add_events_callback(int fd,
- thread_callback cb,
- void* data,
- int events) {
+void audio_thread_add_write_callback(int fd, thread_callback cb, void* data) {
write_callback = cb;
write_callback_data = data;
}
@@ -945,18 +596,5 @@ int audio_thread_rm_callback_sync(struct audio_thread* thread, int fd) {
return 0;
}
-void audio_thread_config_events_callback(
- int fd,
- enum AUDIO_THREAD_EVENTS_CB_TRIGGER trigger) {
- audio_thread_config_events_callback_called++;
- audio_thread_config_events_callback_trigger = trigger;
-}
-}
-
-int cras_audio_thread_event_a2dp_overrun() {
- return 0;
-}
-
-int cras_audio_thread_event_a2dp_throttle() {
- return 0;
+void audio_thread_enable_callback(int fd, int enabled) {}
}
diff --git a/cras/src/tests/alsa_card_unittest.cc b/cras/src/tests/alsa_card_unittest.cc
index cfb67560..dd75b1d9 100644
--- a/cras/src/tests/alsa_card_unittest.cc
+++ b/cras/src/tests/alsa_card_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <gtest/gtest.h>
+#include <iniparser.h>
#include <stdio.h>
#include <sys/param.h>
#include <syslog.h>
@@ -75,10 +76,9 @@ static std::vector<int> cras_system_rm_select_fd_values;
static size_t snd_hctl_handle_events_called;
static size_t iniparser_freedict_called;
static size_t iniparser_load_called;
-static struct cras_device_blocklist* fake_blocklist;
-static int cras_device_blocklist_check_retval;
+static struct cras_device_blacklist* fake_blacklist;
+static int cras_device_blacklist_check_retval;
static unsigned ucm_create_called;
-static char ucm_create_name[100];
static unsigned ucm_destroy_called;
static size_t ucm_get_dev_for_mixer_called;
static size_t ucm_get_flag_called;
@@ -96,8 +96,6 @@ static int cras_alsa_mixer_add_controls_in_section_return_value;
static int cras_alsa_mixer_add_main_volume_control_by_name_called;
static int cras_alsa_mixer_add_main_volume_control_by_name_return_value;
static int ucm_get_echo_reference_dev_name_for_dev_called;
-static size_t cras_system_check_ignore_ucm_suffix_called;
-static bool cras_system_check_ignore_ucm_suffix_value;
static const char* ucm_get_echo_reference_dev_name_for_dev_return_value[4];
static void ResetStubData() {
@@ -147,10 +145,9 @@ static void ResetStubData() {
cras_system_rm_select_fd_values.clear();
iniparser_freedict_called = 0;
iniparser_load_called = 0;
- fake_blocklist = reinterpret_cast<struct cras_device_blocklist*>(3);
- cras_device_blocklist_check_retval = 0;
+ fake_blacklist = reinterpret_cast<struct cras_device_blacklist*>(3);
+ cras_device_blacklist_check_retval = 0;
ucm_create_called = 0;
- memset(ucm_create_name, 0, sizeof(ucm_get_flag_name));
ucm_destroy_called = 0;
ucm_get_dev_for_mixer_called = 0;
ucm_get_flag_called = 0;
@@ -169,8 +166,6 @@ static void ResetStubData() {
cras_alsa_mixer_add_main_volume_control_by_name_called = 0;
cras_alsa_mixer_add_main_volume_control_by_name_return_value = 0;
ucm_get_echo_reference_dev_name_for_dev_called = 0;
- cras_system_check_ignore_ucm_suffix_called = 0;
- cras_system_check_ignore_ucm_suffix_value = 0;
fake_dev1.nodes = NULL;
fake_dev2.nodes = NULL;
fake_dev3.nodes = NULL;
@@ -184,7 +179,7 @@ TEST(AlsaCard, CreateFailInvalidCard) {
ResetStubData();
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 55;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -199,7 +194,7 @@ TEST(AlsaCard, CreateFailMixerInit) {
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
cras_alsa_mixer_create_return = static_cast<struct cras_alsa_mixer*>(NULL);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -215,7 +210,7 @@ TEST(AlsaCard, CreateFailCtlOpen) {
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
snd_ctl_open_return = -1;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(1, snd_ctl_open_called);
@@ -234,7 +229,7 @@ TEST(AlsaCard, CreateFailHctlOpen) {
snd_hctl_open_pointer_val = NULL;
snd_hctl_open_return_value = -1;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(1, snd_ctl_open_called);
@@ -256,7 +251,7 @@ TEST(AlsaCard, CreateFailHctlLoad) {
card_info.card_index = 0;
snd_hctl_load_return_value = -1;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(1, snd_ctl_open_called);
@@ -282,7 +277,7 @@ TEST(AlsaCard, AddSelectForHctlNoDevices) {
snd_hctl_poll_descriptors_fds = poll_fds;
snd_hctl_poll_descriptors_num_fds = ARRAY_SIZE(poll_fds);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(1, snd_ctl_open_called);
@@ -317,7 +312,7 @@ TEST(AlsaCard, AddSelectForHctlWithDevices) {
snd_hctl_poll_descriptors_fds = poll_fds;
snd_hctl_poll_descriptors_num_fds = ARRAY_SIZE(poll_fds);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -349,7 +344,7 @@ TEST(AlsaCard, CreateFailCtlCardInfo) {
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
snd_ctl_card_info_ret = -1;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(1, snd_ctl_open_called);
@@ -365,7 +360,7 @@ TEST(AlsaCard, CreateNoDevices) {
ResetStubData();
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 1;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -390,7 +385,7 @@ TEST(AlsaCard, CreateOneOutputNextDevError) {
snd_ctl_pcm_next_device_return_error = true;
card_info.card_type = ALSA_CARD_TYPE_USB;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
@@ -411,7 +406,7 @@ TEST(AlsaCard, CreateOneOutput) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_USB;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -436,7 +431,7 @@ TEST(AlsaCard, CreateOneOutput) {
EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
}
-TEST(AlsaCard, CreateOneOutputBlocklisted) {
+TEST(AlsaCard, CreateOneOutputBlacklisted) {
struct cras_alsa_card* c;
int dev_nums[] = {0};
int info_rets[] = {0, -1};
@@ -448,10 +443,10 @@ TEST(AlsaCard, CreateOneOutputBlocklisted) {
snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
snd_ctl_pcm_info_rets = info_rets;
alsa_iodev_has_hctl_jacks_return = 0;
- cras_device_blocklist_check_retval = 1;
+ cras_device_blacklist_check_retval = 1;
card_info.card_type = ALSA_CARD_TYPE_USB;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -481,7 +476,7 @@ TEST(AlsaCard, CreateTwoOutputs) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -514,7 +509,7 @@ TEST(AlsaCard, CreateTwoDuplicateDeviceIndex) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -547,7 +542,7 @@ TEST(AlsaCard, CreateOneInput) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -579,7 +574,7 @@ TEST(AlsaCard, CreateOneInputAndOneOutput) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -611,7 +606,7 @@ TEST(AlsaCard, CreateOneInputAndOneOutputTwoDevices) {
snd_ctl_pcm_info_rets = info_rets;
card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
card_info.card_index = 0;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -662,7 +657,7 @@ TEST(AlsaCard, CreateOneOutputWithCoupledMixers) {
DL_APPEND(ucm_get_coupled_mixer_names_return_value, mixer_name_1);
DL_APPEND(ucm_get_coupled_mixer_names_return_value, mixer_name_2);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
@@ -708,7 +703,7 @@ TEST(AlsaCard, CreateFullyUCMNoSections) {
card_info.card_index = 0;
ucm_has_fully_specified_ucm_flag_return_value = 1;
ucm_get_sections_return_value = NULL;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
@@ -751,7 +746,7 @@ TEST(AlsaCard, CreateFullyUCMTwoMainVolume) {
DL_APPEND(ucm_get_main_volume_names_return_value, mixer_name_1);
DL_APPEND(ucm_get_main_volume_names_return_value, mixer_name_2);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
@@ -771,81 +766,34 @@ TEST(AlsaCard, CreateFullyUCMTwoMainVolume) {
EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
}
-TEST(AlsaCard, TwoUCMSecionsDependentPCM) {
- struct cras_alsa_card* c;
- cras_alsa_card_info card_info;
- struct ucm_section* sections = NULL;
- struct ucm_section* section;
-
- /* Create UCM so that MIC1 and MIC2 will be two nodes on the same iodev. */
- section = ucm_section_create("MIC1", "hw:0,3", 0, -1, CRAS_STREAM_INPUT,
- "my-sound-card Headset Jack", "gpio");
- DL_APPEND(sections, section);
- section = ucm_section_create("MIC2", "hw:0,5", 0, 3, CRAS_STREAM_INPUT,
- "my-sound-card Headset Jack", "gpio");
- DL_APPEND(sections, section);
-
- ResetStubData();
- int info_rets[] = {0, 0};
- card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
- card_info.card_index = 0;
- snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
- snd_ctl_pcm_info_rets = info_rets;
- ucm_has_fully_specified_ucm_flag_return_value = 1;
- ucm_get_sections_return_value = sections;
- ASSERT_NE(ucm_get_sections_return_value, (struct ucm_section*)NULL);
-
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
- NULL);
-
- EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
- EXPECT_EQ(snd_ctl_close_called, snd_ctl_open_called);
- EXPECT_EQ(1, snd_ctl_card_info_called);
- EXPECT_EQ(1, ucm_get_sections_called);
- EXPECT_EQ(1, snd_ctl_pcm_info_called);
- EXPECT_EQ(2, cras_alsa_mixer_add_controls_in_section_called);
- EXPECT_EQ(1, cras_alsa_iodev_create_called);
- EXPECT_EQ(2, cras_alsa_iodev_ucm_add_nodes_and_jacks_called);
- EXPECT_EQ(1, cras_alsa_iodev_ucm_complete_init_called);
-
- cras_alsa_card_destroy(c);
- EXPECT_EQ(1, ucm_destroy_called);
- EXPECT_EQ(1, cras_alsa_iodev_destroy_called);
- EXPECT_EQ(cras_alsa_iodev_create_return[0], cras_alsa_iodev_destroy_arg);
- EXPECT_EQ(cras_alsa_mixer_create_called, cras_alsa_mixer_destroy_called);
- EXPECT_EQ(iniparser_load_called, iniparser_freedict_called);
-}
-
struct ucm_section* GenerateUcmSections(void) {
struct ucm_section* sections = NULL;
struct ucm_section* section;
- section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
"my-sound-card Headset Jack", "gpio");
ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("Speaker", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- NULL, NULL);
+ section = ucm_section_create("Speaker", 0, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_add_coupled(section, "SPK-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "SPK-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("Internal Mic", "hw:0,1", 0, -1,
- CRAS_STREAM_INPUT, NULL, NULL);
+ section =
+ ucm_section_create("Internal Mic", 0, CRAS_STREAM_INPUT, NULL, NULL);
ucm_section_add_coupled(section, "INT-MIC-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "INT-MIC-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("Mic", "hw:0,1", 1, -1, CRAS_STREAM_INPUT,
+ section = ucm_section_create("Mic", 1, CRAS_STREAM_INPUT,
"my-sound-card Headset Jack", "gpio");
ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("HDMI", "hw:0,1", 2, -1, CRAS_STREAM_OUTPUT,
- NULL, NULL);
+ section = ucm_section_create("HDMI", 2, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_set_mixer_name(section, "HDMI");
DL_APPEND(sections, section);
@@ -865,7 +813,7 @@ TEST(AlsaCard, CreateFullyUCMFailureOnControls) {
cras_alsa_mixer_add_controls_in_section_return_value = -EINVAL;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_EQ(static_cast<struct cras_alsa_card*>(NULL), c);
@@ -902,7 +850,7 @@ TEST(AlsaCard, CreateFullyUCMFourDevicesFiveSections) {
cras_alsa_iodev_index_return[cras_alsa_iodev_create_return[3]] = 2;
ASSERT_NE(ucm_get_sections_return_value, (struct ucm_section*)NULL);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
@@ -949,7 +897,7 @@ TEST(AlsaCard, GG) {
ucm_get_echo_reference_dev_name_for_dev_return_value[0] = strdup(echo_ref);
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
+ c = cras_alsa_card_create(&card_info, device_config_dir, fake_blacklist,
NULL);
EXPECT_NE(static_cast<struct cras_alsa_card*>(NULL), c);
@@ -957,45 +905,6 @@ TEST(AlsaCard, GG) {
cras_alsa_card_destroy(c);
}
-TEST(AlsaCard, UCMSuffix) {
- struct cras_alsa_card* c;
- cras_alsa_card_info card_info;
- int info_rets[] = {0, 0, 0, 0, 0, -1};
-
- ResetStubData();
- card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
- card_info.card_index = 0;
- snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
- snd_ctl_pcm_info_rets = info_rets;
- ucm_has_fully_specified_ucm_flag_return_value = 1;
- ucm_get_sections_return_value = GenerateUcmSections();
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
- "1mic");
- EXPECT_EQ(0, strcmp(ucm_create_name, "TestName.1mic"));
- EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix_called);
- cras_alsa_card_destroy(c);
-}
-
-TEST(AlsaCard, UCMIgnoreSuffix) {
- struct cras_alsa_card* c;
- cras_alsa_card_info card_info;
- int info_rets[] = {0, 0, 0, 0, 0, -1};
-
- ResetStubData();
- card_info.card_type = ALSA_CARD_TYPE_INTERNAL;
- card_info.card_index = 0;
- snd_ctl_pcm_info_rets_size = ARRAY_SIZE(info_rets);
- snd_ctl_pcm_info_rets = info_rets;
- ucm_has_fully_specified_ucm_flag_return_value = 1;
- ucm_get_sections_return_value = GenerateUcmSections();
- cras_system_check_ignore_ucm_suffix_value = true;
- c = cras_alsa_card_create(&card_info, device_config_dir, fake_blocklist,
- "1mic");
- EXPECT_EQ(0, strcmp(ucm_create_name, "TestName"));
- EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix_called);
- cras_alsa_card_destroy(c);
-}
-
/* Stubs */
extern "C" {
@@ -1026,7 +935,6 @@ void cras_alsa_mixer_destroy(struct cras_alsa_mixer* cras_mixer) {
struct cras_iodev* alsa_iodev_create(size_t card_index,
const char* card_name,
size_t device_index,
- const char* pcm_name,
const char* dev_name,
const char* dev_id,
enum CRAS_ALSA_CARD_TYPE card_type,
@@ -1195,18 +1103,17 @@ struct cras_volume_curve* cras_card_config_get_volume_curve_for_control(
return NULL;
}
-int cras_device_blocklist_check(struct cras_device_blocklist* blocklist,
+int cras_device_blacklist_check(struct cras_device_blacklist* blacklist,
unsigned vendor_id,
unsigned product_id,
unsigned device_index) {
- EXPECT_EQ(fake_blocklist, blocklist);
+ EXPECT_EQ(fake_blacklist, blacklist);
- return cras_device_blocklist_check_retval;
+ return cras_device_blacklist_check_retval;
}
struct cras_use_case_mgr* ucm_create(const char* name) {
ucm_create_called++;
- strncpy(ucm_create_name, name, sizeof(ucm_create_name) - 1);
return reinterpret_cast<struct cras_use_case_mgr*>(0x44);
}
@@ -1264,11 +1171,6 @@ int cras_alsa_mixer_add_controls_in_section(struct cras_alsa_mixer* cmix,
return cras_alsa_mixer_add_controls_in_section_return_value;
}
-bool cras_system_check_ignore_ucm_suffix(const char* card_name) {
- cras_system_check_ignore_ucm_suffix_called++;
- return cras_system_check_ignore_ucm_suffix_value;
-}
-
void ucm_free_mixer_names(struct mixer_name* names) {
struct mixer_name* m;
DL_FOREACH (names, m) {
diff --git a/cras/src/tests/alsa_helpers_unittest.cc b/cras/src/tests/alsa_helpers_unittest.cc
index 32df30af..0e8112cd 100644
--- a/cras/src/tests/alsa_helpers_unittest.cc
+++ b/cras/src/tests/alsa_helpers_unittest.cc
@@ -163,12 +163,34 @@ TEST(AlsaHelper, MatchChannelMapCapability51) {
}
TEST(AlsaHelper, Htimestamp) {
- snd_pcm_t* mock_handle = reinterpret_cast<snd_pcm_t*>(0x1);
+ snd_pcm_t* dummy_handle = reinterpret_cast<snd_pcm_t*>(0x1);
snd_pcm_uframes_t used;
snd_pcm_uframes_t severe_underrun_frames = 480;
struct timespec tstamp;
+ int htimestamp_enabled = 1;
const char* dev_name = "dev_name";
+ // Enable htimestamp use.
+ ResetStubData();
+ EXPECT_EQ(0, cras_alsa_set_swparams(dummy_handle, &htimestamp_enabled));
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_mode_called, 1);
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_type_called, 1);
+ EXPECT_EQ(1, htimestamp_enabled);
+
+ // Try to enable htimestamp use: not supported.
+ ResetStubData();
+ snd_pcm_sw_params_ret_vals.push_back(-EINVAL);
+ EXPECT_EQ(0, cras_alsa_set_swparams(dummy_handle, &htimestamp_enabled));
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_mode_called, 2);
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_type_called, 2);
+ EXPECT_EQ(0, htimestamp_enabled);
+
+ // Disable htimestamp use.
+ ResetStubData();
+ EXPECT_EQ(0, cras_alsa_set_swparams(dummy_handle, &htimestamp_enabled));
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_mode_called, 0);
+ EXPECT_EQ(snd_pcm_sw_params_set_tstamp_type_called, 0);
+
ResetStubData();
tstamp.tv_sec = 0;
tstamp.tv_nsec = 0;
@@ -176,7 +198,7 @@ TEST(AlsaHelper, Htimestamp) {
snd_pcm_htimestamp_tstamp_ret_val.tv_sec = 10;
snd_pcm_htimestamp_tstamp_ret_val.tv_nsec = 10000;
- cras_alsa_get_avail_frames(mock_handle, 48000, severe_underrun_frames,
+ cras_alsa_get_avail_frames(dummy_handle, 48000, severe_underrun_frames,
dev_name, &used, &tstamp);
EXPECT_EQ(used, snd_pcm_htimestamp_avail_ret_val);
EXPECT_EQ(tstamp.tv_sec, snd_pcm_htimestamp_tstamp_ret_val.tv_sec);
@@ -184,7 +206,7 @@ TEST(AlsaHelper, Htimestamp) {
}
TEST(AlsaHelper, GetAvailFramesSevereUnderrun) {
- snd_pcm_t* mock_handle = reinterpret_cast<snd_pcm_t*>(0x1);
+ snd_pcm_t* dummy_handle = reinterpret_cast<snd_pcm_t*>(0x1);
snd_pcm_uframes_t avail;
snd_pcm_uframes_t severe_underrun_frames = 480;
snd_pcm_uframes_t buffer_size = 48000;
@@ -194,7 +216,7 @@ TEST(AlsaHelper, GetAvailFramesSevereUnderrun) {
ResetStubData();
snd_pcm_htimestamp_avail_ret_val = buffer_size + severe_underrun_frames + 1;
- rc = cras_alsa_get_avail_frames(mock_handle, buffer_size,
+ rc = cras_alsa_get_avail_frames(dummy_handle, buffer_size,
severe_underrun_frames, dev_name, &avail,
&tstamp);
// Returns -EPIPE when severe underrun happens.
@@ -202,7 +224,7 @@ TEST(AlsaHelper, GetAvailFramesSevereUnderrun) {
ResetStubData();
snd_pcm_htimestamp_avail_ret_val = buffer_size + severe_underrun_frames;
- rc = cras_alsa_get_avail_frames(mock_handle, buffer_size,
+ rc = cras_alsa_get_avail_frames(dummy_handle, buffer_size,
severe_underrun_frames, dev_name, &avail,
&tstamp);
// Underrun which is not severe enough will be masked.
@@ -212,7 +234,7 @@ TEST(AlsaHelper, GetAvailFramesSevereUnderrun) {
ResetStubData();
snd_pcm_htimestamp_avail_ret_val = buffer_size - 1;
- rc = cras_alsa_get_avail_frames(mock_handle, buffer_size,
+ rc = cras_alsa_get_avail_frames(dummy_handle, buffer_size,
severe_underrun_frames, dev_name, &avail,
&tstamp);
// When avail < buffer_size, there is no underrun.
diff --git a/cras/src/tests/alsa_io_unittest.cc b/cras/src/tests/alsa_io_unittest.cc
index 021b4789..2211f343 100644
--- a/cras/src/tests/alsa_io_unittest.cc
+++ b/cras/src/tests/alsa_io_unittest.cc
@@ -32,7 +32,6 @@ static int cras_alsa_start_called;
static uint8_t* cras_alsa_mmap_begin_buffer;
static size_t cras_alsa_mmap_begin_frames;
static size_t cras_alsa_fill_properties_called;
-static bool cras_alsa_support_8_channels;
static size_t alsa_mixer_set_dBFS_called;
static int alsa_mixer_set_dBFS_value;
static const struct mixer_control* alsa_mixer_set_dBFS_output;
@@ -50,6 +49,8 @@ static struct mixer_control*
cras_alsa_mixer_get_control_for_section_return_value;
static size_t sys_get_volume_called;
static size_t sys_get_volume_return_value;
+static size_t sys_get_capture_gain_called;
+static long sys_get_capture_gain_return_value;
static size_t alsa_mixer_set_mute_called;
static int alsa_mixer_set_mute_value;
static size_t alsa_mixer_get_dB_range_called;
@@ -76,6 +77,7 @@ static std::vector<struct mixer_control*>
static std::vector<int> cras_alsa_mixer_set_output_active_state_values;
static cras_audio_format* fake_format;
static size_t sys_set_volume_limits_called;
+static size_t sys_set_capture_gain_limits_called;
static size_t cras_alsa_mixer_get_minimum_capture_gain_called;
static size_t cras_alsa_mixer_get_maximum_capture_gain_called;
static struct mixer_control* cras_alsa_jack_get_mixer_output_ret;
@@ -94,7 +96,6 @@ static int cras_alsa_jack_list_has_hctl_jacks_return_val;
static jack_state_change_callback* cras_alsa_jack_list_create_cb;
static void* cras_alsa_jack_list_create_cb_data;
static char test_card_name[] = "TestCard";
-static char test_pcm_name[] = "TestPCM";
static char test_dev_name[] = "TestDev";
static char test_dev_id[] = "TestDevId";
static size_t cras_iodev_add_node_called;
@@ -105,6 +106,8 @@ static unsigned cras_alsa_jack_enable_ucm_called;
static unsigned ucm_set_enabled_called;
static size_t cras_iodev_update_dsp_called;
static const char* cras_iodev_update_dsp_name;
+static size_t ucm_get_dsp_name_default_called;
+static const char* ucm_get_dsp_name_default_value;
typedef std::map<const char*, std::string> DspNameMap;
static size_t ucm_get_dsp_name_for_dev_called;
static DspNameMap ucm_get_dsp_name_for_dev_values;
@@ -120,6 +123,13 @@ static const char* cras_alsa_jack_get_name_ret_value = 0;
static char default_jack_name[] = "Something Jack";
static int auto_unplug_input_node_ret = 0;
static int auto_unplug_output_node_ret = 0;
+static int ucm_get_min_software_gain_called;
+static int ucm_get_min_software_gain_ret_value;
+static long ucm_get_min_software_gain_value;
+static int ucm_get_max_software_gain_called;
+static int ucm_get_max_software_gain_ret_value;
+static long ucm_get_max_software_gain_value;
+static long cras_system_set_capture_gain_limits_set_value[2];
static long cras_alsa_mixer_get_minimum_capture_gain_ret_value;
static long cras_alsa_mixer_get_maximum_capture_gain_ret_value;
static snd_pcm_state_t snd_pcm_state_ret;
@@ -137,15 +147,14 @@ static int cras_iodev_frames_queued_ret;
static int cras_iodev_buffer_avail_ret;
static int cras_alsa_resume_appl_ptr_called;
static int cras_alsa_resume_appl_ptr_ahead;
+static int ucm_get_enable_htimestamp_flag_ret;
static const struct cras_volume_curve* fake_get_dBFS_volume_curve_val;
static int cras_iodev_dsp_set_swap_mode_for_node_called;
static std::map<std::string, long> ucm_get_default_node_gain_values;
-static std::map<std::string, long> ucm_get_intrinsic_sensitivity_values;
static thread_callback audio_thread_cb;
static void* audio_thread_cb_data;
static int hotword_send_triggered_msg_called;
static struct timespec clock_gettime_retspec;
-static unsigned cras_iodev_reset_rate_estimator_called;
void ResetStubData() {
cras_alsa_open_called = 0;
@@ -154,8 +163,8 @@ void ResetStubData() {
cras_alsa_get_avail_frames_avail = 0;
cras_alsa_start_called = 0;
cras_alsa_fill_properties_called = 0;
- cras_alsa_support_8_channels = false;
sys_get_volume_called = 0;
+ sys_get_capture_gain_called = 0;
alsa_mixer_set_dBFS_called = 0;
alsa_mixer_set_capture_dBFS_called = 0;
sys_get_mute_called = 0;
@@ -174,6 +183,8 @@ void ResetStubData() {
cras_alsa_mixer_set_output_active_state_outputs.clear();
cras_alsa_mixer_set_output_active_state_values.clear();
sys_set_volume_limits_called = 0;
+ sys_set_capture_gain_limits_called = 0;
+ sys_get_capture_gain_return_value = 0;
cras_alsa_mixer_get_minimum_capture_gain_called = 0;
cras_alsa_mixer_get_maximum_capture_gain_called = 0;
cras_alsa_mixer_get_output_volume_curve_called = 0;
@@ -193,6 +204,8 @@ void ResetStubData() {
ucm_set_enabled_called = 0;
cras_iodev_update_dsp_called = 0;
cras_iodev_update_dsp_name = 0;
+ ucm_get_dsp_name_default_called = 0;
+ ucm_get_dsp_name_default_value = NULL;
ucm_get_dsp_name_for_dev_called = 0;
ucm_get_dsp_name_for_dev_values.clear();
cras_iodev_free_resources_called = 0;
@@ -204,8 +217,16 @@ void ResetStubData() {
cras_alsa_jack_get_name_called = 0;
cras_alsa_jack_get_name_ret_value = default_jack_name;
cras_alsa_jack_update_monitor_fake_name = 0;
+ ucm_get_min_software_gain_called = 0;
+ ucm_get_min_software_gain_ret_value = -1;
+ ucm_get_min_software_gain_value = 0;
+ ucm_get_max_software_gain_called = 0;
+ ucm_get_max_software_gain_ret_value = -1;
+ ucm_get_max_software_gain_value = 0;
cras_card_config_get_volume_curve_for_control_called = 0;
cras_card_config_get_volume_curve_vals.clear();
+ cras_system_set_capture_gain_limits_set_value[0] = -1;
+ cras_system_set_capture_gain_limits_set_value[1] = -1;
cras_alsa_mixer_get_minimum_capture_gain_ret_value = 0;
cras_alsa_mixer_get_maximum_capture_gain_ret_value = 0;
snd_pcm_state_ret = SND_PCM_STATE_RUNNING;
@@ -219,11 +240,10 @@ void ResetStubData() {
cras_iodev_buffer_avail_ret = 0;
cras_alsa_resume_appl_ptr_called = 0;
cras_alsa_resume_appl_ptr_ahead = 0;
+ ucm_get_enable_htimestamp_flag_ret = 0;
fake_get_dBFS_volume_curve_val = NULL;
cras_iodev_dsp_set_swap_mode_for_node_called = 0;
ucm_get_default_node_gain_values.clear();
- ucm_get_intrinsic_sensitivity_values.clear();
- cras_iodev_reset_rate_estimator_called = 0;
}
static long fake_get_dBFS(const struct cras_volume_curve* curve,
@@ -244,13 +264,13 @@ static struct cras_iodev* alsa_iodev_create_with_default_parameters(
struct cras_card_config* config,
struct cras_use_case_mgr* ucm,
enum CRAS_STREAM_DIRECTION direction) {
- return alsa_iodev_create(card_index, test_card_name, 0, test_pcm_name,
- test_dev_name, dev_id, card_type, is_first, mixer,
- config, ucm, fake_hctl, direction, 0, 0,
- (char*)"123");
+ return alsa_iodev_create(card_index, test_card_name, 0, test_dev_name, dev_id,
+ card_type, is_first, mixer, config, ucm, fake_hctl,
+ direction, 0, 0, (char*)"123");
}
namespace {
+
TEST(AlsaIoInit, InitializeInvalidDirection) {
struct alsa_io* aio;
@@ -272,13 +292,12 @@ TEST(AlsaIoInit, InitializePlayback) {
/* Get volume curve twice for iodev, and default node. */
EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
+ EXPECT_EQ(0, cras_alsa_fill_properties_called);
EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
EXPECT_EQ(
0, strncmp(test_card_name, aio->base.info.name, strlen(test_card_name)));
- EXPECT_EQ(1, cras_iodev_update_dsp_called);
- EXPECT_EQ("", cras_iodev_update_dsp_name);
+ EXPECT_EQ(0, ucm_get_dsp_name_default_called);
+ EXPECT_EQ(NULL, cras_iodev_update_dsp_name);
ASSERT_NE(reinterpret_cast<const char*>(NULL), aio->dev_name);
EXPECT_EQ(0, strcmp(test_dev_name, aio->dev_name));
ASSERT_NE(reinterpret_cast<const char*>(NULL), aio->dev_id);
@@ -362,11 +381,6 @@ TEST(AlsaIoInit, DefaultNodeUSBCard) {
ASSERT_STREQ(DEFAULT, aio->base.active_node->name);
ASSERT_EQ(1, aio->base.active_node->plugged);
EXPECT_EQ(2, cras_iodev_set_node_plugged_called);
-
- /* No extra gain applied. */
- ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS,
- aio->base.active_node->intrinsic_sensitivity);
- ASSERT_EQ(0, aio->base.active_node->capture_gain);
alsa_iodev_destroy((struct cras_iodev*)aio);
}
@@ -380,8 +394,6 @@ TEST(AlsaIoInit, OpenPlayback) {
0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, NULL,
CRAS_STREAM_OUTPUT);
ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
- /* Call open_dev once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_open_called);
EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
aio = (struct alsa_io*)iodev;
format.frame_rate = 48000;
@@ -392,9 +404,9 @@ TEST(AlsaIoInit, OpenPlayback) {
aio->free_running = 1;
aio->filled_zeros_for_draining = 512;
iodev->open_dev(iodev);
- EXPECT_EQ(2, cras_alsa_open_called);
+ EXPECT_EQ(1, cras_alsa_open_called);
iodev->configure_dev(iodev);
- EXPECT_EQ(2, cras_alsa_open_called);
+ EXPECT_EQ(1, cras_alsa_open_called);
EXPECT_EQ(1, sys_set_volume_limits_called);
EXPECT_EQ(1, alsa_mixer_set_dBFS_called);
EXPECT_EQ(0, cras_alsa_start_called);
@@ -471,25 +483,120 @@ TEST(AlsaIoInit, UsbCardUseSoftwareVolume) {
alsa_iodev_destroy(iodev);
}
-TEST(AlsaIoInit, SoftwareGainIntrinsicSensitivity) {
+TEST(AlsaIoInit, UseSoftwareGain) {
struct cras_iodev* iodev;
struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
- long intrinsic_sensitivity = -2700;
+ /* MaxSoftwareGain is specified in UCM */
+ ResetStubData();
+ ucm_get_min_software_gain_ret_value = 1;
+ ucm_get_min_software_gain_value = 1;
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
+ iodev = alsa_iodev_create_with_default_parameters(
+ 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
+ CRAS_STREAM_INPUT);
+ ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
+ EXPECT_EQ(1, iodev->active_node->software_volume_needed);
+ EXPECT_EQ(DEFAULT_MIN_CAPTURE_GAIN, iodev->active_node->min_software_gain);
+ EXPECT_EQ(2000, iodev->active_node->max_software_gain);
+ ASSERT_EQ(1, sys_set_capture_gain_limits_called);
+ /* The gain range is [DEFAULT_MIN_CAPTURE_GAIN, maximum software gain]. */
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[0],
+ DEFAULT_MIN_CAPTURE_GAIN);
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[1], 2000);
+
+ alsa_iodev_destroy(iodev);
+
+ /* MaxSoftwareGain and MinSoftwareGain are specified in UCM. */
ResetStubData();
+ ucm_get_min_software_gain_ret_value = 0;
+ ucm_get_min_software_gain_value = 1000;
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
+ iodev = alsa_iodev_create_with_default_parameters(
+ 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
+ CRAS_STREAM_INPUT);
+ ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
+ EXPECT_EQ(1, iodev->active_node->software_volume_needed);
+ EXPECT_EQ(1000, iodev->active_node->min_software_gain);
+ EXPECT_EQ(2000, iodev->active_node->max_software_gain);
+ ASSERT_EQ(1, sys_set_capture_gain_limits_called);
+ /* The gain range is [minimum software gain, maximum software gain]. */
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[0], 1000);
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[1], 2000);
- // Set intrinsic sensitivity to -2700 * 0.01 dBFS/Pa.
- ucm_get_intrinsic_sensitivity_values[INTERNAL_MICROPHONE] =
- intrinsic_sensitivity;
+ alsa_iodev_destroy(iodev);
+
+ /* MinSoftwareGain is larger than MaxSoftwareGain in UCM. */
+ ResetStubData();
+ ucm_get_min_software_gain_ret_value = 0;
+ ucm_get_min_software_gain_value = 3000;
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
+ iodev = alsa_iodev_create_with_default_parameters(
+ 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
+ CRAS_STREAM_INPUT);
+ ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
+ EXPECT_EQ(1, iodev->active_node->software_volume_needed);
+ EXPECT_EQ(DEFAULT_MIN_CAPTURE_GAIN, iodev->active_node->min_software_gain);
+ EXPECT_EQ(2000, iodev->active_node->max_software_gain);
+ ASSERT_EQ(1, sys_set_capture_gain_limits_called);
+ /* The gain range is [DEFAULT_MIN_CAPTURE_GAIN, maximum software gain]. */
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[0],
+ DEFAULT_MIN_CAPTURE_GAIN);
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[1], 2000);
+
+ alsa_iodev_destroy(iodev);
+
+ /* MaxSoftwareGain is not specified in UCM. */
+ ResetStubData();
+ ucm_get_max_software_gain_ret_value = 1;
+ ucm_get_max_software_gain_value = 1;
+ cras_alsa_mixer_get_minimum_capture_gain_ret_value = -500;
+ cras_alsa_mixer_get_maximum_capture_gain_ret_value = 500;
+ iodev = alsa_iodev_create_with_default_parameters(
+ 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
+ CRAS_STREAM_INPUT);
+ ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
+ EXPECT_EQ(0, iodev->active_node->software_volume_needed);
+ EXPECT_EQ(0, iodev->active_node->max_software_gain);
+ ASSERT_EQ(1, sys_set_capture_gain_limits_called);
+ /* The gain range is reported by controls. */
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[0], -500);
+ ASSERT_EQ(cras_system_set_capture_gain_limits_set_value[1], 500);
+
+ alsa_iodev_destroy(iodev);
+}
+
+TEST(AlsaIoInit, SoftwareGainWithDefaultNodeGain) {
+ struct cras_iodev* iodev;
+ struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
+ long system_gain = 500;
+ long default_node_gain = -1000;
+
+ ResetStubData();
+
+ // Use software gain.
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
+
+ // Set default node gain to -1000 * 0.01 dB.
+ ucm_get_default_node_gain_values[INTERNAL_MICROPHONE] = default_node_gain;
// Assume this is the first device so it gets internal mic node name.
iodev = alsa_iodev_create_with_default_parameters(
0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
CRAS_STREAM_INPUT);
ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
- ASSERT_EQ(intrinsic_sensitivity, iodev->active_node->intrinsic_sensitivity);
- ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS - intrinsic_sensitivity,
- iodev->active_node->capture_gain);
+
+ // Gain on node is 300 * 0.01 dB.
+ iodev->active_node->capture_gain = default_node_gain;
+
+ // cras_iodev will call cras_iodev_adjust_active_node_gain to get gain for
+ // software gain.
+ ASSERT_EQ(system_gain + default_node_gain,
+ cras_iodev_adjust_active_node_gain(iodev, system_gain));
alsa_iodev_destroy(iodev);
}
@@ -506,8 +613,7 @@ TEST(AlsaIoInit, RouteBasedOnJackCallback) {
ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
+ EXPECT_EQ(0, cras_alsa_fill_properties_called);
EXPECT_EQ(1, cras_alsa_mixer_list_outputs_called);
EXPECT_EQ(1, cras_alsa_jack_list_create_called);
EXPECT_EQ(1, cras_alsa_jack_list_find_jacks_by_name_matching_called);
@@ -536,8 +642,7 @@ TEST(AlsaIoInit, RouteBasedOnInputJackCallback) {
ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
+ EXPECT_EQ(0, cras_alsa_fill_properties_called);
EXPECT_EQ(1, cras_alsa_jack_list_create_called);
EXPECT_EQ(1, cras_alsa_jack_list_find_jacks_by_name_matching_called);
EXPECT_EQ(0, cras_alsa_jack_list_add_jack_for_section_called);
@@ -564,8 +669,7 @@ TEST(AlsaIoInit, InitializeCapture) {
ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
+ EXPECT_EQ(0, cras_alsa_fill_properties_called);
EXPECT_EQ(1, cras_alsa_mixer_list_inputs_called);
alsa_iodev_destroy((struct cras_iodev*)aio);
@@ -593,6 +697,8 @@ TEST(AlsaIoInit, OpenCapture) {
EXPECT_EQ(1, cras_alsa_open_called);
EXPECT_EQ(1, cras_alsa_mixer_get_minimum_capture_gain_called);
EXPECT_EQ(1, cras_alsa_mixer_get_maximum_capture_gain_called);
+ EXPECT_EQ(1, sys_set_capture_gain_limits_called);
+ EXPECT_EQ(1, sys_get_capture_gain_called);
EXPECT_EQ(1, alsa_mixer_set_capture_dBFS_called);
EXPECT_EQ(1, sys_get_capture_mute_called);
EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
@@ -608,7 +714,8 @@ TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithDefaultNodeGain) {
struct cras_iodev* iodev;
struct cras_audio_format format;
struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
- long default_node_gain = 1000;
+ long system_gain = 2000;
+ long default_node_gain = -1000;
ResetStubData();
// Set default node gain to -1000 * 0.01 dB.
@@ -624,24 +731,15 @@ TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithDefaultNodeGain) {
// Check the default node gain is the same as what specified in UCM.
EXPECT_EQ(default_node_gain, iodev->active_node->capture_gain);
- cras_alsa_mixer_get_minimum_capture_gain_ret_value = 0;
- cras_alsa_mixer_get_maximum_capture_gain_ret_value = 2000;
-
- iodev->open_dev(iodev);
- iodev->configure_dev(iodev);
- iodev->close_dev(iodev);
-
- // Hardware gain is in the hardware gain range and set to 1000 * 0.01 dB.
- EXPECT_EQ(default_node_gain, alsa_mixer_set_capture_dBFS_value);
-
- // Check we do respect the hardware maximum capture gain.
- cras_alsa_mixer_get_maximum_capture_gain_ret_value = 500;
+ // System gain is set to 2000 * 0.01 dB.
+ sys_get_capture_gain_return_value = system_gain;
iodev->open_dev(iodev);
iodev->configure_dev(iodev);
iodev->close_dev(iodev);
- EXPECT_EQ(500, alsa_mixer_set_capture_dBFS_value);
+ // Hardware gain is set to (2000 - 1000) * 0.01 dB.
+ EXPECT_EQ(system_gain + default_node_gain, alsa_mixer_set_capture_dBFS_value);
alsa_iodev_destroy(iodev);
free(fake_format);
@@ -654,6 +752,8 @@ TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithSoftwareGain) {
/* Meet the requirements of using software gain. */
ResetStubData();
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
iodev = alsa_iodev_create_with_default_parameters(
0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
@@ -664,6 +764,9 @@ TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithSoftwareGain) {
format.num_channels = 1;
cras_iodev_set_format(iodev, &format);
+ /* System gain is set to 1000 * 0.01 dB */
+ sys_get_capture_gain_return_value = 1000;
+
iodev->open_dev(iodev);
iodev->configure_dev(iodev);
iodev->close_dev(iodev);
@@ -673,43 +776,12 @@ TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithSoftwareGain) {
/* Test the case where software gain is not needed. */
iodev->active_node->software_volume_needed = 0;
- iodev->active_node->capture_gain = 1000;
iodev->open_dev(iodev);
iodev->configure_dev(iodev);
iodev->close_dev(iodev);
- /* Hardware gain is set to 1000 * 0.01 dB as got from catpure_gain.*/
- EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_value);
-
- alsa_iodev_destroy(iodev);
- free(fake_format);
-}
-
-TEST(AlsaIoInit, OpenCaptureSetCaptureGainWithDefaultUsbDevice) {
- struct cras_iodev* iodev;
- struct cras_audio_format format;
-
- iodev = alsa_iodev_create_with_default_parameters(0, NULL, ALSA_CARD_TYPE_USB,
- 0, fake_mixer, fake_config,
- NULL, CRAS_STREAM_INPUT);
- ASSERT_EQ(0, alsa_iodev_legacy_complete_init(iodev));
-
- format.frame_rate = 48000;
- format.num_channels = 1;
- cras_iodev_set_format(iodev, &format);
-
- iodev->active_node->intrinsic_sensitivity = DEFAULT_CAPTURE_VOLUME_DBFS;
- iodev->active_node->capture_gain = 0;
-
- ResetStubData();
- iodev->open_dev(iodev);
- iodev->configure_dev(iodev);
-
- EXPECT_EQ(1, sys_get_capture_mute_called);
- EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
-
- /* Not change mixer controls for USB devices without UCM config. */
- EXPECT_EQ(0, alsa_mixer_set_capture_dBFS_called);
+ /* Hardware gain is set to 1000 * 0.01 dB as got from system capture gain.*/
+ EXPECT_EQ(1000, alsa_mixer_set_capture_dBFS_value);
alsa_iodev_destroy(iodev);
free(fake_format);
@@ -783,6 +855,7 @@ TEST(AlsaIoInit, DspNameDefault) {
struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
ResetStubData();
+ ucm_get_dsp_name_default_value = "hello";
aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
CRAS_STREAM_OUTPUT);
@@ -790,17 +863,19 @@ TEST(AlsaIoInit, DspNameDefault) {
EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
- EXPECT_STREQ("", cras_iodev_update_dsp_name);
+ EXPECT_EQ(1, ucm_get_dsp_name_default_called);
+ EXPECT_STREQ("hello", cras_iodev_update_dsp_name);
alsa_iodev_destroy((struct cras_iodev*)aio);
}
-TEST(AlsaIoInit, DspName) {
+TEST(AlsaIoInit, DspNameWithoutDefault) {
struct alsa_io* aio;
struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
ResetStubData();
+ ucm_get_dsp_name_default_value = NULL;
ucm_get_dsp_name_for_dev_values[DEFAULT] = "hello";
aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
@@ -809,6 +884,7 @@ TEST(AlsaIoInit, DspName) {
EXPECT_EQ(2, cras_card_config_get_volume_curve_for_control_called);
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
+ EXPECT_EQ(1, ucm_get_dsp_name_default_called);
EXPECT_STREQ("hello", cras_iodev_update_dsp_name);
alsa_iodev_destroy((struct cras_iodev*)aio);
@@ -822,14 +898,16 @@ TEST(AlsaIoInit, DspNameJackOverride) {
static const char* jack_name = "jack";
ResetStubData();
+ ucm_get_dsp_name_default_value = "default_dsp";
aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
0, NULL, ALSA_CARD_TYPE_INTERNAL, 0, fake_mixer, fake_config, fake_ucm,
CRAS_STREAM_OUTPUT);
ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
EXPECT_EQ(1, ucm_get_dsp_name_for_dev_called);
+ EXPECT_EQ(1, ucm_get_dsp_name_default_called);
EXPECT_EQ(1, cras_iodev_update_dsp_called);
- EXPECT_STREQ("", cras_iodev_update_dsp_name);
+ EXPECT_STREQ("default_dsp", cras_iodev_update_dsp_name);
cras_alsa_jack_get_name_ret_value = jack_name;
ucm_get_dsp_name_for_dev_values[jack_name] = "override_dsp";
@@ -837,6 +915,7 @@ TEST(AlsaIoInit, DspNameJackOverride) {
cras_alsa_jack_list_create_cb(jack, 1, cras_alsa_jack_list_create_cb_data);
EXPECT_EQ(2, cras_alsa_jack_get_name_called);
EXPECT_EQ(2, ucm_get_dsp_name_for_dev_called);
+ EXPECT_EQ(1, ucm_get_dsp_name_default_called);
// Mark the jack node as active.
alsa_iodev_set_active_node(&aio->base, aio->base.nodes->next, 1);
@@ -846,9 +925,10 @@ TEST(AlsaIoInit, DspNameJackOverride) {
// Mark the default node as active.
alsa_iodev_set_active_node(&aio->base, aio->base.nodes, 1);
+ EXPECT_EQ(1, ucm_get_dsp_name_default_called);
EXPECT_EQ(2, ucm_get_dsp_name_for_dev_called);
EXPECT_EQ(3, cras_iodev_update_dsp_called);
- EXPECT_STREQ("", cras_iodev_update_dsp_name);
+ EXPECT_STREQ("default_dsp", cras_iodev_update_dsp_name);
alsa_iodev_destroy((struct cras_iodev*)aio);
}
@@ -911,30 +991,6 @@ TEST(AlsaIoInit, SwapMode) {
free(fake_node);
}
-TEST(AlsaIoInit, MaxSupportedChannels) {
- struct alsa_io* aio;
- struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
- int i;
-
- // i = 0: cras_alsa_support_8_channels is false, support 2 channels only.
- // i = 1: cras_alsa_support_8_channels is true, support up to 8 channels.
- for (i = 0; i < 2; i++) {
- ResetStubData();
- cras_alsa_support_8_channels = (bool)i;
-
- aio = (struct alsa_io*)alsa_iodev_create_with_default_parameters(
- 0, test_dev_id, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config,
- NULL, CRAS_STREAM_OUTPUT);
- ASSERT_EQ(0, alsa_iodev_legacy_complete_init((struct cras_iodev*)aio));
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
- uint32_t max_channels = (cras_alsa_support_8_channels) ? 8 : 2;
- EXPECT_EQ(max_channels, aio->base.info.max_supported_channels);
- alsa_iodev_destroy((struct cras_iodev*)aio);
- EXPECT_EQ(1, cras_iodev_free_resources_called);
- }
-}
-
// Test that system settins aren't touched if no streams active.
TEST(AlsaOutputNode, SystemSettingsWhenInactive) {
int rc;
@@ -1039,8 +1095,8 @@ TEST(AlsaOutputNode, TwoJacksHeadphoneLineout) {
EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
// First node 'Headphone'
- section = ucm_section_create(HEADPHONE, "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- "fake-jack", "gpio");
+ section =
+ ucm_section_create(HEADPHONE, 0, CRAS_STREAM_OUTPUT, "fake-jack", "gpio");
ucm_section_set_mixer_name(section, HEADPHONE);
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(10);
@@ -1050,8 +1106,8 @@ TEST(AlsaOutputNode, TwoJacksHeadphoneLineout) {
ucm_section_free_list(section);
// Second node 'Line Out'
- section = ucm_section_create("Line Out", "hw:0.1", 0, -1, CRAS_STREAM_OUTPUT,
- "fake-jack", "gpio");
+ section = ucm_section_create("Line Out", 0, CRAS_STREAM_OUTPUT, "fake-jack",
+ "gpio");
ucm_section_set_mixer_name(section, HEADPHONE);
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(20);
@@ -1072,43 +1128,6 @@ TEST(AlsaOutputNode, TwoJacksHeadphoneLineout) {
alsa_iodev_destroy(iodev);
}
-TEST(AlsaOutputNode, MaxSupportedChannels) {
- struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
- struct cras_iodev* iodev;
- struct ucm_section* section;
- int i;
-
- // i = 0: cras_alsa_support_8_channels is false, support 2 channels only.
- // i = 1: cras_alsa_support_8_channels is true, support up to 8 channels.
- for (i = 0; i < 2; i++) {
- ResetStubData();
- cras_alsa_support_8_channels = (bool)i;
-
- // Create the IO device.
- iodev = alsa_iodev_create_with_default_parameters(
- 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
- CRAS_STREAM_OUTPUT);
- ASSERT_NE(iodev, (void*)NULL);
-
- // Node without controls or jacks.
- section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 1, -1,
- CRAS_STREAM_OUTPUT, NULL, NULL);
- // Device index doesn't match.
- EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
- section->dev_idx = 0;
- ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
- ucm_section_free_list(section);
-
- // Complete initialization, and make first node active.
- alsa_iodev_ucm_complete_init(iodev);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
- uint32_t max_channels = (cras_alsa_support_8_channels) ? 8 : 2;
- EXPECT_EQ(max_channels, iodev->info.max_supported_channels);
- alsa_iodev_destroy(iodev);
- }
-}
-
TEST(AlsaOutputNode, OutputsFromUCM) {
struct alsa_io* aio;
struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
@@ -1137,8 +1156,8 @@ TEST(AlsaOutputNode, OutputsFromUCM) {
EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
// First node.
- section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 0, -1,
- CRAS_STREAM_OUTPUT, NULL, NULL);
+ section =
+ ucm_section_create(INTERNAL_SPEAKER, 0, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_set_mixer_name(section, INTERNAL_SPEAKER);
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(1);
@@ -1148,8 +1167,8 @@ TEST(AlsaOutputNode, OutputsFromUCM) {
EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
// Add a second node (will use the same iodev).
- section = ucm_section_create(HEADPHONE, "hw:0,2", 0, -1, CRAS_STREAM_OUTPUT,
- jack_name, "hctl");
+ section =
+ ucm_section_create(HEADPHONE, 0, CRAS_STREAM_OUTPUT, jack_name, "hctl");
ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
cras_alsa_jack_list_add_jack_for_section_result_jack = NULL;
@@ -1167,16 +1186,12 @@ TEST(AlsaOutputNode, OutputsFromUCM) {
EXPECT_EQ(0, cras_iodev_set_node_plugged_called);
// Complete initialization, and make first node active.
- cras_alsa_support_8_channels = false; // Support 2 channels only.
alsa_iodev_ucm_complete_init(iodev);
EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
EXPECT_EQ(2, cras_alsa_jack_list_add_jack_for_section_called);
EXPECT_EQ(2, cras_alsa_mixer_get_control_for_section_called);
EXPECT_EQ(1, ucm_get_dma_period_for_dev_called);
EXPECT_EQ(ucm_get_dma_period_for_dev_ret, aio->dma_period_set_microsecs);
- /* Call cras_alsa_fill_properties once on update_max_supported_channels. */
- EXPECT_EQ(1, cras_alsa_fill_properties_called);
- EXPECT_EQ(2, iodev->info.max_supported_channels);
aio->handle = (snd_pcm_t*)0x24;
@@ -1197,14 +1212,10 @@ TEST(AlsaOutputNode, OutputsFromUCM) {
EXPECT_EQ(1, ucm_set_enabled_called);
// Simulate jack plug event.
- cras_alsa_support_8_channels = true; // Support up to 8 channels.
cras_alsa_jack_get_mixer_output_ret = outputs[1];
cras_alsa_jack_get_name_ret_value = jack_name;
jack_output_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
- /* Headphone plug event shouldn't trigger update_max_supported_channels. */
- EXPECT_EQ(0, cras_alsa_fill_properties_called);
- EXPECT_EQ(2, iodev->info.max_supported_channels);
alsa_iodev_destroy(iodev);
}
@@ -1226,8 +1237,8 @@ TEST(AlsaOutputNode, OutputNoControlsUCM) {
EXPECT_EQ(1, cras_card_config_get_volume_curve_for_control_called);
// Node without controls or jacks.
- section = ucm_section_create(INTERNAL_SPEAKER, "hw:0,1", 1, -1,
- CRAS_STREAM_OUTPUT, NULL, NULL);
+ section =
+ ucm_section_create(INTERNAL_SPEAKER, 1, CRAS_STREAM_OUTPUT, NULL, NULL);
// Device index doesn't match.
EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
section->dev_idx = 0;
@@ -1268,8 +1279,8 @@ TEST(AlsaOutputNode, OutputFromJackUCM) {
// Node without controls or jacks.
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(1);
- section = ucm_section_create(HEADPHONE, "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- jack_name, "hctl");
+ section =
+ ucm_section_create(HEADPHONE, 0, CRAS_STREAM_OUTPUT, jack_name, "hctl");
ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
EXPECT_EQ(4, cras_card_config_get_volume_curve_for_control_called);
EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
@@ -1297,7 +1308,6 @@ TEST(AlsaOutputNode, InputsFromUCM) {
static const char* jack_name = "TestCard - Headset Jack";
int rc;
struct ucm_section* section;
- long intrinsic_sensitivity = -2700;
ResetStubData();
inputs[0] = reinterpret_cast<struct mixer_control*>(3);
@@ -1316,8 +1326,9 @@ TEST(AlsaOutputNode, InputsFromUCM) {
// First node.
cras_alsa_mixer_get_control_for_section_return_value = inputs[0];
- section = ucm_section_create(INTERNAL_MICROPHONE, "hw:0,1", 0, -1,
- CRAS_STREAM_INPUT, NULL, NULL);
+ ucm_get_max_software_gain_ret_value = -1;
+ section =
+ ucm_section_create(INTERNAL_MICROPHONE, 0, CRAS_STREAM_INPUT, NULL, NULL);
ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
@@ -1325,18 +1336,17 @@ TEST(AlsaOutputNode, InputsFromUCM) {
// Add a second node (will use the same iodev).
cras_alsa_mixer_get_control_name_called = 0;
- // Set intrinsic sensitivity to enable software gain.
- ucm_get_intrinsic_sensitivity_values[MIC] = intrinsic_sensitivity;
+ ucm_get_max_software_gain_ret_value = 0;
+ ucm_get_max_software_gain_value = 2000;
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(1);
cras_alsa_mixer_get_control_for_section_return_value = inputs[1];
- section = ucm_section_create(MIC, "hw:0,2", 0, -1, CRAS_STREAM_INPUT,
- jack_name, "hctl");
+ section = ucm_section_create(MIC, 0, CRAS_STREAM_INPUT, jack_name, "hctl");
ucm_section_set_mixer_name(section, MIC);
ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
ucm_section_free_list(section);
- // Jack plug of an unknown device should do nothing.
+ // Jack plug of an unkonwn device should do nothing.
cras_alsa_jack_get_mixer_input_ret = NULL;
cras_alsa_jack_get_name_ret_value = "Some other jack";
jack_input_plug_event(reinterpret_cast<struct cras_alsa_jack*>(4), 0, aio);
@@ -1354,6 +1364,7 @@ TEST(AlsaOutputNode, InputsFromUCM) {
EXPECT_EQ(2, cras_alsa_jack_list_add_jack_for_section_called);
EXPECT_EQ(2, cras_alsa_mixer_get_control_for_section_called);
EXPECT_EQ(1, cras_alsa_mixer_get_control_name_called);
+ EXPECT_EQ(1, sys_set_capture_gain_limits_called);
EXPECT_EQ(2, cras_iodev_add_node_called);
EXPECT_EQ(2, ucm_get_dma_period_for_dev_called);
EXPECT_EQ(0, aio->dma_period_set_microsecs);
@@ -1369,9 +1380,10 @@ TEST(AlsaOutputNode, InputsFromUCM) {
EXPECT_EQ(1, cras_iodev_update_dsp_called);
EXPECT_EQ(1, cras_alsa_jack_enable_ucm_called);
EXPECT_EQ(1, ucm_set_enabled_called);
+ EXPECT_EQ(1, sys_set_capture_gain_limits_called);
EXPECT_EQ(1, alsa_mixer_set_capture_mute_called);
- ASSERT_EQ(DEFAULT_CAPTURE_VOLUME_DBFS - intrinsic_sensitivity,
- iodev->active_node->capture_gain);
+ EXPECT_EQ(1, iodev->active_node->software_volume_needed);
+ EXPECT_EQ(2000, iodev->active_node->max_software_gain);
alsa_iodev_destroy(iodev);
}
@@ -1392,8 +1404,8 @@ TEST(AlsaOutputNode, InputNoControlsUCM) {
aio = reinterpret_cast<struct alsa_io*>(iodev);
// Node without controls or jacks.
- section = ucm_section_create(INTERNAL_MICROPHONE, "hw:0,1", 1, -1,
- CRAS_STREAM_INPUT, NULL, NULL);
+ section =
+ ucm_section_create(INTERNAL_MICROPHONE, 1, CRAS_STREAM_INPUT, NULL, NULL);
// Device index doesn't match.
EXPECT_EQ(-22, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
section->dev_idx = 0;
@@ -1434,8 +1446,7 @@ TEST(AlsaOutputNode, InputFromJackUCM) {
// Node without controls or jacks.
cras_alsa_jack_list_add_jack_for_section_result_jack =
reinterpret_cast<struct cras_alsa_jack*>(1);
- section = ucm_section_create(MIC, "hw:0,1", 0, -1, CRAS_STREAM_INPUT,
- jack_name, "hctl");
+ section = ucm_section_create(MIC, 0, CRAS_STREAM_INPUT, jack_name, "hctl");
ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
EXPECT_EQ(1, cras_alsa_mixer_get_control_for_section_called);
EXPECT_EQ(1, cras_iodev_add_node_called);
@@ -1543,83 +1554,6 @@ TEST(AlsaOutputNode, AutoUnplugInputNode) {
alsa_iodev_destroy((struct cras_iodev*)aio);
}
-TEST(AlsaLoopback, InitializePlayback) {
- struct alsa_io* aio;
- struct cras_alsa_mixer* const fake_mixer = (struct cras_alsa_mixer*)2;
- struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
- struct cras_iodev* iodev;
- static const char* jack_name = "TestCard - Alsa Loopback";
- struct mixer_control* outputs[1];
- struct ucm_section* section;
-
- ResetStubData();
- outputs[0] = reinterpret_cast<struct mixer_control*>(3);
- cras_alsa_mixer_list_outputs_outputs = outputs;
- cras_alsa_mixer_list_outputs_outputs_length = ARRAY_SIZE(outputs);
- cras_alsa_mixer_get_control_name_values[outputs[0]] = LOOPBACK_PLAYBACK;
-
- // Create the IO device.
- iodev = alsa_iodev_create_with_default_parameters(
- 0, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
- CRAS_STREAM_OUTPUT);
- ASSERT_NE(iodev, (void*)NULL);
- aio = reinterpret_cast<struct alsa_io*>(iodev);
-
- // Add node.
- section = ucm_section_create(LOOPBACK_PLAYBACK, "hw:0,1", 0, -1,
- CRAS_STREAM_OUTPUT, jack_name, NULL);
- ucm_section_set_mixer_name(section, LOOPBACK_PLAYBACK);
- cras_alsa_jack_list_add_jack_for_section_result_jack = NULL;
- cras_alsa_mixer_get_control_for_section_return_value = outputs[0];
- ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
- ucm_section_free_list(section);
-
- // Complete initialization, and check the loopback playback node is plugged as
- // the active node.
- alsa_iodev_ucm_complete_init(iodev);
- EXPECT_EQ(SND_PCM_STREAM_PLAYBACK, aio->alsa_stream);
- ASSERT_NE(aio->base.active_node, (void*)NULL);
- EXPECT_STREQ(LOOPBACK_PLAYBACK, aio->base.active_node->name);
- EXPECT_EQ(1, aio->base.active_node->plugged);
-
- alsa_iodev_destroy(iodev);
-}
-
-TEST(AlsaLoopback, InitializeCapture) {
- struct alsa_io* aio;
- struct cras_use_case_mgr* const fake_ucm = (struct cras_use_case_mgr*)3;
- struct cras_iodev* iodev;
- static const char* jack_name = "TestCard - Alsa Loopback";
- struct ucm_section* section;
-
- ResetStubData();
-
- // Create the IO device.
- iodev = alsa_iodev_create_with_default_parameters(
- 1, NULL, ALSA_CARD_TYPE_INTERNAL, 1, fake_mixer, fake_config, fake_ucm,
- CRAS_STREAM_INPUT);
- ASSERT_NE(iodev, (void*)NULL);
- aio = reinterpret_cast<struct alsa_io*>(iodev);
-
- // Node without controls or jacks.
- cras_alsa_jack_list_add_jack_for_section_result_jack =
- reinterpret_cast<struct cras_alsa_jack*>(1);
- section = ucm_section_create(LOOPBACK_CAPTURE, "hw:0,1", 0, -1,
- CRAS_STREAM_INPUT, jack_name, NULL);
- ASSERT_EQ(0, alsa_iodev_ucm_add_nodes_and_jacks(iodev, section));
- ucm_section_free_list(section);
-
- // Complete initialization, and check the loopback capture node is plugged as
- // the active node.
- alsa_iodev_ucm_complete_init(iodev);
- EXPECT_EQ(SND_PCM_STREAM_CAPTURE, aio->alsa_stream);
- ASSERT_NE(aio->base.active_node, (void*)NULL);
- EXPECT_STREQ(LOOPBACK_CAPTURE, aio->base.active_node->name);
- EXPECT_EQ(1, aio->base.active_node->plugged);
-
- alsa_iodev_destroy(iodev);
-}
-
TEST(AlsaInitNode, SetNodeInitialState) {
struct cras_ionode node;
struct cras_iodev dev;
@@ -1933,6 +1867,11 @@ TEST_F(AlsaVolumeMuteSuite, GetVolumeCurveFromNode) {
.get_dBFS = fake_get_dBFS,
};
+ fmt = (struct cras_audio_format*)malloc(sizeof(*fmt));
+ memcpy(fmt, &fmt_, sizeof(fmt_));
+ aio_output_->base.format = fmt;
+ aio_output_->handle = (snd_pcm_t*)0x24;
+
// Headphone jack plugged and has its own volume curve.
cras_alsa_jack_get_mixer_output_ret = NULL;
cras_alsa_jack_get_name_ret_value = HEADPHONE;
@@ -1941,16 +1880,6 @@ TEST_F(AlsaVolumeMuteSuite, GetVolumeCurveFromNode) {
EXPECT_EQ(1, cras_alsa_jack_update_node_type_called);
EXPECT_EQ(3, cras_card_config_get_volume_curve_for_control_called);
- // These settings should be placed after plugging jacks to make it safer.
- // If is HDMI jack, plug event will trigger update_max_supported_channels()
- // and do open_dev() and close_dev() once. close_dev() will perform alsa_io
- // cleanup.
- // Headphone jack won't trigger, but we still place here due to coherence.
- fmt = (struct cras_audio_format*)malloc(sizeof(*fmt));
- memcpy(fmt, &fmt_, sizeof(fmt_));
- aio_output_->base.format = fmt;
- aio_output_->handle = (snd_pcm_t*)0x24;
-
// Switch to node 'Headphone'.
node = aio_output_->base.nodes->next;
aio_output_->base.active_node = node;
@@ -1975,6 +1904,7 @@ TEST_F(AlsaVolumeMuteSuite, SetVolume) {
aio_output_->base.format = fmt;
aio_output_->handle = (snd_pcm_t*)0x24;
+ aio_output_->num_underruns = 3; // Something non-zero.
sys_get_volume_return_value = fake_system_volume;
rc = aio_output_->base.configure_dev(&aio_output_->base);
ASSERT_EQ(0, rc);
@@ -2055,7 +1985,6 @@ class AlsaFreeRunTestSuite : public testing::Test {
fmt_.frame_rate = 48000;
fmt_.num_channels = 2;
aio.base.frames_queued = frames_queued;
- aio.base.output_underrun = alsa_output_underrun;
aio.base.direction = CRAS_STREAM_OUTPUT;
aio.base.format = &fmt_;
aio.base.buffer_size = BUFFER_SIZE;
@@ -2207,7 +2136,6 @@ TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunNotInFreeRunMoreRemain) {
EXPECT_EQ(0, cras_iodev_fill_odev_zeros_frames);
EXPECT_EQ(0, aio.free_running);
EXPECT_EQ(0, aio.filled_zeros_for_draining);
- EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
}
TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunNotInFreeRunLessRemain) {
@@ -2232,7 +2160,6 @@ TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunNotInFreeRunLessRemain) {
EXPECT_EQ(96, cras_iodev_fill_odev_zeros_frames);
EXPECT_EQ(0, aio.free_running);
EXPECT_EQ(0, aio.filled_zeros_for_draining);
- EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
}
TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunInFreeRun) {
@@ -2250,7 +2177,6 @@ TEST_F(AlsaFreeRunTestSuite, LeaveFreeRunInFreeRun) {
cras_alsa_resume_appl_ptr_ahead);
EXPECT_EQ(0, aio.free_running);
EXPECT_EQ(0, aio.filled_zeros_for_draining);
- EXPECT_EQ(1, cras_iodev_reset_rate_estimator_called);
}
// Reuse AlsaFreeRunTestSuite for output underrun handling because they are
@@ -2260,9 +2186,12 @@ TEST_F(AlsaFreeRunTestSuite, OutputUnderrun) {
int16_t* zeros;
snd_pcm_uframes_t offset;
+ aio.num_underruns = 0;
+
// Ask alsa_io to handle output underrun.
rc = alsa_output_underrun(&aio.base);
EXPECT_EQ(0, rc);
+ EXPECT_EQ(1, aio.num_underruns);
// mmap buffer should be filled with zeros.
zeros = (int16_t*)calloc(BUFFER_SIZE * 2, sizeof(*zeros));
@@ -2306,7 +2235,7 @@ TEST(AlsaHotwordNode, HotwordTriggeredSendMessage) {
ASSERT_EQ(0, rc);
ASSERT_NE(reinterpret_cast<thread_callback>(NULL), audio_thread_cb);
- audio_thread_cb(audio_thread_cb_data, POLLIN);
+ audio_thread_cb(audio_thread_cb_data);
EXPECT_EQ(1, hotword_send_triggered_msg_called);
alsa_iodev_destroy(iodev);
}
@@ -2442,21 +2371,9 @@ int cras_alsa_fill_properties(snd_pcm_t* handle,
(*rates)[0] = 44100;
(*rates)[1] = 48000;
(*rates)[2] = 0;
-
- if (cras_alsa_support_8_channels) { // Support up to 8 channels.
- *channel_counts = (size_t*)malloc(sizeof(**channel_counts) * 6);
- (*channel_counts)[0] = 6;
- (*channel_counts)[1] = 4;
- (*channel_counts)[2] = 2;
- (*channel_counts)[3] = 1;
- (*channel_counts)[4] = 8;
- (*channel_counts)[5] = 0;
- } else { // Support 2 channels only.
- *channel_counts = (size_t*)malloc(sizeof(**channel_counts) * 2);
- (*channel_counts)[0] = 2;
- (*channel_counts)[1] = 0;
- }
-
+ *channel_counts = (size_t*)malloc(sizeof(**channel_counts) * 2);
+ (*channel_counts)[0] = 2;
+ (*channel_counts)[1] = 0;
*formats = (snd_pcm_format_t*)malloc(sizeof(**formats) * 2);
(*formats)[0] = SND_PCM_FORMAT_S16_LE;
(*formats)[1] = (snd_pcm_format_t)0;
@@ -2471,7 +2388,7 @@ int cras_alsa_set_hwparams(snd_pcm_t* handle,
unsigned int dma_period_time) {
return 0;
}
-int cras_alsa_set_swparams(snd_pcm_t* handle) {
+int cras_alsa_set_swparams(snd_pcm_t* handle, int* enable_htimestamp) {
return 0;
}
int cras_alsa_get_avail_frames(snd_pcm_t* handle,
@@ -2545,6 +2462,11 @@ size_t cras_system_get_volume() {
return sys_get_volume_return_value;
}
+long cras_system_get_capture_gain() {
+ sys_get_capture_gain_called++;
+ return sys_get_capture_gain_return_value;
+}
+
int cras_system_get_mute() {
sys_get_mute_called++;
return sys_get_mute_return_value;
@@ -2559,8 +2481,10 @@ void cras_system_set_volume_limits(long min, long max) {
sys_set_volume_limits_called++;
}
-bool cras_system_get_noise_cancellation_enabled() {
- return false;
+void cras_system_set_capture_gain_limits(long min, long max) {
+ cras_system_set_capture_gain_limits_set_value[0] = min;
+ cras_system_set_capture_gain_limits_set_value[1] = max;
+ sys_set_capture_gain_limits_called++;
}
// From cras_alsa_mixer.
@@ -2711,6 +2635,15 @@ const char* cras_alsa_jack_get_name(const struct cras_alsa_jack* jack) {
return cras_alsa_jack_get_name_ret_value;
}
+const char* ucm_get_dsp_name_default(struct cras_use_case_mgr* mgr,
+ int direction) {
+ ucm_get_dsp_name_default_called++;
+ if (ucm_get_dsp_name_default_value)
+ return strdup(ucm_get_dsp_name_default_value);
+ else
+ return NULL;
+}
+
const char* ucm_get_dsp_name_for_dev(struct cras_use_case_mgr* mgr,
const char* dev) {
DspNameMap::iterator it;
@@ -2753,6 +2686,10 @@ char* ucm_get_flag(struct cras_use_case_mgr* mgr, const char* flag_name) {
return NULL;
}
+char* ucm_get_mic_positions(struct cras_use_case_mgr* mgr) {
+ return NULL;
+}
+
int ucm_swap_mode_exists(struct cras_use_case_mgr* mgr) {
return ucm_swap_mode_exists_ret_value;
}
@@ -2770,10 +2707,30 @@ int ucm_get_min_buffer_level(struct cras_use_case_mgr* mgr,
return 0;
}
+unsigned int ucm_get_enable_htimestamp_flag(struct cras_use_case_mgr* mgr) {
+ return ucm_get_enable_htimestamp_flag_ret;
+}
+
unsigned int ucm_get_disable_software_volume(struct cras_use_case_mgr* mgr) {
return 0;
}
+int ucm_get_min_software_gain(struct cras_use_case_mgr* mgr,
+ const char* dev,
+ long* gain) {
+ ucm_get_min_software_gain_called++;
+ *gain = ucm_get_min_software_gain_value;
+ return ucm_get_min_software_gain_ret_value;
+}
+
+int ucm_get_max_software_gain(struct cras_use_case_mgr* mgr,
+ const char* dev,
+ long* gain) {
+ ucm_get_max_software_gain_called++;
+ *gain = ucm_get_max_software_gain_value;
+ return ucm_get_max_software_gain_ret_value;
+}
+
char* ucm_get_hotword_models(struct cras_use_case_mgr* mgr) {
return NULL;
}
@@ -2804,24 +2761,6 @@ int ucm_get_preempt_hotword(struct cras_use_case_mgr* mgr, const char* dev) {
return 0;
}
-int ucm_get_channels_for_dev(struct cras_use_case_mgr* mgr,
- const char* dev,
- enum CRAS_STREAM_DIRECTION direction,
- size_t* channels) {
- return -EINVAL;
-}
-
-int ucm_node_noise_cancellation_exists(struct cras_use_case_mgr* mgr,
- const char* node_name) {
- return 0;
-}
-
-int ucm_enable_node_noise_cancellation(struct cras_use_case_mgr* mgr,
- const char* node_name,
- int enable) {
- return 0;
-}
-
struct cras_volume_curve* cras_volume_curve_create_default() {
return &default_curve;
}
@@ -2858,7 +2797,7 @@ void audio_thread_destroy(audio_thread* thread) {}
void cras_iodev_update_dsp(struct cras_iodev* iodev) {
cras_iodev_update_dsp_called++;
- cras_iodev_update_dsp_name = iodev->dsp_name ?: "";
+ cras_iodev_update_dsp_name = iodev->dsp_name;
}
void cras_iodev_set_node_plugged(struct cras_ionode* ionode, int plugged) {
@@ -2903,12 +2842,6 @@ const char* cras_alsa_jack_get_ucm_device(const struct cras_alsa_jack* jack) {
return NULL;
}
-void ucm_disable_all_hotword_models(struct cras_use_case_mgr* mgr) {}
-
-int ucm_enable_hotword_model(struct cras_use_case_mgr* mgr) {
- return 0;
-}
-
int ucm_get_default_node_gain(struct cras_use_case_mgr* mgr,
const char* dev,
long* gain) {
@@ -2920,23 +2853,11 @@ int ucm_get_default_node_gain(struct cras_use_case_mgr* mgr,
return 0;
}
-int ucm_get_intrinsic_sensitivity(struct cras_use_case_mgr* mgr,
- const char* dev,
- long* vol) {
- if (ucm_get_intrinsic_sensitivity_values.find(dev) ==
- ucm_get_intrinsic_sensitivity_values.end())
- return 1;
-
- *vol = ucm_get_intrinsic_sensitivity_values[dev];
- return 0;
-}
-
void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {}
void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
int cras_iodev_reset_rate_estimator(const struct cras_iodev* iodev) {
- cras_iodev_reset_rate_estimator_called++;
return 0;
}
@@ -2960,10 +2881,7 @@ void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
const struct cras_audio_format* fmt,
uint8_t* base_buffer) {}
-void audio_thread_add_events_callback(int fd,
- thread_callback cb,
- void* data,
- int events) {
+void audio_thread_add_callback(int fd, thread_callback cb, void* data) {
audio_thread_cb = cb;
audio_thread_cb_data = data;
}
@@ -3014,12 +2932,6 @@ int cras_iodev_default_no_stream_playback(struct cras_iodev* odev, int enable) {
return 0;
}
-int cras_iodev_output_underrun(struct cras_iodev* odev,
- unsigned int hw_level,
- unsigned int frames_written) {
- return odev->output_underrun(odev);
-}
-
enum CRAS_IODEV_STATE cras_iodev_state(const struct cras_iodev* iodev) {
return iodev->state;
}
diff --git a/cras/src/tests/alsa_jack_unittest.cc b/cras/src/tests/alsa_jack_unittest.cc
index 1aa95491..24b43a31 100644
--- a/cras/src/tests/alsa_jack_unittest.cc
+++ b/cras/src/tests/alsa_jack_unittest.cc
@@ -86,7 +86,7 @@ static unsigned long eviocbit_ret[NBITS(SW_CNT)];
static int gpio_switch_eviocgbit_fd;
static const char* edid_file_ret;
static unsigned ucm_get_override_type_name_called;
-static int ucm_get_alsa_dev_idx_for_dev_value;
+static char* ucm_get_device_name_for_dev_value;
static snd_hctl_t* fake_hctl = (snd_hctl_t*)2;
static void ResetStubData() {
@@ -137,7 +137,7 @@ static void ResetStubData() {
ucm_get_dev_for_jack_return = false;
edid_file_ret = NULL;
ucm_get_override_type_name_called = 0;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
memset(eviocbit_ret, 0, sizeof(eviocbit_ret));
}
@@ -216,15 +216,14 @@ static struct cras_alsa_jack_list* run_test_with_elem_list(
EXPECT_EQ(0, cras_alsa_jack_list_find_jacks_by_name_matching(jack_list));
EXPECT_EQ(ucm ? njacks : 0, ucm_get_dev_for_jack_called);
EXPECT_EQ(ucm ? njacks : 0, ucm_get_override_type_name_called);
- EXPECT_EQ(1, snd_hctl_first_elem_called);
+ EXPECT_EQ(1 + nhdmi_jacks, snd_hctl_first_elem_called);
EXPECT_EQ(njacks, snd_hctl_elem_set_callback_called);
- EXPECT_EQ(nhdmi_jacks, snd_hctl_find_elem_called);
/* For some functions, the number of calls to them could
* be larger then expected count if there is ELD control
* in given elements. */
- EXPECT_GE(snd_hctl_elem_next_called, nelems);
- EXPECT_GE(snd_hctl_elem_get_name_called, nelems);
+ EXPECT_GE(snd_hctl_elem_next_called, nelems + nhdmi_jacks);
+ EXPECT_GE(snd_hctl_elem_get_name_called, nelems + njacks);
if (direction == CRAS_STREAM_OUTPUT) {
EXPECT_EQ(njacks, cras_alsa_mixer_get_output_matching_name_called);
@@ -418,7 +417,7 @@ TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMMatched) {
/* PlaybackPCM matched, so create jack even if this is not the first device.*/
ucm_get_dev_for_jack_return = true;
- ucm_get_alsa_dev_idx_for_dev_value = 1;
+ ucm_get_device_name_for_dev_value = strdup("hw:c1,1");
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -434,7 +433,7 @@ TEST(AlsaJacks, CreateGPIOHpUCMCapturePCMMatched) {
/* CapturePCM matched, so create jack even if this is not the first device.*/
ucm_get_dev_for_jack_return = true;
- ucm_get_alsa_dev_idx_for_dev_value = 1;
+ ucm_get_device_name_for_dev_value = strdup("hw:c1,1");
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Mic Jack");
@@ -450,7 +449,7 @@ TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotMatched) {
/* PlaybackPCM not matched, do not create jack. */
ucm_get_dev_for_jack_return = true;
- ucm_get_alsa_dev_idx_for_dev_value = 2;
+ ucm_get_device_name_for_dev_value = strdup("hw:c1,2");
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -466,7 +465,7 @@ TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedFirstDevice) {
/* PlaybackPCM not specified, create jack for the first device. */
ucm_get_dev_for_jack_return = true;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -482,7 +481,7 @@ TEST(AlsaJacks, CreateGPIOHpUCMPlaybackPCMNotSpecifiedSecondDevice) {
/* PlaybackPCM not specified, do not create jack for the second device. */
ucm_get_dev_for_jack_return = true;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -498,7 +497,7 @@ TEST(AlsaJacks, CreateGPIOHpNoUCMFirstDevice) {
/* No UCM for this jack, create jack for the first device. */
ucm_get_dev_for_jack_return = false;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -514,7 +513,7 @@ TEST(AlsaJacks, CreateGPIOHpNoUCMSecondDevice) {
/* No UCM for this jack, dot not create jack for the second device. */
ucm_get_dev_for_jack_return = false;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
run_gpio_jack_test(device_index, is_first_device, direction,
should_create_jack, "c1 Headset Jack");
@@ -530,7 +529,7 @@ TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceMicJack) {
// No UCM for this jack, create jack for the first device.
ucm_get_dev_for_jack_return = false;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
// Mic Jack is a valid name for microphone jack.
run_gpio_jack_test(device_index, is_first_device, direction,
@@ -547,7 +546,7 @@ TEST(AlsaJacks, CreateGPIOMicNoUCMFirstDeviceHeadsetJack) {
// No UCM for this jack, create jack for the first device.
ucm_get_dev_for_jack_return = false;
- ucm_get_alsa_dev_idx_for_dev_value = -1;
+ ucm_get_device_name_for_dev_value = NULL;
// Headset Jack is a valid name for microphone jack.
run_gpio_jack_test(device_index, is_first_device, direction,
@@ -679,7 +678,7 @@ TEST(AlsaJacks, CreateHDMIJacksWithELD) {
ASSERT_NE(static_cast<struct cras_alsa_jack_list*>(NULL), jack_list);
/* Assert get device is called for the ELD control */
- EXPECT_EQ(1, snd_hctl_find_elem_called);
+ EXPECT_EQ(1, snd_hctl_elem_get_device_called);
cras_alsa_jack_list_destroy(jack_list);
}
@@ -729,7 +728,7 @@ TEST(AlsaJacks, CreateHCTLHeadphoneJackFromUCM) {
struct cras_alsa_jack_list* jack_list;
struct ucm_section* section;
- section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
"Headphone Jack", "hctl");
ResetStubData();
@@ -765,7 +764,7 @@ TEST(AlsaJacks, CreateGPIOHeadphoneJackFromUCM) {
struct cras_alsa_jack* jack;
struct ucm_section* section;
- section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
"c1 Headphone Jack", "gpio");
ResetStubData();
@@ -807,7 +806,7 @@ TEST(AlsaJacks, BadJackTypeFromUCM) {
struct cras_alsa_jack_list* jack_list;
struct ucm_section* section;
- section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
"Headphone Jack", "badtype");
ResetStubData();
@@ -829,7 +828,7 @@ TEST(AlsaJacks, NoJackTypeFromUCM) {
struct cras_alsa_jack_list* jack_list;
struct ucm_section* section;
- section = ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
"Headphone Jack", NULL);
ResetStubData();
@@ -1054,10 +1053,10 @@ const char* ucm_get_override_type_name(struct cras_use_case_mgr* mgr,
return NULL;
}
-int ucm_get_alsa_dev_idx_for_dev(struct cras_use_case_mgr* mgr,
- const char* dev,
- enum CRAS_STREAM_DIRECTION direction) {
- return ucm_get_alsa_dev_idx_for_dev_value;
+const char* ucm_get_device_name_for_dev(struct cras_use_case_mgr* mgr,
+ const char* dev,
+ enum CRAS_STREAM_DIRECTION direction) {
+ return ucm_get_device_name_for_dev_value;
}
cras_timer* cras_tm_create_timer(cras_tm* tm,
diff --git a/cras/src/tests/alsa_mixer_unittest.cc b/cras/src/tests/alsa_mixer_unittest.cc
index b3db9de5..d61ba3df 100644
--- a/cras/src/tests/alsa_mixer_unittest.cc
+++ b/cras/src/tests/alsa_mixer_unittest.cc
@@ -381,7 +381,7 @@ TEST(AlsaMixer, CreateOneUnknownElementWithVolume) {
mixer_control_destroy(mixer_output);
}
-TEST(AlsaMixer, CreateOneMainElement) {
+TEST(AlsaMixer, CreateOneMasterElement) {
struct cras_alsa_mixer* c;
int element_playback_volume[] = {
1,
@@ -419,10 +419,10 @@ TEST(AlsaMixer, CreateOneMainElement) {
EXPECT_EQ(3, snd_mixer_selem_get_name_called);
EXPECT_EQ(1, snd_mixer_elem_next_called);
- /* set mute should be called for Main. */
+ /* set mute should be called for Master. */
cras_alsa_mixer_set_mute(c, 0, NULL);
EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
- /* set volume should be called for Main. */
+ /* set volume should be called for Master. */
cras_alsa_mixer_set_dBFS(c, 0, NULL);
EXPECT_EQ(1, snd_mixer_selem_set_playback_dB_all_called);
@@ -515,15 +515,15 @@ TEST(AlsaMixer, CreateTwoMainVolumeElements) {
EXPECT_EQ(5, snd_mixer_selem_get_name_called);
EXPECT_EQ(3, snd_mixer_selem_has_playback_switch_called);
- /* Set mute should be called for Main only. */
+ /* Set mute should be called for Master only. */
cras_alsa_mixer_set_mute(c, 0, NULL);
EXPECT_EQ(1, snd_mixer_selem_set_playback_switch_all_called);
- /* Set volume should be called for Main and PCM. If Main doesn't set to
+ /* Set volume should be called for Master and PCM. If Master doesn't set to
* anything but zero then the entire volume should be passed to the PCM
* control.*/
- /* Set volume should be called for Main and PCM. (without mixer_output) */
+ /* Set volume should be called for Master and PCM. (without mixer_output) */
snd_mixer_selem_get_playback_dB_return_values = get_dB_returns;
snd_mixer_selem_get_playback_dB_return_values_length =
ARRAY_SIZE(get_dB_returns);
@@ -557,8 +557,8 @@ TEST(AlsaMixer, CreateTwoMainVolumeElements) {
EXPECT_EQ(1, snd_mixer_selem_has_playback_switch_called);
EXPECT_EQ(1, snd_mixer_selem_get_playback_dB_range_called);
- /* Set volume should be called for Main, PCM, and the mixer_output passed
- * in. If Main doesn't set to anything but zero then the entire volume
+ /* Set volume should be called for Master, PCM, and the mixer_output passed
+ * in. If Master doesn't set to anything but zero then the entire volume
* should be passed to the PCM control.*/
cras_alsa_mixer_set_dBFS(c, -50, mixer_output);
EXPECT_EQ(3, snd_mixer_selem_set_playback_dB_all_called);
@@ -566,8 +566,8 @@ TEST(AlsaMixer, CreateTwoMainVolumeElements) {
EXPECT_EQ(30, set_dB_values[0]);
EXPECT_EQ(30, set_dB_values[1]);
EXPECT_EQ(30, set_dB_values[2]);
- /* Set volume should be called for Main and PCM. Since the controls were
- * sorted, Main should get the volume remaining after PCM is set, in this
+ /* Set volume should be called for Master and PCM. Since the controls were
+ * sorted, Master should get the volume remaining after PCM is set, in this
* case -50 - -24 = -26. */
long get_dB_returns2[] = {
-25,
@@ -584,7 +584,7 @@ TEST(AlsaMixer, CreateTwoMainVolumeElements) {
cras_alsa_mixer_set_dBFS(c, -50, mixer_output);
EXPECT_EQ(2, snd_mixer_selem_set_playback_dB_all_called);
EXPECT_EQ(2, snd_mixer_selem_get_playback_dB_called);
- EXPECT_EQ(54, set_dB_values[0]); // Main
+ EXPECT_EQ(54, set_dB_values[0]); // Master
EXPECT_EQ(30, set_dB_values[1]); // PCM
cras_alsa_mixer_destroy(c);
@@ -639,7 +639,7 @@ TEST(AlsaMixer, CreateTwoMainCaptureElements) {
EXPECT_EQ(5, snd_mixer_selem_get_name_called);
EXPECT_EQ(3, snd_mixer_selem_has_capture_switch_called);
- /* Set mute should be called for Main only. */
+ /* Set mute should be called for Master only. */
cras_alsa_mixer_set_capture_mute(c, 0, NULL);
EXPECT_EQ(1, snd_mixer_selem_set_capture_switch_all_called);
/* Set volume should be called for Capture and Digital Capture. If Capture
@@ -773,7 +773,7 @@ class AlsaMixerOutputs : public testing::Test {
ResetStubData();
snd_mixer_first_elem_return_value =
- reinterpret_cast<snd_mixer_elem_t*>(1); // Main
+ reinterpret_cast<snd_mixer_elem_t*>(1); // Master
snd_mixer_elem_next_return_values = elements;
snd_mixer_elem_next_return_values_length = ARRAY_SIZE(elements);
snd_mixer_selem_has_playback_volume_return_values = element_playback_volume;
@@ -1275,32 +1275,29 @@ class AlsaMixerFullySpeced : public testing::Test {
for (i = 0; i < ARRAY_SIZE(elements); i++)
snd_mixer_find_elem_map[element_names[i]] = elements[i];
- section = ucm_section_create("NullElement", "hw:0,1", 0, -1,
- CRAS_STREAM_OUTPUT, NULL, NULL);
+ section =
+ ucm_section_create("NullElement", 0, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_set_mixer_name(section, "Unknown");
DL_APPEND(sections, section);
- section =
- ucm_section_create("Headphone", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- "my-sound-card Headset Jack", "gpio");
+ section = ucm_section_create("Headphone", 0, CRAS_STREAM_OUTPUT,
+ "my-sound-card Headset Jack", "gpio");
ucm_section_add_coupled(section, "HP-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "HP-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("Speaker", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- NULL, NULL);
+ section = ucm_section_create("Speaker", 0, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_add_coupled(section, "SPK-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "SPK-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("Mic", "hw:0,1", 0, -1, CRAS_STREAM_INPUT,
+ section = ucm_section_create("Mic", 0, CRAS_STREAM_INPUT,
"my-sound-card Headset Jack", "gpio");
ucm_section_set_mixer_name(section, "CAPTURE");
DL_APPEND(sections, section);
- section = ucm_section_create("Internal Mic", "hw:0,1", 0, -1,
- CRAS_STREAM_INPUT, NULL, NULL);
+ section =
+ ucm_section_create("Internal Mic", 0, CRAS_STREAM_INPUT, NULL, NULL);
ucm_section_add_coupled(section, "MIC-L", MIXER_NAME_VOLUME);
ucm_section_add_coupled(section, "MIC-R", MIXER_NAME_VOLUME);
DL_APPEND(sections, section);
- section = ucm_section_create("HDMI", "hw:0,1", 0, -1, CRAS_STREAM_OUTPUT,
- NULL, NULL);
+ section = ucm_section_create("HDMI", 0, CRAS_STREAM_OUTPUT, NULL, NULL);
ucm_section_set_mixer_name(section, "HDMI");
DL_APPEND(sections, section);
ASSERT_NE(sections, (struct ucm_section*)NULL);
diff --git a/cras/src/tests/alsa_ucm_unittest.cc b/cras/src/tests/alsa_ucm_unittest.cc
index 1b351ddf..0773079e 100644
--- a/cras/src/tests/alsa_ucm_unittest.cc
+++ b/cras/src/tests/alsa_ucm_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <gtest/gtest.h>
+#include <iniparser.h>
#include <stdio.h>
#include <syslog.h>
@@ -28,13 +29,11 @@ static unsigned snd_use_case_get_called;
static std::vector<std::string> snd_use_case_get_id;
static int snd_use_case_set_return;
static std::map<std::string, std::string> snd_use_case_get_value;
-static std::map<std::string, unsigned> snd_use_case_geti_value;
static unsigned snd_use_case_set_called;
static std::vector<std::pair<std::string, std::string> > snd_use_case_set_param;
static std::map<std::string, const char**> fake_list;
static std::map<std::string, unsigned> fake_list_size;
static unsigned snd_use_case_free_list_called;
-static unsigned snd_use_case_geti_called;
static std::vector<std::string> list_devices_callback_names;
static std::vector<void*> list_devices_callback_args;
static struct cras_use_case_mgr cras_ucm_mgr;
@@ -47,12 +46,10 @@ static void ResetStubData() {
snd_use_case_set_return = 0;
snd_use_case_get_called = 0;
snd_use_case_set_called = 0;
- snd_use_case_geti_called = 0;
snd_use_case_set_param.clear();
snd_use_case_free_list_called = 0;
snd_use_case_get_id.clear();
snd_use_case_get_value.clear();
- snd_use_case_geti_value.clear();
fake_list.clear();
fake_list_size.clear();
fake_list["_verbs"] = avail_verbs;
@@ -61,7 +58,6 @@ static void ResetStubData() {
list_devices_callback_args.clear();
snd_use_case_mgr_open_mgr_ptr = reinterpret_cast<snd_use_case_mgr_t*>(0x55);
cras_ucm_mgr.use_case = CRAS_STREAM_TYPE_DEFAULT;
- cras_ucm_mgr.hotword_modifier = NULL;
}
static void list_devices_callback(const char* section_name, void* arg) {
@@ -273,8 +269,8 @@ TEST(AlsaUcm, GetDevForJack) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=JackDev/Dev1/HiFi";
- std::string id_2 = "=JackDev/Dev2/HiFi";
+ std::string id_1 = "=JackName/Dev1/HiFi";
+ std::string id_2 = "=JackName/Dev2/HiFi";
std::string value_1 = "Value1";
std::string value_2 = "Value2";
@@ -300,8 +296,8 @@ TEST(AlsaUcm, GetDevForHeadphoneJack) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=JackDev/Mic/HiFi";
- std::string id_2 = "=JackDev/Headphone/HiFi";
+ std::string id_1 = "=JackName/Mic/HiFi";
+ std::string id_2 = "=JackName/Headphone/HiFi";
std::string value = "JackValue";
snd_use_case_get_value[id_1] = value;
@@ -326,8 +322,8 @@ TEST(AlsaUcm, GetDevForMicJack) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=JackDev/Headphone/HiFi";
- std::string id_2 = "=JackDev/Mic/HiFi";
+ std::string id_1 = "=JackName/Headphone/HiFi";
+ std::string id_2 = "=JackName/Mic/HiFi";
std::string value = "JackValue";
snd_use_case_get_value[id_1] = value;
@@ -352,8 +348,8 @@ TEST(AlsaUcm, GetDevForMixer) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=PlaybackMixerElem/Dev1/HiFi";
- std::string id_2 = "=CaptureMixerElem/Dev2/HiFi";
+ std::string id_1 = "=MixerName/Dev1/HiFi";
+ std::string id_2 = "=MixerName/Dev2/HiFi";
std::string value_1 = "Value1";
std::string value_2 = "Value2";
@@ -372,8 +368,9 @@ TEST(AlsaUcm, GetDevForMixer) {
free((void*)dev_name_in);
}
-TEST(AlsaUcm, GetAlsaDeviceIndexForDevice) {
+TEST(AlsaUcm, GetDeviceNameForDevice) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
+ const char *input_dev_name, *output_dev_name;
const char* devices[] = {"Dev1", "Comment for Dev1", "Dev2",
"Comment for Dev2"};
@@ -383,17 +380,24 @@ TEST(AlsaUcm, GetAlsaDeviceIndexForDevice) {
fake_list_size["_devices/HiFi"] = 4;
std::string id_1 = "=CapturePCM/Dev1/HiFi";
std::string id_2 = "=PlaybackPCM/Dev2/HiFi";
- std::string value_1 = "PCMName,1";
- std::string value_2 = "PCMName,2";
+ std::string value_1 = "DeviceName1";
+ std::string value_2 = "DeviceName2";
snd_use_case_get_value[id_1] = value_1;
snd_use_case_get_value[id_2] = value_2;
- EXPECT_EQ(1, ucm_get_alsa_dev_idx_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT));
- EXPECT_EQ(2, ucm_get_alsa_dev_idx_for_dev(mgr, "Dev2", CRAS_STREAM_OUTPUT));
+ input_dev_name = ucm_get_device_name_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT);
+ output_dev_name =
+ ucm_get_device_name_for_dev(mgr, "Dev2", CRAS_STREAM_OUTPUT);
+ ASSERT_TRUE(input_dev_name);
+ ASSERT_TRUE(output_dev_name);
+ EXPECT_EQ(0, strcmp(input_dev_name, value_1.c_str()));
+ EXPECT_EQ(0, strcmp(output_dev_name, value_2.c_str()));
ASSERT_EQ(2, snd_use_case_get_called);
EXPECT_EQ(snd_use_case_get_id[0], id_1);
EXPECT_EQ(snd_use_case_get_id[1], id_2);
+ free((void*)input_dev_name);
+ free((void*)output_dev_name);
}
TEST(AlsaUcm, GetDeviceRateForDevice) {
@@ -424,38 +428,6 @@ TEST(AlsaUcm, GetDeviceRateForDevice) {
EXPECT_EQ(snd_use_case_get_id[1], id_2);
}
-TEST(AlsaUcm, GetDeviceChannelsForDevice) {
- struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- int rc;
- size_t input_dev_channels, output_dev_channels;
- const char* devices[] = {"Dev1", "Comment for Dev1", "Dev2",
- "Comment for Dev2"};
-
- ResetStubData();
-
- fake_list["_devices/HiFi"] = devices;
- fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=CaptureChannels/Dev1/HiFi";
- std::string id_2 = "=PlaybackChannels/Dev2/HiFi";
- std::string value_1 = "4";
- std::string value_2 = "8";
-
- snd_use_case_get_value[id_1] = value_1;
- snd_use_case_get_value[id_2] = value_2;
- rc = ucm_get_channels_for_dev(mgr, "Dev1", CRAS_STREAM_INPUT,
- &input_dev_channels);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(4, input_dev_channels);
- rc = ucm_get_channels_for_dev(mgr, "Dev2", CRAS_STREAM_OUTPUT,
- &output_dev_channels);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(8, output_dev_channels);
-
- ASSERT_EQ(2, snd_use_case_get_called);
- EXPECT_EQ(snd_use_case_get_id[0], id_1);
- EXPECT_EQ(snd_use_case_get_id[1], id_2);
-}
-
TEST(AlsaUcm, GetCaptureChannelMapForDevice) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
int8_t channel_layout[CRAS_CH_MAX];
@@ -527,85 +499,26 @@ TEST(AlsaUcm, SetHotwordModel) {
const char* modifiers[] = {"Hotword Model en", "Comment1",
"Hotword Model jp", "Comment2",
"Hotword Model de", "Comment3"};
- const char* enabled_mods[] = {"Hotword Model jp"};
- int ret;
- std::string id = "_modstatus/Hotword Model jp";
+ const char* enabled_mods[] = {"Hotword Model en"};
ResetStubData();
- snd_use_case_geti_value[id] = 1;
fake_list["_modifiers/HiFi"] = modifiers;
fake_list_size["_modifiers/HiFi"] = 6;
EXPECT_EQ(-EINVAL, ucm_set_hotword_model(mgr, "zh"));
EXPECT_EQ(0, snd_use_case_set_called);
- ret = ucm_set_hotword_model(mgr, "jp");
-
- EXPECT_EQ(0, ret);
- EXPECT_EQ(0, snd_use_case_set_called);
- EXPECT_EQ(0, strcmp(mgr->hotword_modifier, "Hotword Model jp"));
-
fake_list["_enamods"] = enabled_mods;
fake_list_size["_enamods"] = 1;
- ret = ucm_set_hotword_model(mgr, "de");
- EXPECT_EQ(0, ret);
- EXPECT_EQ(2, snd_use_case_set_called);
- EXPECT_EQ(1, snd_use_case_geti_called);
- EXPECT_EQ(
- snd_use_case_set_param[0],
- std::make_pair(std::string("_dismod"), std::string("Hotword Model jp")));
- EXPECT_EQ(
- snd_use_case_set_param[1],
- std::make_pair(std::string("_enamod"), std::string("Hotword Model de")));
- free(mgr->hotword_modifier);
-}
-
-TEST(AlsaUcm, DisableAllHotwordModels) {
- struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- const char* modifiers[] = {"Hotword Model en", "Comment1",
- "Hotword Model jp", "Comment2",
- "Hotword Model de", "Comment3"};
- const char* enabled_mods[] = {"Hotword Model en"};
- ResetStubData();
-
- fake_list["_modifiers/HiFi"] = modifiers;
- fake_list_size["_modifiers/HiFi"] = 6;
- fake_list["_enamods"] = enabled_mods;
- fake_list_size["_enamods"] = 1;
-
- ucm_disable_all_hotword_models(mgr);
+ ucm_set_hotword_model(mgr, "jp");
- EXPECT_EQ(1, snd_use_case_set_called);
+ EXPECT_EQ(2, snd_use_case_set_called);
EXPECT_EQ(
snd_use_case_set_param[0],
std::make_pair(std::string("_dismod"), std::string("Hotword Model en")));
-}
-
-TEST(AlsaUcm, EnableHotwordModel) {
- struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- const char* modifiers[] = {"Hotword Model en", "Comment1",
- "Hotword Model jp", "Comment2",
- "Hotword Model de", "Comment3"};
- const char* enabled_mods[] = {""};
- int ret;
- ResetStubData();
-
- fake_list["_modifiers/HiFi"] = modifiers;
- fake_list_size["_modifiers/HiFi"] = 6;
- fake_list["_enamods"] = enabled_mods;
- fake_list_size["_enamods"] = 0;
-
- EXPECT_EQ(-EINVAL, ucm_enable_hotword_model(mgr));
-
- mgr->hotword_modifier = strdup("Hotword Model de");
- ret = ucm_enable_hotword_model(mgr);
-
- EXPECT_EQ(0, ret);
- EXPECT_EQ(1, snd_use_case_set_called);
EXPECT_EQ(
- snd_use_case_set_param[0],
- std::make_pair(std::string("_enamod"), std::string("Hotword Model de")));
- free(mgr->hotword_modifier);
+ snd_use_case_set_param[1],
+ std::make_pair(std::string("_enamod"), std::string("Hotword Model jp")));
}
TEST(AlsaUcm, SwapModeExists) {
@@ -693,76 +606,6 @@ TEST(AlsaUcm, DisableSwapMode) {
EXPECT_EQ(1, snd_use_case_set_called);
}
-TEST(AlsaUcm, NoiseCancellationExists) {
- struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- int rc;
- const char* node = "Internal Mic";
- const char* modifiers_1[] = {"Internal Mic Noise Cancellation", "Comment"};
- const char* modifiers_2[] = {"Internal Mic Noise Augmentation", "Comment"};
- const char* modifiers_3[] = {"Microphone Noise Cancellation", "Comment"};
-
- ResetStubData();
-
- fake_list["_modifiers/HiFi"] = modifiers_1;
- fake_list_size["_modifiers/HiFi"] = 2;
- rc = ucm_node_noise_cancellation_exists(mgr, node);
- EXPECT_EQ(1, rc);
-
- fake_list["_modifiers/HiFi"] = modifiers_2;
- fake_list_size["_modifiers/HiFi"] = 2;
- rc = ucm_node_noise_cancellation_exists(mgr, node);
- EXPECT_EQ(0, rc);
-
- fake_list["_modifiers/HiFi"] = modifiers_3;
- fake_list_size["_modifiers/HiFi"] = 2;
- rc = ucm_node_noise_cancellation_exists(mgr, node);
- EXPECT_EQ(0, rc);
-}
-
-TEST(AlsaUcm, EnableDisableNoiseCancellation) {
- struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- int rc;
- const char* modifiers[] = {"Internal Mic Noise Cancellation", "Comment1",
- "Microphone Noise Cancellation", "Comment2"};
- const char* modifiers_enabled[] = {"Internal Mic Noise Cancellation"};
-
- ResetStubData();
-
- fake_list["_modifiers/HiFi"] = modifiers;
- fake_list_size["_modifiers/HiFi"] = 4;
-
- fake_list["_enamods"] = modifiers_enabled;
- fake_list_size["_enamods"] = 1;
-
- snd_use_case_set_return = 0;
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Line In", 1);
- EXPECT_EQ(-EPERM, rc); // Modifier is not existed
- EXPECT_EQ(0, snd_use_case_set_called);
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Line In", 0);
- EXPECT_EQ(-EPERM, rc); // Modifier is not existed
- EXPECT_EQ(0, snd_use_case_set_called);
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Microphone", 0);
- EXPECT_EQ(0, rc); // Modifier is already disabled
- EXPECT_EQ(0, snd_use_case_set_called);
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Microphone", 1);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(1, snd_use_case_set_called);
-
- snd_use_case_set_called = 0;
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Internal Mic", 1);
- EXPECT_EQ(0, rc); // Modifier is already enabled
- EXPECT_EQ(0, snd_use_case_set_called);
-
- rc = ucm_enable_node_noise_cancellation(mgr, "Internal Mic", 0);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(1, snd_use_case_set_called);
-}
-
TEST(AlsaFlag, GetFlag) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
char* flag_value;
@@ -924,36 +767,61 @@ TEST(AlsaUcm, FreeMixerNames) {
mixer_name_free(mixer_names_1);
}
-TEST(AlsaUcm, DefaultNodeGain) {
+TEST(AlsaUcm, MaxSoftwareGain) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- long default_node_gain;
+ long max_software_gain;
int ret;
- std::string id = "=DefaultNodeGain/Internal Mic/HiFi";
- std::string value = "-2000";
+ std::string id = "=MaxSoftwareGain/Internal Mic/HiFi";
+ std::string value = "2000";
ResetStubData();
/* Value can be found in UCM. */
snd_use_case_get_value[id] = value;
- ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
+ ret = ucm_get_max_software_gain(mgr, "Internal Mic", &max_software_gain);
EXPECT_EQ(0, ret);
- EXPECT_EQ(-2000, default_node_gain);
+ EXPECT_EQ(2000, max_software_gain);
ResetStubData();
/* Value can not be found in UCM. */
- ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
+ ret = ucm_get_max_software_gain(mgr, "Internal Mic", &max_software_gain);
+
+ ASSERT_TRUE(ret);
+}
+
+TEST(AlsaUcm, MinSoftwareGain) {
+ struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
+ long min_software_gain;
+ int ret;
+ std::string id = "=MinSoftwareGain/Internal Mic/HiFi";
+ std::string value = "2000";
+
+ ResetStubData();
+
+ /* Value can be found in UCM. */
+ snd_use_case_get_value[id] = value;
+
+ ret = ucm_get_min_software_gain(mgr, "Internal Mic", &min_software_gain);
+
+ EXPECT_EQ(0, ret);
+ EXPECT_EQ(2000, min_software_gain);
+
+ ResetStubData();
+
+ /* Value can not be found in UCM. */
+ ret = ucm_get_min_software_gain(mgr, "Internal Mic", &min_software_gain);
ASSERT_TRUE(ret);
}
-TEST(AlsaUcm, IntrinsicSensitivity) {
+TEST(AlsaUcm, DefaultNodeGain) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- long intrinsic_vol;
+ long default_node_gain;
int ret;
- std::string id = "=IntrinsicSensitivity/Internal Mic/HiFi";
+ std::string id = "=DefaultNodeGain/Internal Mic/HiFi";
std::string value = "-2000";
ResetStubData();
@@ -961,15 +829,15 @@ TEST(AlsaUcm, IntrinsicSensitivity) {
/* Value can be found in UCM. */
snd_use_case_get_value[id] = value;
- ret = ucm_get_intrinsic_sensitivity(mgr, "Internal Mic", &intrinsic_vol);
+ ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
EXPECT_EQ(0, ret);
- EXPECT_EQ(-2000, intrinsic_vol);
+ EXPECT_EQ(-2000, default_node_gain);
ResetStubData();
/* Value can not be found in UCM. */
- ret = ucm_get_intrinsic_sensitivity(mgr, "Internal Mic", &intrinsic_vol);
+ ret = ucm_get_default_node_gain(mgr, "Internal Mic", &default_node_gain);
ASSERT_TRUE(ret);
}
@@ -996,6 +864,28 @@ TEST(AlsaUcm, UseFullySpecifiedUCMConfig) {
ASSERT_FALSE(fully_specified_flag);
}
+TEST(AlsaUcm, EnableHtimestampFlag) {
+ struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
+ unsigned int enable_htimestamp_flag;
+
+ std::string id = "=EnableHtimestamp//HiFi";
+ ResetStubData();
+
+ /* Flag is not set */
+ enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
+ ASSERT_FALSE(enable_htimestamp_flag);
+
+ /* Flag is set to "1". */
+ snd_use_case_get_value[id] = std::string("1");
+ enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
+ ASSERT_TRUE(enable_htimestamp_flag);
+
+ /* Flag is set to "0". */
+ snd_use_case_get_value[id] = std::string("0");
+ enable_htimestamp_flag = ucm_get_enable_htimestamp_flag(mgr);
+ ASSERT_FALSE(enable_htimestamp_flag);
+}
+
TEST(AlsaUcm, GetMixerNameForDevice) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
const char *mixer_name_1, *mixer_name_2;
@@ -1006,15 +896,15 @@ TEST(AlsaUcm, GetMixerNameForDevice) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=PlaybackMixerElem/Dev1/HiFi";
- std::string id_2 = "=CaptureMixerElem/Dev2/HiFi";
+ std::string id_1 = "=MixerName/Dev1/HiFi";
+ std::string id_2 = "=MixerName/Dev2/HiFi";
std::string value_1 = "MixerName1";
std::string value_2 = "MixerName2";
snd_use_case_get_value[id_1] = value_1;
snd_use_case_get_value[id_2] = value_2;
- mixer_name_1 = ucm_get_playback_mixer_elem_for_dev(mgr, "Dev1");
- mixer_name_2 = ucm_get_capture_mixer_elem_for_dev(mgr, "Dev2");
+ mixer_name_1 = ucm_get_mixer_name_for_dev(mgr, "Dev1");
+ mixer_name_2 = ucm_get_mixer_name_for_dev(mgr, "Dev2");
EXPECT_EQ(0, strcmp(mixer_name_1, value_1.c_str()));
EXPECT_EQ(0, strcmp(mixer_name_2, value_2.c_str()));
@@ -1100,7 +990,7 @@ TEST(AlsaUcm, ListSectionsByDeviceNameInput) {
EXPECT_EQ(callback_arg, list_devices_callback_args[1]);
}
-TEST(AlsaUcm, GetJackDevForDevice) {
+TEST(AlsaUcm, GetJackNameForDevice) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
const char *jack_name_1, *jack_name_2;
const char* devices[] = {"Dev1", "Comment for Dev1", "Dev2",
@@ -1110,12 +1000,12 @@ TEST(AlsaUcm, GetJackDevForDevice) {
fake_list["_devices/HiFi"] = devices;
fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=JackDev/Dev1/HiFi";
- std::string value_1 = "JackDev1";
+ std::string id_1 = "=JackName/Dev1/HiFi";
+ std::string value_1 = "JackName1";
snd_use_case_get_value[id_1] = value_1;
- jack_name_1 = ucm_get_jack_dev_for_dev(mgr, "Dev1");
- jack_name_2 = ucm_get_jack_dev_for_dev(mgr, "Dev2");
+ jack_name_1 = ucm_get_jack_name_for_dev(mgr, "Dev1");
+ jack_name_2 = ucm_get_jack_name_for_dev(mgr, "Dev2");
EXPECT_EQ(0, strcmp(jack_name_1, value_1.c_str()));
EXPECT_EQ(NULL, jack_name_2);
@@ -1124,28 +1014,43 @@ TEST(AlsaUcm, GetJackDevForDevice) {
free((void*)jack_name_2);
}
-TEST(AlsaUcm, GetJackControlForDevice) {
+TEST(AlsaUcm, GetJackTypeForDevice) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
- const char *jack_name_1, *jack_name_2;
- const char* devices[] = {"Dev1", "Comment for Dev1", "Dev2",
- "Comment for Dev2"};
+ const char *jack_type_1, *jack_type_2, *jack_type_3, *jack_type_4;
+ const char* devices[] = {
+ "Dev1", "Comment for Dev1", "Dev2", "Comment for Dev2",
+ "Dev3", "Comment for Dev3", "Dev4", "Comment for Dev4"};
ResetStubData();
fake_list["_devices/HiFi"] = devices;
- fake_list_size["_devices/HiFi"] = 4;
- std::string id_1 = "=JackControl/Dev1/HiFi";
- std::string value_1 = "JackControl1";
+ fake_list_size["_devices/HiFi"] = 8;
+ std::string id_1 = "=JackType/Dev1/HiFi";
+ std::string value_1 = "hctl";
+ std::string id_2 = "=JackType/Dev2/HiFi";
+ std::string value_2 = "gpio";
+ std::string id_3 = "=JackType/Dev3/HiFi";
+ std::string value_3 = "something";
snd_use_case_get_value[id_1] = value_1;
- jack_name_1 = ucm_get_jack_control_for_dev(mgr, "Dev1");
- jack_name_2 = ucm_get_jack_control_for_dev(mgr, "Dev2");
+ snd_use_case_get_value[id_2] = value_2;
+ snd_use_case_get_value[id_3] = value_3;
- EXPECT_EQ(0, strcmp(jack_name_1, value_1.c_str()));
- EXPECT_EQ(NULL, jack_name_2);
+ jack_type_1 = ucm_get_jack_type_for_dev(mgr, "Dev1");
+ jack_type_2 = ucm_get_jack_type_for_dev(mgr, "Dev2");
+ jack_type_3 = ucm_get_jack_type_for_dev(mgr, "Dev3");
+ jack_type_4 = ucm_get_jack_type_for_dev(mgr, "Dev4");
- free((void*)jack_name_1);
- free((void*)jack_name_2);
+ /* Only "hctl" and "gpio" are valid types. */
+ EXPECT_EQ(0, strcmp(jack_type_1, value_1.c_str()));
+ EXPECT_EQ(0, strcmp(jack_type_2, value_2.c_str()));
+ EXPECT_EQ(NULL, jack_type_3);
+ EXPECT_EQ(NULL, jack_type_4);
+
+ free((void*)jack_type_1);
+ free((void*)jack_type_2);
+ free((void*)jack_type_3);
+ free((void*)jack_type_4);
}
TEST(AlsaUcm, GetPeriodFramesForDevice) {
@@ -1171,6 +1076,7 @@ TEST(AlsaUcm, GetPeriodFramesForDevice) {
dma_period_2 = ucm_get_dma_period_for_dev(mgr, "Dev2");
dma_period_3 = ucm_get_dma_period_for_dev(mgr, "Dev3");
+ /* Only "hctl" and "gpio" are valid types. */
EXPECT_EQ(1000, dma_period_1);
EXPECT_EQ(0, dma_period_2);
EXPECT_EQ(0, dma_period_3);
@@ -1182,22 +1088,18 @@ TEST(AlsaUcm, UcmSection) {
struct mixer_name* controls = NULL;
struct mixer_name* m_name;
int dev_idx = 0;
- int dependent_dev_idx = -1;
size_t i;
enum CRAS_STREAM_DIRECTION dir = CRAS_STREAM_OUTPUT;
static const char* name = "Headphone";
- static const char* pcm_name = "hw:0,1";
static const char* jack_name = "my-card-name Headset Jack";
static const char* jack_type = "gpio";
static const char* mixer_name = "Control1";
static const char* coupled_names[] = {"Coupled1", "Coupled2"};
- section =
- ucm_section_create(NULL, NULL, 0, -1, CRAS_STREAM_OUTPUT, NULL, NULL);
+ section = ucm_section_create(NULL, 0, CRAS_STREAM_OUTPUT, NULL, NULL);
EXPECT_EQ(reinterpret_cast<struct ucm_section*>(NULL), section);
- section = ucm_section_create(name, pcm_name, dev_idx, dependent_dev_idx, dir,
- jack_name, jack_type);
+ section = ucm_section_create(name, dev_idx, dir, jack_name, jack_type);
EXPECT_NE(reinterpret_cast<struct ucm_section*>(NULL), section);
EXPECT_NE(name, section->name);
EXPECT_EQ(0, strcmp(name, section->name));
@@ -1252,7 +1154,6 @@ TEST(AlsaUcm, GetSections) {
struct ucm_section* section;
struct mixer_name* m_name;
int section_count = 0;
- int dev_idx;
int i = 0;
const char* devices[] = {"Headphone", "The headphones jack.",
"Speaker", "The speakers.",
@@ -1260,47 +1161,49 @@ TEST(AlsaUcm, GetSections) {
"Internal Mic", "Internal Microphones",
"HDMI", "HDMI output"};
const char* ids[] = {"=PlaybackPCM/Headphone/HiFi",
- "=JackDev/Headphone/HiFi",
+ "=JackName/Headphone/HiFi",
+ "=JackType/Headphone/HiFi",
"=JackSwitch/Headphone/HiFi",
"=CoupledMixers/Headphone/HiFi",
"=PlaybackPCM/Speaker/HiFi",
"=CoupledMixers/Speaker/HiFi",
- "=DependentPCM/Speaker/HiFi",
"=CapturePCM/Mic/HiFi",
- "=JackDev/Mic/HiFi",
+ "=JackName/Mic/HiFi",
+ "=JackType/Mic/HiFi",
"=JackSwitch/Mic/HiFi",
- "=CaptureMixerElem/Mic/HiFi",
+ "=MixerName/Mic/HiFi",
"=CapturePCM/Internal Mic/HiFi",
"=CoupledMixers/Internal Mic/HiFi",
"=JackSwitch/Internal Mic/HiFi",
"=PlaybackPCM/HDMI/HiFi",
- "=PlaybackMixerElem/HDMI/HiFi",
+ "=MixerName/HDMI/HiFi",
NULL};
const char* values[] = {
"hw:my-sound-card,0",
"my-sound-card Headset Jack",
+ "gpio",
"2",
"HP-L,HP-R",
- "hw:my-sound-card,1",
- "SPK-L,SPK-R",
"hw:my-sound-card,0",
+ "SPK-L,SPK-R",
- "hw:my-sound-card,2",
+ "hw:my-sound-card,0",
"my-sound-card Headset Jack",
+ "gpio",
"0",
"CAPTURE",
- "hw:my-sound-card,3",
+ "hw:my-sound-card,0",
"MIC-L,MIC-R",
"-10",
- "hw:my-sound-card,4",
+ "hw:my-sound-card,2",
"HDMI",
};
@@ -1321,12 +1224,11 @@ TEST(AlsaUcm, GetSections) {
// Headphone
section = sections;
- EXPECT_EQ(0, strcmp(section->pcm_name, "hw:my-sound-card,0"));
EXPECT_EQ(0, strcmp(section->name, "Headphone"));
EXPECT_EQ(0, section->dev_idx);
EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
EXPECT_EQ(0, strcmp(section->jack_name, values[1]));
- EXPECT_EQ(0, strcmp(section->jack_type, "gpio"));
+ EXPECT_EQ(0, strcmp(section->jack_type, values[2]));
EXPECT_EQ(NULL, section->mixer_name);
ASSERT_NE((struct mixer_name*)NULL, section->coupled);
m_name = section->coupled;
@@ -1335,19 +1237,16 @@ TEST(AlsaUcm, GetSections) {
EXPECT_EQ(0, strcmp(m_name->name, "HP-R"));
EXPECT_EQ(NULL, m_name->next);
EXPECT_EQ(2, section->jack_switch);
- dev_idx = section->dev_idx;
// Speaker
section = section->next;
- EXPECT_EQ(0, strcmp(section->pcm_name, "hw:my-sound-card,1"));
EXPECT_EQ(0, strcmp(section->name, "Speaker"));
- EXPECT_EQ(1, section->dev_idx);
+ EXPECT_EQ(0, section->dev_idx);
EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
EXPECT_EQ(NULL, section->jack_name);
EXPECT_EQ(NULL, section->jack_type);
EXPECT_EQ(-1, section->jack_switch);
EXPECT_EQ(NULL, section->mixer_name);
- EXPECT_EQ(dev_idx, section->dependent_dev_idx);
ASSERT_NE((struct mixer_name*)NULL, section->coupled);
m_name = section->coupled;
EXPECT_EQ(0, strcmp(m_name->name, "SPK-L"));
@@ -1357,12 +1256,11 @@ TEST(AlsaUcm, GetSections) {
// Mic
section = section->next;
- EXPECT_EQ(0, strcmp(section->pcm_name, "hw:my-sound-card,2"));
EXPECT_EQ(0, strcmp(section->name, "Mic"));
- EXPECT_EQ(2, section->dev_idx);
+ EXPECT_EQ(0, section->dev_idx);
EXPECT_EQ(CRAS_STREAM_INPUT, section->dir);
EXPECT_EQ(0, strcmp(section->jack_name, values[1]));
- EXPECT_EQ(0, strcmp(section->jack_type, "gpio"));
+ EXPECT_EQ(0, strcmp(section->jack_type, values[2]));
EXPECT_EQ(0, section->jack_switch);
ASSERT_NE((const char*)NULL, section->mixer_name);
EXPECT_EQ(0, strcmp(section->mixer_name, "CAPTURE"));
@@ -1370,9 +1268,8 @@ TEST(AlsaUcm, GetSections) {
// Internal Mic
section = section->next;
- EXPECT_EQ(0, strcmp(section->pcm_name, "hw:my-sound-card,3"));
EXPECT_EQ(0, strcmp(section->name, "Internal Mic"));
- EXPECT_EQ(3, section->dev_idx);
+ EXPECT_EQ(0, section->dev_idx);
EXPECT_EQ(CRAS_STREAM_INPUT, section->dir);
EXPECT_EQ(NULL, section->jack_name);
EXPECT_EQ(NULL, section->jack_type);
@@ -1386,9 +1283,8 @@ TEST(AlsaUcm, GetSections) {
// HDMI
section = section->next;
- EXPECT_EQ(0, strcmp(section->pcm_name, "hw:my-sound-card,4"));
EXPECT_EQ(0, strcmp(section->name, "HDMI"));
- EXPECT_EQ(4, section->dev_idx);
+ EXPECT_EQ(2, section->dev_idx);
EXPECT_EQ(CRAS_STREAM_OUTPUT, section->dir);
EXPECT_EQ(NULL, section->jack_name);
EXPECT_EQ(NULL, section->jack_type);
@@ -1405,7 +1301,7 @@ TEST(AlsaUcm, GetSectionsMissingPCM) {
struct ucm_section* sections;
int i = 0;
const char* devices[] = {"Headphone", "The headphones jack."};
- const char* ids[] = {"=JackDev/Headphone/HiFi",
+ const char* ids[] = {"=JackName/Headphone/HiFi",
"=CoupledMixers/Headphone/HiFi", NULL};
const char* values[] = {
"my-sound-card Headset Jack",
@@ -1426,6 +1322,34 @@ TEST(AlsaUcm, GetSectionsMissingPCM) {
EXPECT_EQ(NULL, sections);
}
+TEST(AlsaUcm, GetSectionsBadPCM) {
+ struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
+ struct ucm_section* sections;
+ int i = 0;
+ const char* devices[] = {"Headphone", "The headphones jack."};
+ const char* ids[] = {"=PlaybackPCM/Headphone/HiFi",
+ "=JackName/Headphone/HiFi",
+ "=CoupledMixers/Headphone/HiFi", NULL};
+ const char* values[] = {
+ "hw:my-sound-card:0",
+ "my-sound-card Headset Jack",
+ "HP-L,HP-R",
+ };
+
+ ResetStubData();
+
+ fake_list["_devices/HiFi"] = devices;
+ fake_list_size["_devices/HiFi"] = ARRAY_SIZE(devices);
+
+ while (ids[i]) {
+ snd_use_case_get_value[ids[i]] = values[i];
+ i++;
+ }
+
+ sections = ucm_get_sections(mgr);
+ EXPECT_EQ(NULL, sections);
+}
+
TEST(AlsaUcm, CheckUseCaseVerbs) {
struct cras_use_case_mgr* mgr = &cras_ucm_mgr;
@@ -1540,19 +1464,6 @@ int snd_use_case_free_list(const char* list[], int items) {
return 0;
}
-int snd_use_case_geti(snd_use_case_mgr_t* uc_mgr,
- const char* identifier,
- long* value) {
- snd_use_case_geti_called++;
- if (snd_use_case_geti_value.find(identifier) ==
- snd_use_case_geti_value.end()) {
- *value = 0;
- return -1;
- }
- *value = snd_use_case_geti_value[identifier];
- return 0;
-}
-
} /* extern "C" */
} // namespace
diff --git a/cras/src/tests/apm_list_unittest.cc b/cras/src/tests/apm_list_unittest.cc
index 65e712fb..2c91cf9b 100644
--- a/cras/src/tests/apm_list_unittest.cc
+++ b/cras/src/tests/apm_list_unittest.cc
@@ -16,8 +16,6 @@ extern "C" {
#include "webrtc_apm.h"
}
-#define FILENAME_TEMPLATE "ApmTest.XXXXXX"
-
namespace {
static void* stream_ptr = reinterpret_cast<void*>(0x123);
@@ -30,12 +28,8 @@ static unsigned int webrtc_apm_process_stream_f_called;
static unsigned int webrtc_apm_process_reverse_stream_f_called;
static device_enabled_callback_t device_enabled_callback_val;
static struct ext_dsp_module* ext_dsp_module_value;
-static struct cras_ionode fake_node;
static struct cras_iodev fake_iodev;
static int webrtc_apm_create_called;
-static bool cras_iodev_is_aec_use_case_ret;
-static dictionary* webrtc_apm_create_aec_ini_val = NULL;
-static dictionary* webrtc_apm_create_apm_ini_val = NULL;
TEST(ApmList, ApmListCreate) {
list = cras_apm_list_create(stream_ptr, 0);
@@ -48,175 +42,30 @@ TEST(ApmList, ApmListCreate) {
cras_apm_list_destroy(list);
}
-static char* prepare_tempdir() {
- char dirname[sizeof(FILENAME_TEMPLATE) + 1];
- char filename[64];
- char* tempdir;
- FILE* fp;
-
- strcpy(dirname, FILENAME_TEMPLATE);
- tempdir = mkdtemp(dirname);
- snprintf(filename, 64, "%s/apm.ini", tempdir);
- fp = fopen(filename, "w");
- fprintf(fp, "%s", "[foo]\n");
- fclose(fp);
- fp = NULL;
- snprintf(filename, 64, "%s/aec.ini", tempdir);
- fp = fopen(filename, "w");
- fprintf(fp, "%s", "[bar]\n");
- fclose(fp);
- fp = NULL;
- return strdup(tempdir);
-}
-
-static void delete_tempdir(char* dir) {
- char filename[64];
-
- snprintf(filename, 64, "%s/apm.ini", dir);
- unlink(filename);
- snprintf(filename, 64, "%s/aec.ini", dir);
- unlink(filename);
- rmdir(dir);
-}
-
-static void init_channel_layout(struct cras_audio_format* fmt) {
- int i;
- for (i = 0; i < CRAS_CH_MAX; i++)
- fmt->channel_layout[i] = -1;
-}
-
-TEST(ApmList, AddApmInputDevUnuseFirstChannel) {
- struct cras_audio_format fmt;
- struct cras_audio_format* val;
- struct cras_apm* apm;
- int ch;
- const int num_test_casts = 9;
- int test_layouts[num_test_casts][CRAS_CH_MAX] = {
- {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {2, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {3, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1},
- {3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1}};
- int test_num_channels[num_test_casts] = {1, 2, 2, 2, 2, 3, 4, 4, 4};
-
- fmt.frame_rate = 48000;
- fmt.format = SND_PCM_FORMAT_S16_LE;
-
- cras_apm_list_init("");
- list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
- EXPECT_NE((void*)NULL, list);
-
- for (int i = 0; i < num_test_casts; i++) {
- fmt.num_channels = test_num_channels[i];
- init_channel_layout(&fmt);
- for (ch = 0; ch < CRAS_CH_MAX; ch++)
- fmt.channel_layout[ch] = test_layouts[i][ch];
-
- /* Input dev is of aec use case. */
- apm = cras_apm_list_add_apm(list, dev_ptr, &fmt, 1);
- EXPECT_NE((void*)NULL, apm);
-
- /* Assert that the post-processing format never has an unset
- * first channel in the layout. */
- bool first_channel_found_in_layout = 0;
- val = cras_apm_list_get_format(apm);
- for (ch = 0; ch < CRAS_CH_MAX; ch++)
- if (0 == val->channel_layout[ch])
- first_channel_found_in_layout = 1;
-
- EXPECT_EQ(1, first_channel_found_in_layout);
-
- cras_apm_list_remove_apm(list, dev_ptr);
- }
-
- cras_apm_list_destroy(list);
- cras_apm_list_deinit();
-}
-
TEST(ApmList, AddRemoveApm) {
struct cras_audio_format fmt;
- char* dir;
fmt.num_channels = 2;
fmt.frame_rate = 48000;
fmt.format = SND_PCM_FORMAT_S16_LE;
- fake_iodev.active_node = &fake_node;
- fake_node.type = CRAS_NODE_TYPE_INTERNAL_SPEAKER;
-
- dir = prepare_tempdir();
- cras_apm_list_init(dir);
- cras_iodev_is_aec_use_case_ret = 1;
list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
EXPECT_NE((void*)NULL, list);
- /* Input dev is of aec use case. */
- EXPECT_NE((void*)NULL, cras_apm_list_add_apm(list, dev_ptr, &fmt, 1));
- EXPECT_NE((void*)NULL, webrtc_apm_create_aec_ini_val);
- EXPECT_NE((void*)NULL, webrtc_apm_create_apm_ini_val);
- EXPECT_EQ((void*)NULL, cras_apm_list_get_active_apm(stream_ptr, dev_ptr));
-
- cras_apm_list_start_apm(list, dev_ptr);
- EXPECT_NE((void*)NULL, cras_apm_list_get_active_apm(stream_ptr, dev_ptr));
- EXPECT_EQ((void*)NULL, cras_apm_list_get_active_apm(stream_ptr, dev_ptr2));
-
- /* Input dev is not of aec use case. */
- EXPECT_NE((void*)NULL, cras_apm_list_add_apm(list, dev_ptr2, &fmt, 0));
- EXPECT_EQ((void*)NULL, webrtc_apm_create_aec_ini_val);
- EXPECT_EQ((void*)NULL, webrtc_apm_create_apm_ini_val);
- cras_apm_list_start_apm(list, dev_ptr2);
- cras_apm_list_stop_apm(list, dev_ptr);
-
- EXPECT_EQ((void*)NULL, cras_apm_list_get_active_apm(stream_ptr, dev_ptr));
- EXPECT_NE((void*)NULL, cras_apm_list_get_active_apm(stream_ptr, dev_ptr2));
-
- cras_apm_list_stop_apm(list, dev_ptr2);
- cras_apm_list_remove_apm(list, dev_ptr);
- cras_apm_list_remove_apm(list, dev_ptr2);
-
- cras_apm_list_destroy(list);
- cras_apm_list_deinit();
- delete_tempdir(dir);
- free(dir);
-}
-
-TEST(ApmList, OutputTypeNotAecUseCase) {
- struct cras_audio_format fmt;
- char* dir;
-
- fmt.num_channels = 2;
- fmt.frame_rate = 48000;
- fmt.format = SND_PCM_FORMAT_S16_LE;
- fake_iodev.active_node = &fake_node;
-
- dir = prepare_tempdir();
- cras_apm_list_init(dir);
+ EXPECT_NE((void*)NULL, cras_apm_list_add(list, dev_ptr, &fmt));
+ EXPECT_EQ((void*)NULL, cras_apm_list_get(list, dev_ptr2));
- list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
- EXPECT_NE((void*)NULL, list);
+ EXPECT_NE((void*)NULL, cras_apm_list_add(list, dev_ptr2, &fmt));
+ EXPECT_NE((void*)NULL, cras_apm_list_get(list, dev_ptr));
- /* Output device is of aec use case. */
- cras_iodev_is_aec_use_case_ret = 1;
- EXPECT_NE((void*)NULL, cras_apm_list_add_apm(list, dev_ptr, &fmt, 1));
- EXPECT_NE((void*)NULL, webrtc_apm_create_aec_ini_val);
- EXPECT_NE((void*)NULL, webrtc_apm_create_apm_ini_val);
- cras_apm_list_remove_apm(list, dev_ptr);
+ cras_apm_list_remove(list, dev_ptr);
+ EXPECT_EQ((void*)NULL, cras_apm_list_get(list, dev_ptr));
+ EXPECT_NE((void*)NULL, cras_apm_list_get(list, dev_ptr2));
- /* Output device is not of aec use case. */
- cras_iodev_is_aec_use_case_ret = 0;
- EXPECT_NE((void*)NULL, cras_apm_list_add_apm(list, dev_ptr, &fmt, 1));
- EXPECT_EQ((void*)NULL, webrtc_apm_create_aec_ini_val);
- EXPECT_EQ((void*)NULL, webrtc_apm_create_apm_ini_val);
- cras_apm_list_remove_apm(list, dev_ptr);
+ cras_apm_list_remove(list, dev_ptr2);
+ EXPECT_EQ((void*)NULL, cras_apm_list_get(list, dev_ptr2));
cras_apm_list_destroy(list);
- cras_apm_list_deinit();
- delete_tempdir(dir);
- free(dir);
}
TEST(ApmList, ApmProcessForwardBuffer) {
@@ -228,16 +77,11 @@ TEST(ApmList, ApmProcessForwardBuffer) {
fmt.num_channels = 2;
fmt.frame_rate = 48000;
fmt.format = SND_PCM_FORMAT_S16_LE;
- init_channel_layout(&fmt);
- fmt.channel_layout[CRAS_CH_FL] = 0;
- fmt.channel_layout[CRAS_CH_FR] = 1;
-
- cras_apm_list_init("");
list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
EXPECT_NE((void*)NULL, list);
- apm = cras_apm_list_add_apm(list, dev_ptr, &fmt, 1);
+ apm = cras_apm_list_add(list, dev_ptr, &fmt);
buf = float_buffer_create(500, 2);
float_buffer_written(buf, 300);
@@ -274,7 +118,6 @@ TEST(ApmList, ApmProcessForwardBuffer) {
float_buffer_destroy(&buf);
cras_apm_list_destroy(list);
- cras_apm_list_deinit();
}
TEST(ApmList, ApmProcessReverseData) {
@@ -316,8 +159,7 @@ TEST(ApmList, ApmProcessReverseData) {
list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
EXPECT_NE((void*)NULL, list);
- apm = cras_apm_list_add_apm(list, dev_ptr, &fmt, 1);
- cras_apm_list_start_apm(list, dev_ptr);
+ apm = cras_apm_list_add(list, dev_ptr, &fmt);
ext_dsp_module_value->run(ext_dsp_module_value, 250);
EXPECT_EQ(0, webrtc_apm_process_reverse_stream_f_called);
@@ -338,22 +180,19 @@ TEST(ApmList, StreamAddToAlreadyOpenedDev) {
fmt.frame_rate = 48000;
fmt.format = SND_PCM_FORMAT_S16_LE;
- cras_apm_list_init("");
-
webrtc_apm_create_called = 0;
list = cras_apm_list_create(stream_ptr, APM_ECHO_CANCELLATION);
EXPECT_NE((void*)NULL, list);
- apm1 = cras_apm_list_add_apm(list, dev_ptr, &fmt, 1);
+ apm1 = cras_apm_list_add(list, dev_ptr, &fmt);
EXPECT_EQ(1, webrtc_apm_create_called);
EXPECT_NE((void*)NULL, apm1);
- apm2 = cras_apm_list_add_apm(list, dev_ptr, &fmt, 1);
+ apm2 = cras_apm_list_add(list, dev_ptr, &fmt);
EXPECT_EQ(1, webrtc_apm_create_called);
EXPECT_EQ(apm1, apm2);
cras_apm_list_destroy(list);
- cras_apm_list_deinit();
}
extern "C" {
@@ -372,9 +211,6 @@ void cras_iodev_set_ext_dsp_module(struct cras_iodev* iodev,
struct ext_dsp_module* ext) {
ext_dsp_module_value = ext;
}
-bool cras_iodev_is_aec_use_case(const struct cras_ionode* node) {
- return cras_iodev_is_aec_use_case_ret;
-}
struct cras_audio_area* cras_audio_area_create(int num_channels) {
return &fake_audio_area;
}
@@ -405,8 +241,6 @@ webrtc_apm webrtc_apm_create(unsigned int num_channels,
dictionary* aec_ini,
dictionary* apm_ini) {
webrtc_apm_create_called++;
- webrtc_apm_create_aec_ini_val = aec_ini;
- webrtc_apm_create_apm_ini_val = apm_ini;
return reinterpret_cast<webrtc_apm>(0x11);
}
void webrtc_apm_dump_configs(dictionary* aec_ini, dictionary* apm_ini) {}
diff --git a/cras/src/tests/audio_thread_unittest.cc b/cras/src/tests/audio_thread_unittest.cc
index 93045e0b..e06514e3 100644
--- a/cras/src/tests/audio_thread_unittest.cc
+++ b/cras/src/tests/audio_thread_unittest.cc
@@ -18,7 +18,6 @@ extern "C" {
#define FIRST_CB_LEVEL 480
static int cras_audio_thread_event_busyloop_called;
-static int cras_audio_thread_event_severe_underrun_called;
static unsigned int cras_rstream_dev_offset_called;
static unsigned int cras_rstream_dev_offset_ret[MAX_CALLS];
static const struct cras_rstream*
@@ -56,7 +55,6 @@ static struct cras_iodev* cras_iodev_start_ramp_odev;
static enum CRAS_IODEV_RAMP_REQUEST cras_iodev_start_ramp_request;
static struct timespec clock_gettime_retspec;
static struct timespec init_cb_ts_;
-static struct timespec sleep_interval_ts_;
static std::map<const struct dev_stream*, struct timespec>
dev_stream_wake_time_val;
static int cras_device_monitor_set_device_mute_state_called;
@@ -965,7 +963,6 @@ TEST_F(StreamDeviceSuite, DoPlaybackSevereUnderrun) {
thread_add_stream(thread_, &rstream, &piodev, 1);
// Assume device is running and there is a severe underrun.
- cras_audio_thread_event_severe_underrun_called = 0;
iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
frames_queued_ = -EPIPE;
@@ -978,7 +975,6 @@ TEST_F(StreamDeviceSuite, DoPlaybackSevereUnderrun) {
// Audio thread should ask main thread to reset device.
EXPECT_EQ(1, cras_iodev_reset_request_called);
EXPECT_EQ(&iodev, cras_iodev_reset_request_iodev);
- EXPECT_EQ(1, cras_audio_thread_event_severe_underrun_called);
thread_rm_open_dev(thread_, CRAS_STREAM_OUTPUT, iodev.info.idx);
TearDownRstream(&rstream);
@@ -1226,12 +1222,10 @@ struct dev_stream* dev_stream_create(struct cras_rstream* stream,
unsigned int dev_id,
const struct cras_audio_format* dev_fmt,
void* dev_ptr,
- struct timespec* cb_ts,
- const struct timespec* sleep_interval_ts) {
+ struct timespec* cb_ts) {
struct dev_stream* out = static_cast<dev_stream*>(calloc(1, sizeof(*out)));
out->stream = stream;
init_cb_ts_ = *cb_ts;
- sleep_interval_ts_ = *sleep_interval_ts;
return out;
}
@@ -1271,7 +1265,7 @@ void dev_stream_set_delay(const struct dev_stream* dev_stream,
void dev_stream_set_dev_rate(struct dev_stream* dev_stream,
unsigned int dev_rate,
double dev_rate_ratio,
- double main_rate_ratio,
+ double master_rate_ratio,
int coarse_rate_adjust) {}
void dev_stream_update_frames(const struct dev_stream* dev_stream) {}
@@ -1317,9 +1311,7 @@ int cras_iodev_fill_odev_zeros(struct cras_iodev* odev, unsigned int frames) {
return 0;
}
-int cras_iodev_output_underrun(struct cras_iodev* odev,
- unsigned int hw_level,
- unsigned int frames_written) {
+int cras_iodev_output_underrun(struct cras_iodev* odev) {
cras_iodev_output_underrun_called++;
return 0;
}
@@ -1412,19 +1404,12 @@ int cras_device_monitor_set_device_mute_state(unsigned int dev_idx) {
cras_device_monitor_set_device_mute_state_called++;
return 0;
}
-int cras_device_monitor_error_close(unsigned int dev_idx) {
- return 0;
-}
int cras_iodev_drop_frames_by_time(struct cras_iodev* iodev,
struct timespec ts) {
return 0;
}
-bool cras_iodev_is_on_internal_card(const struct cras_ionode* node) {
- return 0;
-}
-
// From librt.
int clock_gettime(clockid_t clk_id, struct timespec* tp) {
*tp = clock_gettime_retspec;
@@ -1457,16 +1442,6 @@ int cras_audio_thread_event_drop_samples() {
return 0;
}
-int cras_audio_thread_event_severe_underrun() {
- cras_audio_thread_event_severe_underrun_called++;
- return 0;
-}
-
-float input_data_get_software_gain_scaler(struct input_data* data,
- float idev_sw_gain_scaler,
- struct cras_rstream* stream) {
- return 1.0;
-}
} // extern "C"
int main(int argc, char** argv) {
diff --git a/cras/src/tests/audio_thread_unittest_obsolete.cc b/cras/src/tests/audio_thread_unittest_obsolete.cc
index ae9f5ef3..0baeb38f 100644
--- a/cras/src/tests/audio_thread_unittest_obsolete.cc
+++ b/cras/src/tests/audio_thread_unittest_obsolete.cc
@@ -52,8 +52,8 @@ static unsigned int dev_stream_mix_called;
static struct timespec time_now;
static int cras_fmt_conversion_needed_return_val;
-static struct cras_audio_area* mock_audio_area1;
-static struct cras_audio_area* mock_audio_area2;
+static struct cras_audio_area* dummy_audio_area1;
+static struct cras_audio_area* dummy_audio_area2;
static struct cras_audio_format cras_iodev_set_format_val;
static struct dev_stream_capture_call dev_stream_capture_call;
@@ -95,18 +95,18 @@ class ReadStreamSuite : public testing::Test {
SetupRstream(&rstream2_, 2);
shm2_ = cras_rstream_input_shm(rstream2_);
- mock_audio_area1 = (cras_audio_area*)calloc(
+ dummy_audio_area1 = (cras_audio_area*)calloc(
1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area));
- mock_audio_area1->num_channels = 2;
- channel_area_set_channel(&mock_audio_area1->channels[0], CRAS_CH_FL);
- channel_area_set_channel(&mock_audio_area1->channels[1], CRAS_CH_FR);
- rstream_->input_audio_area = mock_audio_area1;
- mock_audio_area2 = (cras_audio_area*)calloc(
+ dummy_audio_area1->num_channels = 2;
+ channel_area_set_channel(&dummy_audio_area1->channels[0], CRAS_CH_FL);
+ channel_area_set_channel(&dummy_audio_area1->channels[1], CRAS_CH_FR);
+ rstream_->input_audio_area = dummy_audio_area1;
+ dummy_audio_area2 = (cras_audio_area*)calloc(
1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area));
- mock_audio_area2->num_channels = 2;
- channel_area_set_channel(&mock_audio_area2->channels[0], CRAS_CH_FL);
- channel_area_set_channel(&mock_audio_area2->channels[1], CRAS_CH_FR);
- rstream2_->input_audio_area = mock_audio_area2;
+ dummy_audio_area2->num_channels = 2;
+ channel_area_set_channel(&dummy_audio_area2->channels[0], CRAS_CH_FL);
+ channel_area_set_channel(&dummy_audio_area2->channels[1], CRAS_CH_FR);
+ rstream2_->input_audio_area = dummy_audio_area2;
dev_stream_mix_dont_fill_next = 0;
dev_stream_mix_count = 0;
@@ -123,8 +123,8 @@ class ReadStreamSuite : public testing::Test {
free(rstream_);
free(shm2_->area);
free(rstream2_);
- free(mock_audio_area1);
- free(mock_audio_area2);
+ free(dummy_audio_area1);
+ free(dummy_audio_area2);
}
void SetupRstream(struct cras_rstream** rstream, int fd) {
@@ -1444,18 +1444,18 @@ class ActiveDevicesSuite : public testing::Test {
rstream2_->buffer_frames -= 50;
rstream2_->cb_threshold -= 50;
- mock_audio_area1 = (cras_audio_area*)calloc(
+ dummy_audio_area1 = (cras_audio_area*)calloc(
1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area));
- mock_audio_area1->num_channels = 2;
- channel_area_set_channel(&mock_audio_area1->channels[0], CRAS_CH_FL);
- channel_area_set_channel(&mock_audio_area1->channels[1], CRAS_CH_FR);
- rstream_->input_audio_area = mock_audio_area1;
- mock_audio_area2 = (cras_audio_area*)calloc(
+ dummy_audio_area1->num_channels = 2;
+ channel_area_set_channel(&dummy_audio_area1->channels[0], CRAS_CH_FL);
+ channel_area_set_channel(&dummy_audio_area1->channels[1], CRAS_CH_FR);
+ rstream_->input_audio_area = dummy_audio_area1;
+ dummy_audio_area2 = (cras_audio_area*)calloc(
1, sizeof(cras_audio_area) + 2 * sizeof(cras_channel_area));
- mock_audio_area2->num_channels = 2;
- channel_area_set_channel(&mock_audio_area2->channels[0], CRAS_CH_FL);
- channel_area_set_channel(&mock_audio_area2->channels[1], CRAS_CH_FR);
- rstream2_->input_audio_area = mock_audio_area2;
+ dummy_audio_area2->num_channels = 2;
+ channel_area_set_channel(&dummy_audio_area2->channels[0], CRAS_CH_FL);
+ channel_area_set_channel(&dummy_audio_area2->channels[1], CRAS_CH_FR);
+ rstream2_->input_audio_area = dummy_audio_area2;
cras_iodev_set_format_called = 0;
close_dev_called_ = 0;
@@ -1483,8 +1483,8 @@ class ActiveDevicesSuite : public testing::Test {
shm = cras_rstream_output_shm(rstream_);
free(shm->header);
free(rstream_);
- free(mock_audio_area1);
- free(mock_audio_area2);
+ free(dummy_audio_area1);
+ free(dummy_audio_area2);
}
void SetupRstream(struct cras_rstream** rstream) {
diff --git a/cras/src/tests/bt_device_unittest.cc b/cras/src/tests/bt_device_unittest.cc
index ccb581cc..d2e9a13f 100644
--- a/cras/src/tests/bt_device_unittest.cc
+++ b/cras/src/tests/bt_device_unittest.cc
@@ -15,8 +15,6 @@ extern "C" {
#define FAKE_OBJ_PATH "/obj/path"
}
-static const unsigned int CONN_WATCH_MAX_RETRIES = 30;
-
static struct cras_iodev* cras_bt_io_create_profile_ret;
static struct cras_iodev* cras_bt_io_append_btio_val;
static struct cras_ionode* cras_bt_io_get_profile_ret;
@@ -32,7 +30,6 @@ static cras_main_message* cras_main_message_send_msg;
static cras_message_callback cras_main_message_add_handler_callback;
static void* cras_main_message_add_handler_callback_data;
static int cras_tm_create_timer_called;
-static int cras_tm_cancel_timer_called;
static int cras_a2dp_start_called;
static int cras_a2dp_suspend_connected_device_called;
static int cras_hfp_ag_remove_conflict_called;
@@ -44,10 +41,6 @@ static int dbus_message_new_method_call_called;
static const char* dbus_message_new_method_call_method;
static struct cras_bt_device* cras_a2dp_connected_device_ret;
static struct cras_bt_device* cras_a2dp_suspend_connected_device_dev;
-static struct cras_timer* cras_tm_cancel_timer_arg;
-static struct cras_timer* cras_tm_create_timer_ret;
-static size_t cras_iodev_set_node_plugged_called;
-static int cras_iodev_set_node_plugged_value;
struct MockDBusMessage {
int type;
@@ -65,7 +58,6 @@ void ResetStubData() {
cras_bt_io_try_remove_ret = 0;
cras_main_message_send_msg = NULL;
cras_tm_create_timer_called = 0;
- cras_tm_cancel_timer_called = 0;
cras_a2dp_start_called = 0;
cras_a2dp_suspend_connected_device_called = 0;
cras_hfp_ag_remove_conflict_called = 0;
@@ -74,7 +66,6 @@ void ResetStubData() {
dbus_message_new_method_call_method = NULL;
dbus_message_new_method_call_called = 0;
cras_a2dp_connected_device_ret = NULL;
- cras_iodev_set_node_plugged_called = 0;
}
static void FreeMockDBusMessage(MockDBusMessage* head) {
@@ -87,12 +78,11 @@ static void FreeMockDBusMessage(MockDBusMessage* head) {
delete head;
}
-static struct MockDBusMessage* NewMockDBusConnectedMessage(long connected) {
+static struct MockDBusMessage* NewMockDBusConnectedMessage() {
MockDBusMessage* msg = new MockDBusMessage{DBUS_TYPE_ARRAY, NULL};
MockDBusMessage* dict =
new MockDBusMessage{DBUS_TYPE_STRING, (void*)strdup("Connected")};
- MockDBusMessage* variant =
- new MockDBusMessage{DBUS_TYPE_BOOLEAN, (void*)connected};
+ MockDBusMessage* variant = new MockDBusMessage{DBUS_TYPE_BOOLEAN, (void*)1};
msg->recurse = dict;
dict->next = new MockDBusMessage{DBUS_TYPE_INVALID, NULL};
@@ -176,8 +166,6 @@ TEST_F(BtDeviceTestSuite, AppendRmIodev) {
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
cras_bt_device_rm_iodev(device, &d2_);
EXPECT_EQ(1, cras_bt_io_remove_called);
- EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
- EXPECT_EQ(0, cras_iodev_set_node_plugged_value);
/* Test A2DP disconnection will cause bt_io destroy. */
cras_bt_io_try_remove_ret = 0;
@@ -185,8 +173,6 @@ TEST_F(BtDeviceTestSuite, AppendRmIodev) {
EXPECT_EQ(1, cras_bt_io_remove_called);
EXPECT_EQ(1, cras_bt_io_destroy_called);
EXPECT_EQ(0, cras_bt_device_get_active_profile(device));
- EXPECT_EQ(2, cras_iodev_set_node_plugged_called);
- EXPECT_EQ(0, cras_iodev_set_node_plugged_value);
cras_bt_device_remove(device);
}
@@ -228,10 +214,9 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpOnly) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(device,
- CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
+ cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
@@ -239,22 +224,14 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpOnly) {
/* Schedule another timer, if A2DP not yet configured. */
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
-
- /* ConnectProfile must not be called, since this is A2DP only case. */
- EXPECT_EQ(0, dbus_message_new_method_call_called);
+ EXPECT_EQ(1, dbus_message_new_method_call_called);
+ EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
cras_bt_device_a2dp_configured(device);
-
- /* Prepate the iodev created by cras_a2dp_start. */
- cras_bt_io_create_profile_ret = &bt_iodev1;
- cras_bt_device_append_iodev(device, &d1_, CRAS_BT_DEVICE_PROFILE_A2DP_SOURCE);
-
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
EXPECT_EQ(1, cras_a2dp_start_called);
- EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
- EXPECT_EQ(1, cras_iodev_set_node_plugged_value);
cras_bt_device_remove(device);
FreeMockDBusMessage(msg_root);
@@ -269,11 +246,10 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedHfpHspOnly) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
+ cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
@@ -281,23 +257,15 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedHfpHspOnly) {
/* Schedule another timer, if HFP AG not yet intialized. */
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
-
- /* ConnectProfile must not be called, since this is HFP only case. */
- EXPECT_EQ(0, dbus_message_new_method_call_called);
+ EXPECT_EQ(1, dbus_message_new_method_call_called);
+ EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
cras_bt_device_audio_gateway_initialized(device);
- /* Prepate the iodev created by ag initialization. */
- cras_bt_io_create_profile_ret = &bt_iodev2;
- cras_bt_device_append_iodev(device, &d3_,
- CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
-
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
EXPECT_EQ(1, cras_hfp_ag_remove_conflict_called);
EXPECT_EQ(1, cras_hfp_ag_start_called);
- EXPECT_EQ(1, cras_iodev_set_node_plugged_called);
- EXPECT_EQ(1, cras_iodev_set_node_plugged_value);
cras_bt_device_remove(device);
FreeMockDBusMessage(msg_root);
@@ -312,12 +280,11 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpHfpHsp) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
- CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
+ cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
+ cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
@@ -326,19 +293,12 @@ TEST_F(BtDeviceTestSuite, SetDeviceConnectedA2dpHfpHsp) {
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
- /* ConnectProfile must not be called, since the first profile connection
- * should be initiated by Bluez.
- */
- EXPECT_EQ(0, dbus_message_new_method_call_called);
-
cras_bt_device_audio_gateway_initialized(device);
/* Schedule another timer, because A2DP is not ready. */
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(3, cras_tm_create_timer_called);
EXPECT_EQ(0, cras_hfp_ag_start_called);
-
- /* ConnectProfile should be called to connect A2DP, since HFP is connected */
EXPECT_EQ(1, dbus_message_new_method_call_called);
EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
@@ -363,12 +323,11 @@ TEST_F(BtDeviceTestSuite, DevConnectedConflictCheck) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
- CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
+ cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
+ cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
cras_bt_device_audio_gateway_initialized(device);
cras_bt_device_a2dp_configured(device);
@@ -402,34 +361,42 @@ TEST_F(BtDeviceTestSuite, A2dpDropped) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
- CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
+ cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
+ cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
- cras_bt_device_audio_gateway_initialized(device);
- cras_bt_device_a2dp_configured(device);
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
+ /* Schedule another timer, if HFP AG not yet intialized. */
+ cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
+ EXPECT_EQ(2, cras_tm_create_timer_called);
+ EXPECT_EQ(1, dbus_message_new_method_call_called);
+ EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
+
+ cras_bt_device_a2dp_configured(device);
+
+ cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
+ EXPECT_EQ(3, cras_tm_create_timer_called);
+
cras_bt_device_notify_profile_dropped(device,
CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
- EXPECT_EQ(2, cras_tm_create_timer_called);
+ EXPECT_EQ(4, cras_tm_create_timer_called);
/* Expect suspend timer is scheduled. */
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(1, cras_a2dp_suspend_connected_device_called);
EXPECT_EQ(1, cras_hfp_ag_suspend_connected_device_called);
- EXPECT_EQ(1, dbus_message_new_method_call_called);
+ EXPECT_EQ(2, dbus_message_new_method_call_called);
EXPECT_STREQ("Disconnect", dbus_message_new_method_call_method);
cras_bt_device_remove(device);
FreeMockDBusMessage(msg_root);
}
-TEST_F(BtDeviceTestSuite, DevConnectDisconnectBackToBack) {
+TEST_F(BtDeviceTestSuite, ConnectionWatchTimeout) {
struct cras_bt_device* device;
struct MockDBusMessage *msg_root, *cur;
@@ -438,89 +405,26 @@ TEST_F(BtDeviceTestSuite, DevConnectDisconnectBackToBack) {
device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
EXPECT_NE((void*)NULL, device);
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
- CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ cras_bt_device_add_supported_profiles(device, A2DP_SINK_UUID);
+ cras_bt_device_add_supported_profiles(device, HSP_HS_UUID);
+ cras_bt_device_add_supported_profiles(device, HFP_HF_UUID);
- cur = msg_root = NewMockDBusConnectedMessage(1);
+ cur = msg_root = NewMockDBusConnectedMessage();
cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
- FreeMockDBusMessage(msg_root);
-
- cras_bt_device_a2dp_configured(device);
- cras_bt_device_audio_gateway_initialized(device);
- /* Expect suspend timer is scheduled. */
- cras_tm_create_timer_ret = reinterpret_cast<struct cras_timer*>(0x101);
- cras_bt_device_notify_profile_dropped(device,
- CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
- EXPECT_EQ(2, cras_tm_create_timer_called);
- /* Another profile drop won't schedule another timer because one is
- * already armed. */
- EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
- cras_bt_device_notify_profile_dropped(device,
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
+ /* Schedule another timer, if HFP AG not yet intialized. */
+ cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
EXPECT_EQ(2, cras_tm_create_timer_called);
-
- cur = msg_root = NewMockDBusConnectedMessage(0);
- cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
-
- /* When BlueZ reports headset disconnection, cancel the pending timer. */
- EXPECT_EQ(cras_tm_cancel_timer_called, 1);
- EXPECT_EQ(cras_tm_cancel_timer_arg, (void*)0x101);
- FreeMockDBusMessage(msg_root);
-
- /* Headset connects again. */
- cur = msg_root = NewMockDBusConnectedMessage(1);
- cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
- EXPECT_EQ(3, cras_tm_create_timer_called);
- EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
- FreeMockDBusMessage(msg_root);
-
- /* Headset disconnects, later profile drop events shouldn't trigger
- * suspend timer because headset is already in disconnected stats.
- */
- cur = msg_root = NewMockDBusConnectedMessage(0);
- cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
- FreeMockDBusMessage(msg_root);
-
- cras_tm_create_timer_called = 0;
- cras_bt_device_notify_profile_dropped(device,
- CRAS_BT_DEVICE_PROFILE_A2DP_SINK);
- EXPECT_EQ(0, cras_tm_create_timer_called);
- cras_bt_device_notify_profile_dropped(device,
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
- EXPECT_EQ(0, cras_tm_create_timer_called);
-
- cras_bt_device_remove(device);
-}
-
-TEST_F(BtDeviceTestSuite, ConnectionWatchTimeout) {
- struct cras_bt_device* device;
- struct MockDBusMessage *msg_root, *cur;
-
- ResetStubData();
-
- device = cras_bt_device_create(NULL, FAKE_OBJ_PATH);
- EXPECT_NE((void*)NULL, device);
-
- cras_bt_device_set_supported_profiles(
- device, CRAS_BT_DEVICE_PROFILE_A2DP_SINK |
- CRAS_BT_DEVICE_PROFILE_HSP_HEADSET |
- CRAS_BT_DEVICE_PROFILE_HFP_HANDSFREE);
-
- cur = msg_root = NewMockDBusConnectedMessage(1);
- cras_bt_device_update_properties(device, (DBusMessageIter*)&cur, NULL);
- EXPECT_EQ(1, cras_tm_create_timer_called);
- EXPECT_NE((void*)NULL, cras_tm_create_timer_cb);
+ EXPECT_EQ(1, dbus_message_new_method_call_called);
+ EXPECT_STREQ("ConnectProfile", dbus_message_new_method_call_method);
cras_bt_device_a2dp_configured(device);
- for (unsigned int i = 0; i < CONN_WATCH_MAX_RETRIES; i++) {
+ for (int i = 0; i < 29; i++) {
cras_tm_create_timer_cb(NULL, cras_tm_create_timer_cb_data);
- EXPECT_EQ(i + 2, cras_tm_create_timer_called);
+ EXPECT_EQ(i + 3, cras_tm_create_timer_called);
EXPECT_EQ(0, cras_a2dp_start_called);
EXPECT_EQ(0, cras_hfp_ag_start_called);
EXPECT_EQ(0, cras_hfp_ag_remove_conflict_called);
@@ -647,11 +551,6 @@ int cras_iodev_close(struct cras_iodev* dev) {
return 0;
}
-void cras_iodev_set_node_plugged(struct cras_ionode* ionode, int plugged) {
- cras_iodev_set_node_plugged_called++;
- cras_iodev_set_node_plugged_value = plugged;
-}
-
int cras_iodev_list_dev_is_enabled(const struct cras_iodev* dev) {
return 0;
}
@@ -695,13 +594,10 @@ struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
cras_tm_create_timer_called++;
cras_tm_create_timer_cb = cb;
cras_tm_create_timer_cb_data = cb_data;
- return cras_tm_create_timer_ret;
+ return NULL;
}
-void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {
- cras_tm_cancel_timer_called++;
- cras_tm_cancel_timer_arg = t;
-}
+void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {}
DBusMessage* dbus_message_new_method_call(const char* destination,
const char* path,
diff --git a/cras/src/tests/bt_io_unittest.cc b/cras/src/tests/bt_io_unittest.cc
index dd02652f..97f4dae4 100644
--- a/cras/src/tests/bt_io_unittest.cc
+++ b/cras/src/tests/bt_io_unittest.cc
@@ -59,8 +59,6 @@ class BtIoBasicSuite : public testing::Test {
ResetStubData();
SetUpIodev(&iodev_, CRAS_STREAM_OUTPUT);
SetUpIodev(&iodev2_, CRAS_STREAM_OUTPUT);
- iodev_.active_node = &node_;
- iodev2_.active_node = &node2_;
update_supported_formats_called_ = 0;
frames_queued_called_ = 0;
@@ -139,8 +137,6 @@ class BtIoBasicSuite : public testing::Test {
static struct cras_iodev* bt_iodev;
static struct cras_iodev iodev_;
static struct cras_iodev iodev2_;
- static struct cras_ionode node_;
- static struct cras_ionode node2_;
static unsigned int update_supported_formats_called_;
static unsigned int frames_queued_called_;
static unsigned int delay_frames_called_;
@@ -153,8 +149,6 @@ class BtIoBasicSuite : public testing::Test {
struct cras_iodev* BtIoBasicSuite::bt_iodev;
struct cras_iodev BtIoBasicSuite::iodev_;
struct cras_iodev BtIoBasicSuite::iodev2_;
-struct cras_ionode BtIoBasicSuite::node_;
-struct cras_ionode BtIoBasicSuite::node2_;
unsigned int BtIoBasicSuite::update_supported_formats_called_;
unsigned int BtIoBasicSuite::frames_queued_called_;
unsigned int BtIoBasicSuite::delay_frames_called_;
@@ -178,7 +172,6 @@ TEST_F(BtIoBasicSuite, CreateBtIo) {
bt_iodev->update_supported_formats(bt_iodev);
EXPECT_EQ(1, update_supported_formats_called_);
- bt_iodev->state = CRAS_IODEV_STATE_OPEN;
bt_iodev->configure_dev(bt_iodev);
EXPECT_EQ(1, configure_dev_called_);
bt_iodev->frames_queued(bt_iodev, &tstamp);
@@ -235,7 +228,6 @@ TEST_F(BtIoBasicSuite, SwitchProfileOnCloseInputDev) {
iodev_.direction = CRAS_STREAM_INPUT;
bt_iodev = cras_bt_io_create(fake_device, &iodev_,
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
- bt_iodev->state = CRAS_IODEV_STATE_OPEN;
cras_bt_device_get_active_profile_ret =
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
@@ -254,7 +246,6 @@ TEST_F(BtIoBasicSuite, NoSwitchProfileOnCloseInputDevNoSupportA2dp) {
iodev_.direction = CRAS_STREAM_INPUT;
bt_iodev = cras_bt_io_create(fake_device, &iodev_,
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
- bt_iodev->state = CRAS_IODEV_STATE_OPEN;
cras_bt_device_get_active_profile_ret =
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
@@ -266,23 +257,6 @@ TEST_F(BtIoBasicSuite, NoSwitchProfileOnCloseInputDevNoSupportA2dp) {
cras_bt_io_destroy(bt_iodev);
}
-TEST_F(BtIoBasicSuite, NoSwitchProfileOnCloseInputDevInCloseState) {
- ResetStubData();
- iodev_.direction = CRAS_STREAM_INPUT;
- bt_iodev = cras_bt_io_create(fake_device, &iodev_,
- CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
- bt_iodev->state = CRAS_IODEV_STATE_CLOSE;
-
- cras_bt_device_get_active_profile_ret =
- CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY |
- CRAS_BT_DEVICE_PROFILE_HSP_AUDIOGATEWAY;
- cras_bt_device_has_a2dp_ret = 1;
- bt_iodev->close_dev(bt_iodev);
-
- EXPECT_EQ(0, cras_bt_device_switch_profile_called);
- cras_bt_io_destroy(bt_iodev);
-}
-
TEST_F(BtIoBasicSuite, SwitchProfileOnAppendA2dpDev) {
ResetStubData();
bt_iodev = cras_bt_io_create(fake_device, &iodev_,
@@ -423,8 +397,7 @@ int cras_iodev_list_rm_input(struct cras_iodev* dev) {
}
// From bt device
-unsigned int cras_bt_device_get_active_profile(
- const struct cras_bt_device* device) {
+int cras_bt_device_get_active_profile(const struct cras_bt_device* device) {
return cras_bt_device_get_active_profile_ret;
}
@@ -458,10 +431,6 @@ const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
return "/fake/object/path";
}
-int cras_bt_device_get_stable_id(const struct cras_bt_device* device) {
- return 123;
-}
-
int cras_bt_device_get_use_hardware_volume(struct cras_bt_device* device) {
return 1;
}
@@ -474,20 +443,4 @@ int cras_iodev_default_no_stream_playback(struct cras_iodev* odev, int enable) {
return 0;
}
-int cras_iodev_frames_queued(struct cras_iodev* iodev,
- struct timespec* hw_tstamp) {
- return 0;
-}
-
-unsigned int cras_iodev_default_frames_to_play_in_sleep(
- struct cras_iodev* odev,
- unsigned int* hw_level,
- struct timespec* hw_tstamp) {
- return 0;
-}
-
-int hfp_iodev_is_hsp(struct cras_iodev* iodev) {
- return 0;
-}
-
} // extern "C"
diff --git a/cras/src/tests/capture_rclient_unittest.cc b/cras/src/tests/capture_rclient_unittest.cc
index 446fddfa..5e0bc58c 100644
--- a/cras/src/tests/capture_rclient_unittest.cc
+++ b/cras/src/tests/capture_rclient_unittest.cc
@@ -20,18 +20,22 @@ extern "C" {
}
static unsigned int cras_make_fd_nonblocking_called;
static unsigned int cras_observer_remove_called;
+static unsigned int cras_server_metrics_stream_config_called;
static int stream_list_add_called;
static int stream_list_add_return;
static unsigned int stream_list_rm_called;
-static struct cras_audio_shm mock_shm;
-static struct cras_rstream mock_rstream;
+static struct cras_audio_shm dummy_shm;
+static struct cras_rstream dummy_rstream;
+static unsigned int cras_rstream_config_init_with_message_called;
void ResetStubData() {
cras_make_fd_nonblocking_called = 0;
cras_observer_remove_called = 0;
+ cras_server_metrics_stream_config_called = 0;
stream_list_add_called = 0;
stream_list_add_return = 0;
stream_list_rm_called = 0;
+ cras_rstream_config_init_with_message_called = 0;
}
namespace {
@@ -106,12 +110,13 @@ TEST_F(CCRMessageSuite, StreamConnectMessage) {
cras_fill_connect_message(&msg, CRAS_STREAM_INPUT, stream_id,
CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_UNKNOWN,
480, 240, /*flags=*/0, /*effects=*/0, fmt,
- NO_DEVICE);
+ NO_DEVICE, /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
EXPECT_EQ(1, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
EXPECT_EQ(1, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -133,14 +138,16 @@ TEST_F(CCRMessageSuite, StreamConnectMessageInvalidDirection) {
continue;
cras_fill_connect_message(&msg, dir, stream_id, CRAS_STREAM_TYPE_DEFAULT,
CRAS_CLIENT_TYPE_UNKNOWN, 480, 240, /*flags=*/0,
- /*effects=*/0, fmt, NO_DEVICE);
+ /*effects=*/0, fmt, NO_DEVICE,
+ /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rc = rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_,
1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(0, cras_rstream_config_init_with_message_called);
EXPECT_EQ(0, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -160,14 +167,15 @@ TEST_F(CCRMessageSuite, StreamConnectMessageInvalidClientId) {
cras_fill_connect_message(&msg, CRAS_STREAM_INPUT, stream_id,
CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_UNKNOWN,
480, 240, /*flags=*/0, /*effects=*/0, fmt,
- NO_DEVICE);
+ NO_DEVICE, /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rc =
rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(0, cras_rstream_config_init_with_message_called);
EXPECT_EQ(0, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -177,6 +185,43 @@ TEST_F(CCRMessageSuite, StreamConnectMessageInvalidClientId) {
EXPECT_EQ(stream_id, out_msg.stream_id);
}
+/*
+ * TODO(yuhsaun): Remove this test when there are no client uses the old
+ * craslib. (CRAS_PROTO_VER = 3)
+ */
+TEST_F(CCRMessageSuite, StreamConnectMessageOldProtocal) {
+ struct cras_client_stream_connected out_msg;
+ int rc;
+
+ struct cras_connect_message_old msg;
+ cras_stream_id_t stream_id = 0x10002;
+
+ msg.proto_version = 3;
+ msg.direction = CRAS_STREAM_INPUT;
+ msg.stream_id = stream_id;
+ msg.stream_type = CRAS_STREAM_TYPE_DEFAULT;
+ msg.buffer_frames = 480;
+ msg.cb_threshold = 240;
+ msg.flags = 0;
+ msg.effects = 0;
+ pack_cras_audio_format(&msg.format, &fmt);
+ msg.dev_idx = NO_DEVICE;
+ msg.header.id = CRAS_SERVER_CONNECT_STREAM;
+ msg.header.length = sizeof(struct cras_connect_message_old);
+
+ fd_ = 100;
+ rc =
+ rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
+ EXPECT_EQ(1, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
+ EXPECT_EQ(1, stream_list_add_called);
+ EXPECT_EQ(0, stream_list_rm_called);
+
+ rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
+ EXPECT_EQ(sizeof(out_msg), rc);
+ EXPECT_EQ(stream_id, out_msg.stream_id);
+}
+
TEST_F(CCRMessageSuite, StreamDisconnectMessage) {
struct cras_disconnect_stream_message msg;
cras_stream_id_t stream_id = 0x10002;
@@ -223,6 +268,11 @@ unsigned int cras_rstream_get_effects(const struct cras_rstream* stream) {
return 0;
}
+int cras_server_metrics_stream_config(struct cras_rstream_config* config) {
+ cras_server_metrics_stream_config_called++;
+ return 0;
+}
+
int cras_send_with_fds(int sockfd,
const void* buf,
size_t len,
@@ -252,27 +302,30 @@ int stream_list_add(struct stream_list* list,
struct cras_rstream** stream) {
int ret;
- *stream = &mock_rstream;
+ *stream = &dummy_rstream;
stream_list_add_called++;
ret = stream_list_add_return;
if (ret)
stream_list_add_return = -EINVAL;
- mock_rstream.shm = &mock_shm;
- mock_rstream.direction = config->direction;
- mock_rstream.stream_id = config->stream_id;
+ dummy_rstream.shm = &dummy_shm;
+ dummy_rstream.direction = config->direction;
+ dummy_rstream.stream_id = config->stream_id;
return ret;
}
-bool cras_audio_format_valid(const struct cras_audio_format* fmt) {
- return true;
+void cras_rstream_config_init_with_message(
+ struct cras_rclient* client,
+ const struct cras_connect_message* msg,
+ int* aud_fd,
+ int* client_shm_fd,
+ const struct cras_audio_format* remote_fmt,
+ struct cras_rstream_config* stream_config) {
+ cras_rstream_config_init_with_message_called++;
}
-void detect_rtc_stream_pair(struct stream_list* list,
- struct cras_rstream* stream) {
- return;
-}
+void cras_rstream_config_cleanup(struct cras_rstream_config* stream_config) {}
} // extern "C"
diff --git a/cras/src/tests/control_rclient_unittest.cc b/cras/src/tests/control_rclient_unittest.cc
index 63e3c8f0..634bfe1a 100644
--- a/cras/src/tests/control_rclient_unittest.cc
+++ b/cras/src/tests/control_rclient_unittest.cc
@@ -9,7 +9,6 @@
extern "C" {
#include "audio_thread.h"
#include "cras_bt_log.h"
-#include "cras_main_thread_log.h"
#include "cras_messages.h"
#include "cras_rclient.h"
#include "cras_rstream.h"
@@ -21,14 +20,13 @@ extern "C" {
}
// Stub data.
-static int audio_thread_config_global_remix_called;
-static float audio_thread_config_global_remix_copy[CRAS_MAX_REMIX_CHANNELS *
- CRAS_MAX_REMIX_CHANNELS];
static int cras_rstream_create_return;
static struct cras_rstream* cras_rstream_create_stream_out;
static int cras_iodev_attach_stream_retval;
static size_t cras_system_set_volume_value;
static int cras_system_set_volume_called;
+static size_t cras_system_set_capture_gain_value;
+static int cras_system_set_capture_gain_called;
static size_t cras_system_set_mute_value;
static int cras_system_set_mute_called;
static size_t cras_system_set_user_mute_value;
@@ -47,8 +45,9 @@ static unsigned int stream_list_add_stream_called;
static unsigned int stream_list_disconnect_stream_called;
static unsigned int cras_iodev_list_rm_input_called;
static unsigned int cras_iodev_list_rm_output_called;
-static struct cras_audio_shm mock_shm;
-static struct cras_rstream mock_rstream;
+static unsigned int cras_server_metrics_stream_config_called;
+static struct cras_audio_shm dummy_shm;
+static struct cras_rstream dummy_rstream;
static size_t cras_observer_num_ops_registered;
static size_t cras_observer_register_notify_called;
static size_t cras_observer_add_called;
@@ -60,16 +59,17 @@ static size_t cras_observer_set_ops_called;
static size_t cras_observer_ops_are_empty_called;
static struct cras_observer_ops cras_observer_ops_are_empty_empty_ops;
static size_t cras_observer_remove_called;
+static unsigned int cras_rstream_config_init_with_message_called;
void ResetStubData() {
- audio_thread_config_global_remix_called = 0;
- memset(audio_thread_config_global_remix_copy, 0,
- sizeof(audio_thread_config_global_remix_copy));
cras_rstream_create_return = 0;
cras_rstream_create_stream_out = (struct cras_rstream*)NULL;
cras_iodev_attach_stream_retval = 0;
+ cras_server_metrics_stream_config_called = 0;
cras_system_set_volume_value = 0;
cras_system_set_volume_called = 0;
+ cras_system_set_capture_gain_value = 0;
+ cras_system_set_capture_gain_called = 0;
cras_system_set_mute_value = 0;
cras_system_set_mute_called = 0;
cras_system_set_user_mute_value = 0;
@@ -101,6 +101,7 @@ void ResetStubData() {
memset(&cras_observer_ops_are_empty_empty_ops, 0,
sizeof(cras_observer_ops_are_empty_empty_ops));
cras_observer_remove_called = 0;
+ cras_rstream_config_init_with_message_called = 0;
}
namespace {
@@ -160,7 +161,6 @@ class RClientMessagesSuite : public testing::Test {
connect_msg_.dev_idx = NO_DEVICE;
connect_msg_.client_shm_size = 0;
btlog = cras_bt_event_log_init();
- main_log = main_thread_event_log_init();
ResetStubData();
}
@@ -170,7 +170,6 @@ class RClientMessagesSuite : public testing::Test {
close(pipe_fds_[0]);
close(pipe_fds_[1]);
cras_bt_event_log_deinit(btlog);
- main_thread_event_log_deinit(main_log);
}
void RegisterNotification(enum CRAS_CLIENT_MESSAGE_ID msg_id,
@@ -195,15 +194,17 @@ TEST_F(RClientMessagesSuite, AudThreadAttachFail) {
fd_ = 100;
rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
&fd_, 1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
EXPECT_EQ(sizeof(out_msg), rc);
EXPECT_EQ(stream_id_, out_msg.stream_id);
EXPECT_NE(0, out_msg.err);
EXPECT_EQ(0, cras_iodev_list_rm_output_called);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
EXPECT_EQ(1, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(0, cras_server_metrics_stream_config_called);
}
TEST_F(RClientMessagesSuite, ConnectMsgWithBadFd) {
@@ -212,7 +213,7 @@ TEST_F(RClientMessagesSuite, ConnectMsgWithBadFd) {
rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
NULL, 0);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EBADF, rc);
rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
EXPECT_EQ(sizeof(out_msg), rc);
@@ -220,6 +221,33 @@ TEST_F(RClientMessagesSuite, ConnectMsgWithBadFd) {
EXPECT_NE(0, out_msg.err);
EXPECT_EQ(stream_list_add_stream_called,
stream_list_disconnect_stream_called);
+ EXPECT_EQ(0, cras_server_metrics_stream_config_called);
+}
+
+TEST_F(RClientMessagesSuite, ConnectMsgFromOldClient) {
+ struct cras_client_stream_connected out_msg;
+ int rc;
+
+ cras_rstream_create_stream_out = rstream_;
+ cras_iodev_attach_stream_retval = 0;
+
+ connect_msg_.header.length = sizeof(struct cras_connect_message_old);
+ connect_msg_.proto_version = 3;
+
+ fd_ = 100;
+ rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
+ &fd_, 1);
+ EXPECT_EQ(0, rc);
+ EXPECT_EQ(1, cras_make_fd_nonblocking_called);
+
+ rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
+ EXPECT_EQ(sizeof(out_msg), rc);
+ EXPECT_EQ(stream_id_, out_msg.stream_id);
+ EXPECT_EQ(0, out_msg.err);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
+ EXPECT_EQ(1, stream_list_add_stream_called);
+ EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(1, cras_server_metrics_stream_config_called);
}
TEST_F(RClientMessagesSuite, StreamConnectMessageValidDirection) {
@@ -245,8 +273,10 @@ TEST_F(RClientMessagesSuite, StreamConnectMessageValidDirection) {
EXPECT_EQ(sizeof(out_msg), rc);
EXPECT_EQ(stream_id_, out_msg.stream_id);
EXPECT_EQ(0, out_msg.err);
+ EXPECT_EQ(called, cras_rstream_config_init_with_message_called);
EXPECT_EQ(called, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(called, cras_server_metrics_stream_config_called);
}
}
@@ -261,7 +291,7 @@ TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidDirection) {
fd_ = 100;
rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
&fd_, 1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
@@ -270,6 +300,7 @@ TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidDirection) {
EXPECT_EQ(-EINVAL, out_msg.err);
EXPECT_EQ(0, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(0, cras_server_metrics_stream_config_called);
}
TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidClientId) {
@@ -281,8 +312,9 @@ TEST_F(RClientMessagesSuite, StreamConnectMessageInvalidClientId) {
fd_ = 100;
rc = rclient_->ops->handle_message_from_client(rclient_, &connect_msg_.header,
&fd_, 1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(0, cras_rstream_config_init_with_message_called);
EXPECT_EQ(0, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
@@ -309,8 +341,10 @@ TEST_F(RClientMessagesSuite, SuccessReply) {
EXPECT_EQ(sizeof(out_msg), rc);
EXPECT_EQ(stream_id_, out_msg.stream_id);
EXPECT_EQ(0, out_msg.err);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
EXPECT_EQ(1, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(1, cras_server_metrics_stream_config_called);
}
TEST_F(RClientMessagesSuite, SuccessCreateThreadReply) {
@@ -330,8 +364,10 @@ TEST_F(RClientMessagesSuite, SuccessCreateThreadReply) {
EXPECT_EQ(sizeof(out_msg), rc);
EXPECT_EQ(stream_id_, out_msg.stream_id);
EXPECT_EQ(0, out_msg.err);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
EXPECT_EQ(1, stream_list_add_stream_called);
EXPECT_EQ(0, stream_list_disconnect_stream_called);
+ EXPECT_EQ(1, cras_server_metrics_stream_config_called);
}
TEST_F(RClientMessagesSuite, SetVolume) {
@@ -349,6 +385,21 @@ TEST_F(RClientMessagesSuite, SetVolume) {
EXPECT_EQ(66, cras_system_set_volume_value);
}
+TEST_F(RClientMessagesSuite, SetCaptureVolume) {
+ struct cras_set_system_volume msg;
+ int rc;
+
+ msg.header.id = CRAS_SERVER_SET_SYSTEM_CAPTURE_GAIN;
+ msg.header.length = sizeof(msg);
+ msg.volume = 66;
+
+ rc =
+ rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
+ EXPECT_EQ(0, rc);
+ EXPECT_EQ(1, cras_system_set_capture_gain_called);
+ EXPECT_EQ(66, cras_system_set_capture_gain_value);
+}
+
TEST_F(RClientMessagesSuite, SetMute) {
struct cras_set_system_mute msg;
int rc;
@@ -418,23 +469,6 @@ TEST_F(RClientMessagesSuite, DumpSnapshots) {
EXPECT_EQ(1, cras_system_state_dump_snapshots_called);
}
-TEST_F(RClientMessagesSuite, ConfigGlobalRemix) {
- int rc;
- struct cras_config_global_remix msg;
- const int num_channels = 2;
- float coefficient[4] = {0.1, 0.2, 0.3, 0.4};
- cras_fill_config_global_remix_command(&msg, num_channels, coefficient,
- num_channels * num_channels);
-
- rc =
- rclient_->ops->handle_message_from_client(rclient_, &msg.header, NULL, 0);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(1, audio_thread_config_global_remix_called);
- for (unsigned i = 0; i < (unsigned)num_channels * num_channels; i++) {
- EXPECT_EQ(audio_thread_config_global_remix_copy[i], coefficient[i]);
- }
-}
-
void RClientMessagesSuite::RegisterNotification(
enum CRAS_CLIENT_MESSAGE_ID msg_id,
void* callback,
@@ -588,6 +622,21 @@ TEST_F(RClientMessagesSuite, SendOutputMuteChanged) {
EXPECT_EQ(msg->mute_locked, mute_locked);
}
+TEST_F(RClientMessagesSuite, SendCaptureGainChanged) {
+ void* void_client = reinterpret_cast<void*>(rclient_);
+ char buf[1024];
+ ssize_t rc;
+ struct cras_client_volume_changed* msg =
+ (struct cras_client_volume_changed*)buf;
+ const int32_t gain = 90;
+
+ send_capture_gain_changed(void_client, gain);
+ rc = read(pipe_fds_[0], buf, sizeof(buf));
+ ASSERT_EQ(rc, (ssize_t)sizeof(*msg));
+ EXPECT_EQ(msg->header.id, CRAS_CLIENT_CAPTURE_GAIN_CHANGED);
+ EXPECT_EQ(msg->volume, gain);
+}
+
TEST_F(RClientMessagesSuite, SendCaptureMuteChanged) {
void* void_client = reinterpret_cast<void*>(rclient_);
char buf[1024];
@@ -713,7 +762,6 @@ int main(int argc, char** argv) {
extern "C" {
struct cras_bt_event_log* btlog;
-struct main_thread_event_log* main_log;
struct audio_thread* cras_iodev_list_get_audio_thread() {
return iodev_get_thread_return;
@@ -748,9 +796,6 @@ int audio_thread_resume(struct audio_thread* thread) {
int audio_thread_config_global_remix(struct audio_thread* thread,
unsigned int num_channels,
const float* coefficient) {
- audio_thread_config_global_remix_called++;
- memcpy(audio_thread_config_global_remix_copy, coefficient,
- num_channels * num_channels * sizeof(coefficient));
return 0;
}
@@ -817,6 +862,11 @@ void cras_system_set_volume(size_t volume) {
cras_system_set_volume_called++;
}
+void cras_system_set_capture_gain(long gain) {
+ cras_system_set_capture_gain_value = gain;
+ cras_system_set_capture_gain_called++;
+}
+
// From system_state.
void cras_system_set_mute(int mute) {
cras_system_set_mute_value = mute;
@@ -887,16 +937,16 @@ int stream_list_add(struct stream_list* list,
struct cras_rstream** stream) {
int ret;
- *stream = &mock_rstream;
+ *stream = &dummy_rstream;
stream_list_add_stream_called++;
ret = stream_list_add_stream_return;
if (ret)
stream_list_add_stream_return = -EINVAL;
- mock_rstream.shm = &mock_shm;
- mock_rstream.direction = config->direction;
- mock_rstream.stream_id = config->stream_id;
+ dummy_rstream.shm = &dummy_shm;
+ dummy_rstream.direction = config->direction;
+ dummy_rstream.stream_id = config->stream_id;
return ret;
}
@@ -959,19 +1009,21 @@ void cras_observer_remove(struct cras_observer_client* client) {
cras_observer_remove_called++;
}
-bool cras_audio_format_valid(const struct cras_audio_format* fmt) {
- return true;
-}
-
-struct packet_status_logger* cras_hfp_ag_get_wbs_logger() {
- return NULL;
+int cras_server_metrics_stream_config(struct cras_rstream_config* config) {
+ cras_server_metrics_stream_config_called++;
+ return 0;
}
-void detect_rtc_stream_pair(struct stream_list* list,
- struct cras_rstream* stream) {
- return;
+void cras_rstream_config_init_with_message(
+ struct cras_rclient* client,
+ const struct cras_connect_message* msg,
+ int* aud_fd,
+ int* client_shm_fd,
+ const struct cras_audio_format* remote_fmt,
+ struct cras_rstream_config* stream_config) {
+ cras_rstream_config_init_with_message_called++;
}
-void cras_system_set_hotword_pause_at_suspend(bool pause) {}
+void cras_rstream_config_cleanup(struct cras_rstream_config* stream_config) {}
} // extern "C"
diff --git a/cras/src/tests/cras_abi_unittest.cc b/cras/src/tests/cras_abi_unittest.cc
deleted file mode 100644
index d566a9b7..00000000
--- a/cras/src/tests/cras_abi_unittest.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include <gtest/gtest.h>
-
-extern "C" {
-#include "cras_client.c"
-#include "cras_client.h"
-
-inline int libcras_unsupported_func(struct libcras_client* client) {
- CHECK_VERSION(client, INT_MAX);
- return 0;
-}
-
-cras_stream_id_t cb_stream_id;
-uint8_t* cb_buf;
-unsigned int cb_frames;
-struct timespec cb_latency;
-void* cb_usr_arg;
-int get_stream_cb_called;
-struct timespec now;
-
-int get_stream_cb(struct libcras_stream_cb_data* data) {
- get_stream_cb_called++;
- EXPECT_NE((void*)NULL, data);
- EXPECT_EQ(0, libcras_stream_cb_data_get_stream_id(data, &cb_stream_id));
- EXPECT_EQ(0, libcras_stream_cb_data_get_buf(data, &cb_buf));
- EXPECT_EQ(0, libcras_stream_cb_data_get_frames(data, &cb_frames));
- EXPECT_EQ(0, libcras_stream_cb_data_get_latency(data, &cb_latency));
- EXPECT_EQ(0, libcras_stream_cb_data_get_usr_arg(data, &cb_usr_arg));
- return 0;
-}
-}
-
-namespace {
-class CrasAbiTestSuite : public testing::Test {
- protected:
- struct cras_audio_shm* InitShm(int frames) {
- struct cras_audio_shm* shm =
- static_cast<struct cras_audio_shm*>(calloc(1, sizeof(*shm)));
- shm->header =
- static_cast<cras_audio_shm_header*>(calloc(1, sizeof(*shm->header)));
- cras_shm_set_frame_bytes(shm, 4);
- uint32_t used_size = frames * 4;
- cras_shm_set_used_size(shm, used_size);
- shm->samples_info.length = used_size * 2;
- memcpy(&shm->header->config, &shm->config, sizeof(shm->config));
- return shm;
- }
-
- void DestroyShm(struct cras_audio_shm* shm) {
- if (shm)
- free(shm->header);
- free(shm);
- }
-
- virtual void SetUp() { get_stream_cb_called = 0; }
-};
-
-TEST_F(CrasAbiTestSuite, CheckUnsupportedFunction) {
- auto* client = libcras_client_create();
- EXPECT_NE((void*)NULL, client);
- EXPECT_EQ(-ENOSYS, libcras_unsupported_func(client));
- libcras_client_destroy(client);
-}
-
-TEST_F(CrasAbiTestSuite, BasicStream) {
- auto* client = libcras_client_create();
- EXPECT_NE((void*)NULL, client);
- auto* stream = libcras_stream_params_create();
- EXPECT_NE((void*)NULL, stream);
- /* Returns timeout because there is no real CRAS server in unittest. */
- EXPECT_EQ(-ETIMEDOUT, libcras_client_connect_timeout(client, 0));
- EXPECT_EQ(0, libcras_client_run_thread(client));
- EXPECT_EQ(0, libcras_stream_params_set(stream, CRAS_STREAM_INPUT, 480, 480,
- CRAS_STREAM_TYPE_DEFAULT,
- CRAS_CLIENT_TYPE_TEST, 0, NULL, NULL,
- NULL, 48000, SND_PCM_FORMAT_S16, 2));
- cras_stream_id_t id;
- /* Fails to add a stream because the stream callback is not set. */
- EXPECT_EQ(-EINVAL, libcras_client_add_pinned_stream(client, 0, &id, stream));
- /* Fails to set a stream volume because the stream is not added. */
- EXPECT_EQ(-EINVAL, libcras_client_set_stream_volume(client, id, 1.0));
- EXPECT_EQ(0, libcras_client_rm_stream(client, id));
- EXPECT_EQ(0, libcras_client_stop(client));
- libcras_stream_params_destroy(stream);
- libcras_client_destroy(client);
-}
-
-TEST_F(CrasAbiTestSuite, StreamCallback) {
- struct client_stream stream;
- struct cras_stream_params params;
- stream.id = 0x123;
- stream.direction = CRAS_STREAM_INPUT;
- stream.flags = 0;
- stream.config = &params;
- params.stream_cb = get_stream_cb;
- params.cb_threshold = 480;
- params.user_data = (void*)0x321;
- stream.shm = InitShm(960);
- stream.shm->header->write_offset[0] = 960 * 4;
- stream.shm->header->write_buf_idx = 0;
- stream.shm->header->read_offset[0] = 0;
- stream.shm->header->read_buf_idx = 0;
- now.tv_sec = 100;
- now.tv_nsec = 0;
- stream.shm->header->ts.tv_sec = 90;
- stream.shm->header->ts.tv_nsec = 0;
-
- handle_capture_data_ready(&stream, 480);
-
- EXPECT_EQ(1, get_stream_cb_called);
- EXPECT_EQ(stream.id, cb_stream_id);
- EXPECT_EQ(cras_shm_get_write_buffer_base(stream.shm), cb_buf);
- EXPECT_EQ(480, cb_frames);
- EXPECT_EQ(10, cb_latency.tv_sec);
- EXPECT_EQ(0, cb_latency.tv_nsec);
- EXPECT_EQ((void*)0x321, cb_usr_arg);
-
- DestroyShm(stream.shm);
-}
-
-} // namespace
-
-extern "C" {
-
-int clock_gettime(clockid_t clk_id, struct timespec* tp) {
- *tp = now;
- return 0;
-}
-}
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- openlog(NULL, LOG_PERROR, LOG_USER);
- return RUN_ALL_TESTS();
-}
diff --git a/cras/src/tests/dev_io_stubs.cc b/cras/src/tests/dev_io_stubs.cc
index d97dde50..b74162b8 100644
--- a/cras/src/tests/dev_io_stubs.cc
+++ b/cras/src/tests/dev_io_stubs.cc
@@ -151,11 +151,6 @@ void add_stream_to_dev(IodevPtr& dev, const StreamPtr& stream) {
static_cast<size_t>(dev->max_cb_level));
dev->largest_cb_level = std::max(stream->rstream->cb_threshold,
static_cast<size_t>(dev->max_cb_level));
-
- if (stream->rstream->main_dev.dev_id == NO_DEVICE) {
- stream->rstream->main_dev.dev_id = dev->info.idx;
- stream->rstream->main_dev.dev_ptr = dev.get();
- }
}
void fill_audio_format(cras_audio_format* format, unsigned int rate) {
diff --git a/cras/src/tests/dev_io_unittest.cc b/cras/src/tests/dev_io_unittest.cc
index 2dbf344e..a18dd48a 100644
--- a/cras/src/tests/dev_io_unittest.cc
+++ b/cras/src/tests/dev_io_unittest.cc
@@ -8,7 +8,6 @@
#include <time.h>
#include <memory>
-#include <unordered_map>
extern "C" {
#include "cras_iodev.h" // stubbed
@@ -28,15 +27,7 @@ struct audio_thread_event_log* atlog;
#include "rstream_stub.h"
static float dev_stream_capture_software_gain_scaler_val;
-static float input_data_get_software_gain_scaler_val;
static unsigned int dev_stream_capture_avail_ret = 480;
-struct set_dev_rate_data {
- unsigned int dev_rate;
- double dev_rate_ratio;
- double main_rate_ratio;
- int coarse_rate_adjust;
-};
-std::unordered_map<struct dev_stream*, set_dev_rate_data> set_dev_rate_map;
namespace {
@@ -47,7 +38,6 @@ class DevIoSuite : public testing::Test {
iodev_stub_reset();
rstream_stub_reset();
fill_audio_format(&format, 48000);
- set_dev_rate_map.clear();
stream = create_stream(1, 1, CRAS_STREAM_INPUT, cb_threshold, &format);
}
@@ -79,90 +69,25 @@ TEST_F(DevIoSuite, SendCapturedFails) {
TEST_F(DevIoSuite, CaptureGain) {
struct open_dev* dev_list = NULL;
- struct open_dev* odev_list = NULL;
struct timespec ts;
DevicePtr dev = create_device(CRAS_STREAM_INPUT, cb_threshold, &format,
CRAS_NODE_TYPE_MIC);
dev->dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
+ dev->dev->software_gain_scaler = 0.99f;
iodev_stub_frames_queued(dev->dev.get(), 20, ts);
DL_APPEND(dev_list, dev->odev.get());
add_stream_to_dev(dev->dev, stream);
- /* The applied scaler gain should match what is reported by input_data. */
- dev->dev->active_node->ui_gain_scaler = 1.0f;
- input_data_get_software_gain_scaler_val = 1.0f;
- dev_io_capture(&dev_list, &odev_list);
+ /* For stream that uses APM, always apply gain scaler 1.0f regardless of
+ * what node/stream gains are. */
+ stream->rstream->apm_list = reinterpret_cast<struct cras_apm_list*>(0xf0f);
+ dev_io_capture(&dev_list);
EXPECT_EQ(1.0f, dev_stream_capture_software_gain_scaler_val);
- input_data_get_software_gain_scaler_val = 0.99f;
- dev_io_capture(&dev_list, &odev_list);
+ stream->rstream->apm_list = 0x0;
+ dev_io_capture(&dev_list);
EXPECT_EQ(0.99f, dev_stream_capture_software_gain_scaler_val);
-
- dev->dev->active_node->ui_gain_scaler = 0.6f;
- input_data_get_software_gain_scaler_val = 0.7f;
- dev_io_capture(&dev_list, &odev_list);
- EXPECT_FLOAT_EQ(0.42f, dev_stream_capture_software_gain_scaler_val);
-}
-
-/*
- * When input and output devices are on the internal sound card,
- * and their device rates are the same, use the estimated rate
- * on the output device as the estimated rate of input device.
- */
-TEST_F(DevIoSuite, CopyOutputEstimatedRate) {
- struct open_dev* idev_list = NULL;
- struct open_dev* odev_list = NULL;
- struct timespec ts;
- DevicePtr out_dev = create_device(CRAS_STREAM_OUTPUT, cb_threshold, &format,
- CRAS_NODE_TYPE_INTERNAL_SPEAKER);
- DevicePtr in_dev = create_device(CRAS_STREAM_INPUT, cb_threshold, &format,
- CRAS_NODE_TYPE_MIC);
-
- in_dev->dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
- iodev_stub_frames_queued(in_dev->dev.get(), 20, ts);
- DL_APPEND(idev_list, in_dev->odev.get());
- add_stream_to_dev(in_dev->dev, stream);
- DL_APPEND(odev_list, out_dev->odev.get());
- iodev_stub_on_internal_card(out_dev->dev->active_node, 1);
- iodev_stub_on_internal_card(in_dev->dev->active_node, 1);
-
- iodev_stub_est_rate_ratio(in_dev->dev.get(), 0.8f);
- iodev_stub_est_rate_ratio(out_dev->dev.get(), 1.2f);
-
- dev_io_capture(&idev_list, &odev_list);
-
- EXPECT_FLOAT_EQ(1.2f, set_dev_rate_map[stream->dstream.get()].dev_rate_ratio);
-}
-
-/*
- * When input and output devices are not both on the internal sound card,
- * estimated rates are independent.
- */
-TEST_F(DevIoSuite, InputOutputIndependentEstimatedRate) {
- struct open_dev* idev_list = NULL;
- struct open_dev* odev_list = NULL;
- struct timespec ts;
- DevicePtr out_dev = create_device(CRAS_STREAM_OUTPUT, cb_threshold, &format,
- CRAS_NODE_TYPE_INTERNAL_SPEAKER);
- DevicePtr in_dev = create_device(CRAS_STREAM_INPUT, cb_threshold, &format,
- CRAS_NODE_TYPE_USB);
-
- in_dev->dev->state = CRAS_IODEV_STATE_NORMAL_RUN;
- iodev_stub_frames_queued(in_dev->dev.get(), 20, ts);
- DL_APPEND(idev_list, in_dev->odev.get());
- add_stream_to_dev(in_dev->dev, stream);
- DL_APPEND(odev_list, out_dev->odev.get());
- iodev_stub_on_internal_card(out_dev->dev->active_node, 1);
- iodev_stub_on_internal_card(in_dev->dev->active_node, 0);
-
- iodev_stub_est_rate_ratio(in_dev->dev.get(), 0.8f);
- iodev_stub_est_rate_ratio(out_dev->dev.get(), 1.2f);
- iodev_stub_update_rate(in_dev->dev.get(), 1);
-
- dev_io_capture(&idev_list, &odev_list);
-
- EXPECT_FLOAT_EQ(0.8f, set_dev_rate_map[stream->dstream.get()].dev_rate_ratio);
}
/*
@@ -207,49 +132,6 @@ TEST_F(DevIoSuite, SendCapturedNeedToResetDevices) {
}
/*
- * If any hw_level is larger than 0.5 * buffer_size and
- * DROP_FRAMES_THRESHOLD_MS, reset all input devices.
- */
-
-TEST_F(DevIoSuite, SendCapturedNeedToResetDevices2) {
- struct timespec start;
- struct timespec drop_time;
- struct open_dev* dev_list = NULL;
- bool rc;
-
- stream = create_stream(1, 1, CRAS_STREAM_INPUT, 2000, &format);
-
- clock_gettime(CLOCK_MONOTONIC_RAW, &start);
- AddFakeDataToStream(stream.get(), 0);
-
- DevicePtr dev1 =
- create_device(CRAS_STREAM_INPUT, 2048, &format, CRAS_NODE_TYPE_MIC);
- DevicePtr dev2 =
- create_device(CRAS_STREAM_INPUT, 10000, &format, CRAS_NODE_TYPE_MIC);
- DL_APPEND(dev_list, dev1->odev.get());
- DL_APPEND(dev_list, dev2->odev.get());
- add_stream_to_dev(dev1->dev, stream);
- add_stream_to_dev(dev2->dev, stream);
-
- iodev_stub_frames_queued(dev1->dev.get(), 2480, start);
- iodev_stub_frames_queued(dev2->dev.get(), 2480, start);
- EXPECT_EQ(0, dev_io_send_captured_samples(dev_list));
-
- /*
- * Should drop frames to one min_cb_level, which is 2480 - 2000 = 480 (10ms).
- */
- rc = iodev_stub_get_drop_time(dev1->dev.get(), &drop_time);
- EXPECT_EQ(true, rc);
- EXPECT_EQ(0, drop_time.tv_sec);
- EXPECT_EQ(10000000, drop_time.tv_nsec);
-
- rc = iodev_stub_get_drop_time(dev2->dev.get(), &drop_time);
- EXPECT_EQ(true, rc);
- EXPECT_EQ(0, drop_time.tv_sec);
- EXPECT_EQ(10000000, drop_time.tv_nsec);
-}
-
-/*
* If the hw_level is larger than 1.5 * largest_cb_level but less than
* DROP_FRAMES_THRESHOLD_MS, do nothing.
*/
@@ -274,10 +156,7 @@ TEST_F(DevIoSuite, SendCapturedLevelLessThanThreshold) {
EXPECT_EQ(false, rc);
}
-/*
- * If all hw_level is less than 1.5 * largest_cb_level and 0.5 * buffer_size,
- * do nothing.
- */
+/* If all hw_level is less than 1.5 * largest_cb_level, do nothing. */
TEST_F(DevIoSuite, SendCapturedNoNeedToResetDevices) {
struct timespec start;
struct timespec drop_time;
@@ -307,50 +186,6 @@ TEST_F(DevIoSuite, SendCapturedNoNeedToResetDevices) {
EXPECT_EQ(false, rc);
}
-/*
- * On loopback and hotword devices, if any hw_level is larger than
- * 1.5 * largest_cb_level and DROP_FRAMES_THRESHOLD_MS, do nothing.
- */
-TEST_F(DevIoSuite, SendCapturedNoNeedToDrop) {
- struct timespec start;
- struct timespec drop_time;
- struct open_dev* dev_list = NULL;
- bool rc;
-
- clock_gettime(CLOCK_MONOTONIC_RAW, &start);
- AddFakeDataToStream(stream.get(), 0);
-
- DevicePtr dev1 =
- create_device(CRAS_STREAM_INPUT, 480, &format, CRAS_NODE_TYPE_HOTWORD);
- DevicePtr dev2 = create_device(CRAS_STREAM_INPUT, 480, &format,
- CRAS_NODE_TYPE_POST_MIX_PRE_DSP);
- DevicePtr dev3 =
- create_device(CRAS_STREAM_INPUT, 480, &format, CRAS_NODE_TYPE_POST_DSP);
-
- DL_APPEND(dev_list, dev1->odev.get());
- DL_APPEND(dev_list, dev2->odev.get());
- DL_APPEND(dev_list, dev3->odev.get());
-
- add_stream_to_dev(dev1->dev, stream);
- add_stream_to_dev(dev2->dev, stream);
- add_stream_to_dev(dev3->dev, stream);
-
- iodev_stub_frames_queued(dev1->dev.get(), 4800, start);
- iodev_stub_frames_queued(dev2->dev.get(), 4800, start);
- iodev_stub_frames_queued(dev2->dev.get(), 4800, start);
-
- EXPECT_EQ(0, dev_io_send_captured_samples(dev_list));
-
- rc = iodev_stub_get_drop_time(dev1->dev.get(), &drop_time);
- EXPECT_EQ(false, rc);
-
- rc = iodev_stub_get_drop_time(dev2->dev.get(), &drop_time);
- EXPECT_EQ(false, rc);
-
- rc = iodev_stub_get_drop_time(dev3->dev.get(), &drop_time);
- EXPECT_EQ(false, rc);
-}
-
/* Stubs */
extern "C" {
@@ -369,20 +204,10 @@ int input_data_put_for_stream(struct input_data* data,
return 0;
}
-float input_data_get_software_gain_scaler(struct input_data* data,
- float idev_sw_gain_scaler,
- struct cras_rstream* stream) {
- return input_data_get_software_gain_scaler_val;
-}
-
int cras_audio_thread_event_drop_samples() {
return 0;
}
-int cras_audio_thread_event_severe_underrun() {
- return 0;
-}
-
int dev_stream_attached_devs(const struct dev_stream* dev_stream) {
return 0;
}
@@ -402,16 +227,8 @@ int dev_stream_mix(struct dev_stream* dev_stream,
void dev_stream_set_dev_rate(struct dev_stream* dev_stream,
unsigned int dev_rate,
double dev_rate_ratio,
- double main_rate_ratio,
- int coarse_rate_adjust) {
- set_dev_rate_data new_data;
- new_data.dev_rate = dev_rate;
- new_data.dev_rate_ratio = dev_rate_ratio;
- new_data.main_rate_ratio = main_rate_ratio;
- new_data.coarse_rate_adjust = coarse_rate_adjust;
-
- set_dev_rate_map[dev_stream] = new_data;
-}
+ double master_rate_ratio,
+ int coarse_rate_adjust) {}
int dev_stream_capture_update_rstream(struct dev_stream* dev_stream) {
return 0;
}
@@ -451,11 +268,7 @@ struct dev_stream* dev_stream_create(struct cras_rstream* stream,
unsigned int dev_id,
const struct cras_audio_format* dev_fmt,
void* dev_ptr,
- struct timespec* cb_ts,
- const struct timespec* sleep_interval_ts) {
- return 0;
-}
-int cras_device_monitor_error_close(unsigned int dev_idx) {
+ struct timespec* cb_ts) {
return 0;
}
} // extern "C"
diff --git a/cras/src/tests/dev_stream_unittest.cc b/cras/src/tests/dev_stream_unittest.cc
index 700376fb..39c16e48 100644
--- a/cras/src/tests/dev_stream_unittest.cc
+++ b/cras/src/tests/dev_stream_unittest.cc
@@ -334,36 +334,18 @@ TEST_F(CreateSuite, CreateSRC44to48) {
out_fmt.frame_rate = 48000; // Output from converter is device rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for device output.
unsigned int device_frames =
cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames, out_fmt.frame_rate);
- EXPECT_LE(kBufferFrames, device_frames); // Soundness check.
+ EXPECT_LE(kBufferFrames, device_frames); // Sanity check.
EXPECT_LE(device_frames, config_format_converter_frames);
EXPECT_LE(device_frames, dev_stream->conv_buffer_size_frames);
dev_stream_destroy(dev_stream);
}
-TEST_F(CreateSuite, CreateOutputWithSchedule) {
- struct dev_stream* dev_stream;
- unsigned int dev_id = 9;
- // init_cb_ts and non-null init_sleep_ts will be used.
- struct timespec init_cb_ts = {1, 2};
- struct timespec init_sleep_ts = {3, 4};
-
- rstream_.direction = CRAS_STREAM_OUTPUT;
- dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_48, (void*)0x55,
- &init_cb_ts, &init_sleep_ts);
-
- EXPECT_EQ(init_cb_ts.tv_sec, rstream_.next_cb_ts.tv_sec);
- EXPECT_EQ(init_cb_ts.tv_nsec, rstream_.next_cb_ts.tv_nsec);
- EXPECT_EQ(init_sleep_ts.tv_sec, rstream_.sleep_interval_ts.tv_sec);
- EXPECT_EQ(init_sleep_ts.tv_nsec, rstream_.sleep_interval_ts.tv_nsec);
- dev_stream_destroy(dev_stream);
-}
-
TEST_F(CreateSuite, CreateSRC44from48Input) {
struct dev_stream* dev_stream;
struct cras_audio_format processed_fmt = fmt_s16le_48;
@@ -376,13 +358,13 @@ TEST_F(CreateSuite, CreateSRC44from48Input) {
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
cras_rstream_post_processing_format_val = &processed_fmt;
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for device input.
unsigned int device_frames =
cras_frames_at_rate(out_fmt.frame_rate, kBufferFrames, in_fmt.frame_rate);
- EXPECT_LE(kBufferFrames, device_frames); // Soundness check.
+ EXPECT_LE(kBufferFrames, device_frames); // Sanity check.
EXPECT_LE(device_frames, config_format_converter_frames);
EXPECT_EQ(&processed_fmt, config_format_converter_from_fmt);
EXPECT_LE(device_frames, dev_stream->conv_buffer_size_frames);
@@ -396,8 +378,8 @@ TEST_F(CreateSuite, CreateSRC48to44) {
in_fmt.frame_rate = 48000; // Stream rate.
out_fmt.frame_rate = 44100; // Device rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
- dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55,
- &cb_ts, NULL);
+ dev_stream =
+ dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for stream input.
@@ -414,8 +396,8 @@ TEST_F(CreateSuite, CreateSRC48from44Input) {
in_fmt.frame_rate = 44100; // Device rate.
out_fmt.frame_rate = 48000; // Stream rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
- dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55,
- &cb_ts, NULL);
+ dev_stream =
+ dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for stream output.
@@ -432,13 +414,13 @@ TEST_F(CreateSuite, CreateSRC8to48) {
out_fmt.frame_rate = 48000; // Device rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for device output.
unsigned int device_frames =
cras_frames_at_rate(in_fmt.frame_rate, kBufferFrames, out_fmt.frame_rate);
- EXPECT_LE(kBufferFrames, device_frames); // Soundness check.
+ EXPECT_LE(kBufferFrames, device_frames); // Sanity check.
EXPECT_LE(device_frames, config_format_converter_frames);
EXPECT_LE(device_frames, dev_stream->conv_buffer_size_frames);
dev_stream_destroy(dev_stream);
@@ -453,13 +435,13 @@ TEST_F(CreateSuite, CreateSRC8from48Input) {
out_fmt.frame_rate = 8000; // Stream rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_48, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for device input.
unsigned int device_frames =
cras_frames_at_rate(out_fmt.frame_rate, kBufferFrames, in_fmt.frame_rate);
- EXPECT_LE(kBufferFrames, device_frames); // Soundness check.
+ EXPECT_LE(kBufferFrames, device_frames); // Sanity check.
EXPECT_LE(device_frames, config_format_converter_frames);
EXPECT_LE(device_frames, dev_stream->conv_buffer_size_frames);
dev_stream_destroy(dev_stream);
@@ -473,7 +455,7 @@ TEST_F(CreateSuite, CreateSRC48to8) {
out_fmt.frame_rate = 8000; // Device rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_8, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_8, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for stream input.
@@ -491,7 +473,7 @@ TEST_F(CreateSuite, CreateSRC48from8Input) {
out_fmt.frame_rate = 48000; // Stream rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream =
- dev_stream_create(&rstream_, 0, &fmt_s16le_8, (void*)0x55, &cb_ts, NULL);
+ dev_stream_create(&rstream_, 0, &fmt_s16le_8, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for stream output.
@@ -508,8 +490,8 @@ TEST_F(CreateSuite, CreateSRC48MonoFrom44StereoInput) {
in_fmt.frame_rate = 44100; // Device rate.
out_fmt.frame_rate = 48000; // Stream rate.
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
- dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55,
- &cb_ts, NULL);
+ dev_stream =
+ dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
// Converter tmp and output buffers are large enough for stream output.
@@ -528,8 +510,8 @@ TEST_F(CreateSuite, CaptureAvailConvBufHasSamples) {
rstream_.format = fmt_s16le_48;
rstream_.direction = CRAS_STREAM_INPUT;
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
- dev_stream = dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55,
- &cb_ts, NULL);
+ dev_stream =
+ dev_stream_create(&rstream_, 0, &fmt_s16le_44_1, (void*)0x55, &cb_ts);
EXPECT_EQ(1, config_format_converter_called);
EXPECT_NE(static_cast<byte_buffer*>(NULL), dev_stream->conv_buffer);
EXPECT_LE(
@@ -547,16 +529,16 @@ TEST_F(CreateSuite, CaptureAvailConvBufHasSamples) {
dev_stream_destroy(dev_stream);
}
-TEST_F(CreateSuite, SetDevRateNotMainDev) {
+TEST_F(CreateSuite, SetDevRateNotMasterDev) {
struct dev_stream* dev_stream;
unsigned int dev_id = 9;
rstream_.format = fmt_s16le_48;
rstream_.direction = CRAS_STREAM_INPUT;
- rstream_.main_dev.dev_id = 4;
+ rstream_.master_dev.dev_id = 4;
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 0);
EXPECT_EQ(1, cras_fmt_conv_set_linear_resample_rates_called);
@@ -575,17 +557,17 @@ TEST_F(CreateSuite, SetDevRateNotMainDev) {
dev_stream_destroy(dev_stream);
}
-TEST_F(CreateSuite, SetDevRateMainDev) {
+TEST_F(CreateSuite, SetDevRateMasterDev) {
struct dev_stream* dev_stream;
unsigned int dev_id = 9;
unsigned int expected_ts_nsec;
rstream_.format = fmt_s16le_48;
rstream_.direction = CRAS_STREAM_INPUT;
- rstream_.main_dev.dev_id = dev_id;
+ rstream_.master_dev.dev_id = dev_id;
config_format_converter_conv = reinterpret_cast<struct cras_fmt_conv*>(0x33);
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
dev_stream_set_dev_rate(dev_stream, 44100, 1.01, 1.0, 0);
EXPECT_EQ(1, cras_fmt_conv_set_linear_resample_rates_called);
@@ -679,7 +661,7 @@ TEST_F(CreateSuite, DevStreamFlushAudioMessages) {
unsigned int dev_id = 9;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
dev_stream_flush_old_audio_messages(dev_stream);
EXPECT_EQ(1, cras_rstream_flush_old_audio_messages_called);
@@ -691,7 +673,7 @@ TEST_F(CreateSuite, DevStreamIsPending) {
unsigned int dev_id = 9;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
// dev_stream_is_pending_reply is only a wrapper.
cras_rstream_is_pending_reply_ret = 0;
@@ -712,7 +694,7 @@ TEST_F(CreateSuite, StreamCanSend) {
rstream_.direction = CRAS_STREAM_INPUT;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
// Assume there is a next_cb_ts on rstream.
rstream_.next_cb_ts.tv_sec = 1;
@@ -809,7 +791,7 @@ TEST_F(CreateSuite, StreamCanSendBulkAudio) {
rstream_.direction = CRAS_STREAM_INPUT;
rstream_.flags |= BULK_AUDIO_OK;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
// Assume there is a next_cb_ts on rstream.
rstream_.next_cb_ts.tv_sec = 1;
@@ -882,7 +864,7 @@ TEST_F(CreateSuite, TriggerOnlyStreamSendOnlyOnce) {
rstream_.direction = CRAS_STREAM_INPUT;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
dev_stream->stream->flags = TRIGGER_ONLY;
dev_stream->stream->triggered = 0;
@@ -914,7 +896,7 @@ TEST_F(CreateSuite, InputDevStreamWakeTimeByNextCbTs) {
rstream_.direction = CRAS_STREAM_INPUT;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
// Assume there is a next_cb_ts on rstream.
rstream_.next_cb_ts.tv_sec = 1;
@@ -947,8 +929,8 @@ TEST_F(CreateSuite, InputDevStreamWakeTimeByDevice) {
int needed_frames_from_device = 0;
rstream_.direction = CRAS_STREAM_INPUT;
- dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_48, (void*)0x55,
- &cb_ts, NULL);
+ dev_stream =
+ dev_stream_create(&rstream_, dev_id, &fmt_s16le_48, (void*)0x55, &cb_ts);
// Assume there is a next_cb_ts on rstream, that is, 1.005 seconds.
rstream_.next_cb_ts.tv_sec = 1;
@@ -1012,7 +994,7 @@ TEST_F(CreateSuite, UpdateNextWakeTime) {
rstream_.direction = CRAS_STREAM_OUTPUT;
dev_stream = dev_stream_create(&rstream_, dev_id, &fmt_s16le_44_1,
- (void*)0x55, &cb_ts, NULL);
+ (void*)0x55, &cb_ts);
// Case 1: The new next_cb_ts is greater than now. Do not need to reschedule.
rstream_.next_cb_ts.tv_sec = 2;
@@ -1188,11 +1170,6 @@ struct cras_audio_format* cras_rstream_post_processing_format(
void* dev_ptr) {
return cras_rstream_post_processing_format_val;
}
-void* buffer_share_get_data(const struct buffer_share* mix, unsigned int id) {
- return NULL;
-};
-void cras_apm_list_start_apm(struct cras_apm_list* list, void* dev_ptr){};
-void cras_apm_list_stop_apm(struct cras_apm_list* list, void* dev_ptr){};
int config_format_converter(struct cras_fmt_conv** conv,
enum CRAS_STREAM_DIRECTION dir,
@@ -1314,7 +1291,7 @@ int cras_rstream_flush_old_audio_messages(struct cras_rstream* stream) {
return 0;
}
-int cras_server_metrics_missed_cb_event(struct cras_rstream* stream) {
+int cras_server_metrics_missed_cb_event(const struct cras_rstream* stream) {
cras_server_metrics_missed_cb_event_called++;
return 0;
}
diff --git a/cras/src/tests/device_blacklist_unittest.cc b/cras/src/tests/device_blacklist_unittest.cc
new file mode 100644
index 00000000..2c1edf06
--- /dev/null
+++ b/cras/src/tests/device_blacklist_unittest.cc
@@ -0,0 +1,88 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <gtest/gtest.h>
+#include <stdio.h>
+
+extern "C" {
+#include "cras_device_blacklist.h"
+}
+
+namespace {
+
+static const char CONFIG_PATH[] = CRAS_UT_TMPDIR;
+static const char CONFIG_FILENAME[] = "device_blacklist";
+
+void CreateConfigFile(const char* config_text) {
+ FILE* f;
+ char card_path[128];
+
+ snprintf(card_path, sizeof(card_path), "%s/%s", CONFIG_PATH, CONFIG_FILENAME);
+ f = fopen(card_path, "w");
+ if (f == NULL)
+ return;
+
+ fprintf(f, "%s", config_text);
+
+ fclose(f);
+}
+
+TEST(Blacklist, EmptyBlacklist) {
+ static const char empty_config_text[] = "";
+ struct cras_device_blacklist* blacklist;
+
+ CreateConfigFile(empty_config_text);
+
+ blacklist = cras_device_blacklist_create(CONFIG_PATH);
+ ASSERT_NE(static_cast<cras_device_blacklist*>(NULL), blacklist);
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0, 0));
+
+ cras_device_blacklist_destroy(blacklist);
+}
+
+TEST(Blacklist, BlackListOneUsbOutput) {
+ static const char usb_output_config_text[] =
+ "[USB_Outputs]\n"
+ "0d8c_0008_00000012_0 = 1\n";
+ struct cras_device_blacklist* blacklist;
+
+ CreateConfigFile(usb_output_config_text);
+
+ blacklist = cras_device_blacklist_create(CONFIG_PATH);
+ ASSERT_NE(static_cast<cras_device_blacklist*>(NULL), blacklist);
+
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8d, 0x0008, 0x12, 0));
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0009, 0x12, 0));
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0x13, 0));
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0x12, 1));
+ EXPECT_EQ(1, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0x12, 0));
+
+ cras_device_blacklist_destroy(blacklist);
+}
+
+TEST(Blacklist, BlackListTwoUsbOutput) {
+ static const char usb_output_config_text[] =
+ "[USB_Outputs]\n"
+ "0d8c_0008_00000000_0 = 1\n"
+ "0d8c_0009_00000000_0 = 1\n";
+ struct cras_device_blacklist* blacklist;
+
+ CreateConfigFile(usb_output_config_text);
+
+ blacklist = cras_device_blacklist_create(CONFIG_PATH);
+ ASSERT_NE(static_cast<cras_device_blacklist*>(NULL), blacklist);
+
+ EXPECT_EQ(1, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0009, 0, 0));
+ EXPECT_EQ(1, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0, 0));
+ EXPECT_EQ(0, cras_device_blacklist_check(blacklist, 0x0d8c, 0x0008, 0, 1));
+
+ cras_device_blacklist_destroy(blacklist);
+}
+
+} // namespace
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/cras/src/tests/device_blocklist_unittest.cc b/cras/src/tests/device_blocklist_unittest.cc
deleted file mode 100644
index 44a976e1..00000000
--- a/cras/src/tests/device_blocklist_unittest.cc
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <gtest/gtest.h>
-#include <stdio.h>
-
-extern "C" {
-#include "cras_device_blocklist.h"
-}
-
-namespace {
-
-static const char CONFIG_PATH[] = CRAS_UT_TMPDIR;
-static const char CONFIG_FILENAME[] = "device_blocklist";
-
-void CreateConfigFile(const char* config_text) {
- FILE* f;
- char card_path[128];
-
- snprintf(card_path, sizeof(card_path), "%s/%s", CONFIG_PATH, CONFIG_FILENAME);
- f = fopen(card_path, "w");
- if (f == NULL)
- return;
-
- fprintf(f, "%s", config_text);
-
- fclose(f);
-}
-
-TEST(Blocklist, EmptyBlocklist) {
- static const char empty_config_text[] = "";
- struct cras_device_blocklist* blocklist;
-
- CreateConfigFile(empty_config_text);
-
- blocklist = cras_device_blocklist_create(CONFIG_PATH);
- ASSERT_NE(static_cast<cras_device_blocklist*>(NULL), blocklist);
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0, 0));
-
- cras_device_blocklist_destroy(blocklist);
-}
-
-TEST(Blocklist, BlockListOneUsbOutput) {
- static const char usb_output_config_text[] =
- "[USB_Outputs]\n"
- "0d8c_0008_00000012_0 = 1\n";
- struct cras_device_blocklist* blocklist;
-
- CreateConfigFile(usb_output_config_text);
-
- blocklist = cras_device_blocklist_create(CONFIG_PATH);
- ASSERT_NE(static_cast<cras_device_blocklist*>(NULL), blocklist);
-
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8d, 0x0008, 0x12, 0));
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0009, 0x12, 0));
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0x13, 0));
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0x12, 1));
- EXPECT_EQ(1, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0x12, 0));
-
- cras_device_blocklist_destroy(blocklist);
-}
-
-TEST(Blocklist, BlockListTwoUsbOutput) {
- static const char usb_output_config_text[] =
- "[USB_Outputs]\n"
- "0d8c_0008_00000000_0 = 1\n"
- "0d8c_0009_00000000_0 = 1\n";
- struct cras_device_blocklist* blocklist;
-
- CreateConfigFile(usb_output_config_text);
-
- blocklist = cras_device_blocklist_create(CONFIG_PATH);
- ASSERT_NE(static_cast<cras_device_blocklist*>(NULL), blocklist);
-
- EXPECT_EQ(1, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0009, 0, 0));
- EXPECT_EQ(1, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0, 0));
- EXPECT_EQ(0, cras_device_blocklist_check(blocklist, 0x0d8c, 0x0008, 0, 1));
-
- cras_device_blocklist_destroy(blocklist);
-}
-
-} // namespace
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/cras/src/tests/empty_iodev_unittest.cc b/cras/src/tests/empty_iodev_unittest.cc
index 148d5301..585fba32 100644
--- a/cras/src/tests/empty_iodev_unittest.cc
+++ b/cras/src/tests/empty_iodev_unittest.cc
@@ -13,7 +13,7 @@ extern "C" {
static struct timespec clock_gettime_retspec;
static struct cras_audio_format fake_format;
-static cras_audio_area mock_audio_area;
+static cras_audio_area dummy_audio_area;
namespace {
@@ -57,7 +57,7 @@ int cras_iodev_default_no_stream_playback(struct cras_iodev* odev, int enable) {
}
void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
- iodev->area = &mock_audio_area;
+ iodev->area = &dummy_audio_area;
}
void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
diff --git a/cras/src/tests/ewma_power_unittest.cc b/cras/src/tests/ewma_power_unittest.cc
deleted file mode 100644
index 10f03189..00000000
--- a/cras/src/tests/ewma_power_unittest.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <gtest/gtest.h>
-
-extern "C" {
-#include "ewma_power.h"
-}
-
-namespace {
-
-TEST(EWMAPower, RelativePowerValue) {
- struct ewma_power ewma;
- int16_t buf[480];
- float f;
- int i;
-
- for (i = 0; i < 480; i++)
- buf[i] = 0x00fe;
-
- ewma_power_init(&ewma, 48000);
- EXPECT_EQ(48, ewma.step_fr);
-
- ewma_power_calculate(&ewma, buf, 1, 480);
- EXPECT_LT(0.0f, ewma.power);
-
- // After 10ms of silence the power value decreases.
- f = ewma.power;
- for (i = 0; i < 480; i++)
- buf[i] = 0x00;
- ewma_power_calculate(&ewma, buf, 1, 480);
- EXPECT_LT(ewma.power, f);
-
- // After 300ms of silence the power value decreases to insignificant low.
- for (i = 0; i < 30; i++)
- ewma_power_calculate(&ewma, buf, 1, 480);
- EXPECT_LT(ewma.power, 1.0e-10);
-}
-
-TEST(EWMAPower, PowerInStereoData) {
- struct ewma_power ewma;
- int16_t buf[960];
- int i;
- float f;
-
- ewma_power_init(&ewma, 48000);
-
- for (i = 0; i < 960; i += 2) {
- buf[i] = 0x0;
- buf[i + 1] = 0x00fe;
- }
- ewma_power_calculate(&ewma, buf, 2, 480);
- EXPECT_LT(0.0f, ewma.power);
-
- // After 10ms of silence the power value decreases.
- f = ewma.power;
- for (i = 0; i < 960; i++)
- buf[i] = 0x0;
- ewma_power_calculate(&ewma, buf, 2, 480);
- EXPECT_LT(ewma.power, f);
-
- // After 300ms of silence the power value decreases to insignificant low.
- for (i = 0; i < 30; i++)
- ewma_power_calculate(&ewma, buf, 2, 480);
- EXPECT_LT(ewma.power, 1.0e-10);
-
- // Assume the data is silent in the other channel.
- ewma_power_init(&ewma, 48000);
-
- for (i = 0; i < 960; i += 2) {
- buf[i] = 0x0ffe;
- buf[i + 1] = 0x0;
- }
- ewma_power_calculate(&ewma, buf, 2, 480);
- EXPECT_LT(0.0f, ewma.power);
-}
-
-TEST(EWMAPower, PowerInAudioArea) {
- struct ewma_power ewma;
- struct cras_audio_area* area = cras_audio_area_create(4);
- struct cras_audio_format* fmt =
- cras_audio_format_create(SND_PCM_FORMAT_S16_LE, 48000, 4);
- int8_t layout[CRAS_CH_MAX] = {0, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- int16_t buf[1920];
- int i;
- float f;
-
- cras_audio_format_set_channel_layout(fmt, layout);
- cras_audio_area_config_channels(area, fmt);
-
- for (i = 0; i < 1920; i += 4) {
- buf[i] = 0x0ffe;
- buf[i + 1] = 0x0;
- buf[i + 2] = 0x0;
- buf[i + 3] = 0x0ffe;
- }
- ewma_power_init(&ewma, 48000);
- ewma_power_calculate_area(&ewma, buf, area, 480);
- f = ewma.power;
- EXPECT_LT(0.0f, f);
-
- /* Change the layout in the same audio area. Expect the power be lower because
- * one of the channel is now silent. */
- layout[CRAS_CH_FR] = 2;
- cras_audio_format_set_channel_layout(fmt, layout);
- cras_audio_area_config_channels(area, fmt);
- ewma_power_init(&ewma, 48000);
- ewma_power_calculate_area(&ewma, buf, area, 480);
- EXPECT_GT(f, ewma.power);
-
- /* Change layout to the two silent channels. Expect power is 0.0f. */
- layout[CRAS_CH_FL] = 1;
- cras_audio_format_set_channel_layout(fmt, layout);
- cras_audio_area_config_channels(area, fmt);
- ewma_power_init(&ewma, 48000);
- ewma_power_calculate_area(&ewma, buf, area, 480);
- EXPECT_EQ(0.0f, ewma.power);
-
- cras_audio_format_destroy(fmt);
- cras_audio_area_destroy(area);
-}
-
-} // namespace
-
-int main(int argc, char** argv) {
- ::testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/cras/src/tests/fmt_conv_ops_unittest.cc b/cras/src/tests/fmt_conv_ops_unittest.cc
index 0baf37b1..d58d618e 100644
--- a/cras/src/tests/fmt_conv_ops_unittest.cc
+++ b/cras/src/tests/fmt_conv_ops_unittest.cc
@@ -4,8 +4,6 @@
#include <gtest/gtest.h>
#include <limits.h>
-#include <math.h>
-#include <stdint.h>
#include <sys/param.h>
#include <memory>
@@ -418,39 +416,6 @@ TEST(FormatConverterOpsTest, StereoTo51S16LECenter) {
}
}
-// Test Quad to 5.1 conversion. S16_LE.
-TEST(FormatConverterOpsTest, QuadTo51S16LE) {
- const size_t frames = 4096;
- const size_t in_ch = 4;
- const size_t out_ch = 6;
- const unsigned int fl_quad = 0;
- const unsigned int fr_quad = 1;
- const unsigned int rl_quad = 2;
- const unsigned int rr_quad = 3;
-
- const unsigned int fl_51 = 0;
- const unsigned int fr_51 = 1;
- const unsigned int center_51 = 2;
- const unsigned int lfe_51 = 3;
- const unsigned int rl_51 = 4;
- const unsigned int rr_51 = 5;
-
- S16LEPtr src = CreateS16LE(frames * in_ch);
- S16LEPtr dst = CreateS16LE(frames * out_ch);
-
- size_t ret = s16_quad_to_51(fl_51, fr_51, rl_51, rr_51, (uint8_t*)src.get(),
- frames, (uint8_t*)dst.get());
- EXPECT_EQ(ret, frames);
- for (size_t i = 0; i < frames; ++i) {
- EXPECT_EQ(0, dst[i * 6 + center_51]);
- EXPECT_EQ(0, dst[i * 6 + lfe_51]);
- EXPECT_EQ(src[i * 4 + fl_quad], dst[i * 6 + fl_51]);
- EXPECT_EQ(src[i * 4 + fr_quad], dst[i * 6 + fr_51]);
- EXPECT_EQ(src[i * 4 + rl_quad], dst[i * 6 + rl_51]);
- EXPECT_EQ(src[i * 4 + rr_quad], dst[i * 6 + rr_51]);
- }
-}
-
// Test Stereo to 5.1 conversion. S16_LE, LeftRight.
TEST(FormatConverterOpsTest, StereoTo51S16LELeftRight) {
const size_t frames = 4096;
@@ -512,7 +477,7 @@ TEST(FormatConverterOpsTest, _51ToStereoS16LE) {
const size_t out_ch = 2;
const size_t left = 0;
const size_t right = 1;
- const size_t center = 2;
+ const size_t center = 4;
S16LEPtr src = CreateS16LE(frames * in_ch);
S16LEPtr dst = CreateS16LE(frames * out_ch);
@@ -521,58 +486,11 @@ TEST(FormatConverterOpsTest, _51ToStereoS16LE) {
s16_51_to_stereo((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
EXPECT_EQ(ret, frames);
- /* Use the normalized_factor from the left channel = 1 / (|1| + |0.707|)
- * to prevent mixing overflow.
- */
- const float normalized_factor = 0.585;
-
- for (size_t i = 0; i < frames; ++i) {
- int16_t half_center = src[i * 6 + center] * 0.707 * normalized_factor;
- int16_t l = normalized_factor * src[i * 6 + left] + half_center;
- int16_t r = normalized_factor * src[i * 6 + right] + half_center;
-
- EXPECT_EQ(l, dst[i * 2 + left]);
- EXPECT_EQ(r, dst[i * 2 + right]);
- }
-}
-
-// Test 5.1 to Quad conversion. S16_LE.
-TEST(FormatConverterOpsTest, _51ToQuadS16LE) {
- const size_t frames = 4096;
- const size_t in_ch = 6;
- const size_t out_ch = 4;
- const unsigned int fl_quad = 0;
- const unsigned int fr_quad = 1;
- const unsigned int rl_quad = 2;
- const unsigned int rr_quad = 3;
-
- const unsigned int fl_51 = 0;
- const unsigned int fr_51 = 1;
- const unsigned int center_51 = 2;
- const unsigned int lfe_51 = 3;
- const unsigned int rl_51 = 4;
- const unsigned int rr_51 = 5;
-
- S16LEPtr src = CreateS16LE(frames * in_ch);
- S16LEPtr dst = CreateS16LE(frames * out_ch);
-
- size_t ret = s16_51_to_quad((uint8_t*)src.get(), frames, (uint8_t*)dst.get());
- EXPECT_EQ(ret, frames);
-
- /* Use normalized_factor from the left channel = 1 / (|1| + |0.707| + |0.5|)
- * to prevent overflow. */
- const float normalized_factor = 0.453;
for (size_t i = 0; i < frames; ++i) {
- int16_t half_center = src[i * 6 + center_51] * 0.707 * normalized_factor;
- int16_t lfe = src[6 * i + lfe_51] * 0.5 * normalized_factor;
- int16_t fl = normalized_factor * src[6 * i + fl_51] + half_center + lfe;
- int16_t fr = normalized_factor * src[6 * i + fr_51] + half_center + lfe;
- int16_t rl = normalized_factor * src[6 * i + rl_51] + lfe;
- int16_t rr = normalized_factor * src[6 * i + rr_51] + lfe;
- EXPECT_EQ(fl, dst[4 * i + fl_quad]);
- EXPECT_EQ(fr, dst[4 * i + fr_quad]);
- EXPECT_EQ(rl, dst[4 * i + rl_quad]);
- EXPECT_EQ(rr, dst[4 * i + rr_quad]);
+ int16_t half_center = src[i * 6 + center] / 2;
+ EXPECT_EQ(S16AddAndClip(src[i * 6 + left], half_center), dst[i * 2 + left]);
+ EXPECT_EQ(S16AddAndClip(src[i * 6 + right], half_center),
+ dst[i * 2 + right]);
}
}
@@ -701,42 +619,12 @@ TEST(FormatConverterOpsTest, StereoTo3chS16LE) {
EXPECT_EQ(ret, frames);
for (size_t i = 0; i < frames; ++i) {
- int32_t sum = 0;
for (size_t k = 0; k < in_ch; ++k)
- sum += (int32_t)src[i * in_ch + k];
- src[i * in_ch + 0] = (int16_t)(sum / (int32_t)in_ch);
- }
- for (size_t i = 0; i < frames; ++i) {
- for (size_t k = 0; k < out_ch; ++k)
- EXPECT_EQ(src[i * in_ch + 0], dst[i * out_ch + k]);
- }
-}
-
-// Test 6ch to 8ch conversion. S16_LE.
-TEST(FormatConverterOpsTest, 6chTo8chS16LE) {
- const size_t frames = 65536;
- const size_t in_ch = 6;
- const size_t out_ch = 8;
- struct cras_audio_format fmt = {
- .format = SND_PCM_FORMAT_S16_LE,
- .frame_rate = 48000,
- .num_channels = 8,
- };
-
- S16LEPtr src = CreateS16LE(frames * in_ch);
- S16LEPtr dst = CreateS16LE(frames * out_ch);
- for (size_t i = 0; i < frames; ++i) {
- for (size_t k = 0; k < in_ch; k++) {
- src[i * in_ch + k] = (k == 0) ? (INT16_MIN + (int16_t)i) : 0;
- }
+ src[i * in_ch + k] /= in_ch;
+ for (size_t k = 1; k < in_ch; ++k)
+ src[i * in_ch + 0] += src[i * in_ch + k];
}
-
- size_t ret = s16_default_all_to_all(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
- frames, (uint8_t*)dst.get());
- EXPECT_EQ(ret, frames);
-
for (size_t i = 0; i < frames; ++i) {
- src[i * in_ch + 0] /= (int16_t)in_ch;
for (size_t k = 0; k < out_ch; ++k)
EXPECT_EQ(src[i * in_ch + 0], dst[i * out_ch + k]);
}
@@ -788,65 +676,6 @@ TEST(FormatConverterOpsTest, ConvertChannelsS16LE) {
}
}
-// Test Stereo to 20ch conversion. S16_LE.
-TEST(FormatConverterOpsTest, TwoToTwentyS16LE) {
- const size_t frames = 4096;
- const size_t in_ch = 2;
- const size_t out_ch = 20;
- struct cras_audio_format fmt = {
- .format = SND_PCM_FORMAT_S16_LE,
- .frame_rate = 48000,
- .num_channels = 20,
- };
-
- S16LEPtr src = CreateS16LE(frames * in_ch);
- S16LEPtr dst = CreateS16LE(frames * out_ch);
-
- size_t ret = s16_some_to_some(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
- frames, (uint8_t*)dst.get());
- EXPECT_EQ(ret, frames);
-
- for (size_t i = 0; i < frames; ++i) {
- size_t k;
- // Input channles should be directly copied over.
- for (k = 0; k < in_ch; ++k) {
- EXPECT_EQ(src[i * in_ch + k], dst[i * out_ch + k]);
- }
- // The rest should be zeroed.
- for (; k < out_ch; ++k) {
- EXPECT_EQ(0, dst[i * out_ch + k]);
- }
-
- }
-}
-
-// Test 20ch to Stereo. S16_LE.
-TEST(FormatConverterOpsTest, TwentyToTwoS16LE) {
- const size_t frames = 4096;
- const size_t in_ch = 20;
- const size_t out_ch = 2;
- struct cras_audio_format fmt = {
- .format = SND_PCM_FORMAT_S16_LE,
- .frame_rate = 48000,
- .num_channels = 2,
- };
-
- S16LEPtr src = CreateS16LE(frames * in_ch);
- S16LEPtr dst = CreateS16LE(frames * out_ch);
-
- size_t ret = s16_some_to_some(&fmt, in_ch, out_ch, (uint8_t*)src.get(),
- frames, (uint8_t*)dst.get());
- EXPECT_EQ(ret, frames);
-
- for (size_t i = 0; i < frames; ++i) {
- size_t k;
- // Input channles should be directly copied over.
- for (k = 0; k < out_ch; ++k) {
- EXPECT_EQ(src[i * in_ch + k], dst[i * out_ch + k]);
- }
- }
-}
-
extern "C" {} // extern "C"
int main(int argc, char** argv) {
diff --git a/cras/src/tests/fmt_conv_unittest.cc b/cras/src/tests/fmt_conv_unittest.cc
index c66984ee..5474f172 100644
--- a/cras/src/tests/fmt_conv_unittest.cc
+++ b/cras/src/tests/fmt_conv_unittest.cc
@@ -3,7 +3,6 @@
// found in the LICENSE file.
#include <gtest/gtest.h>
-#include <math.h>
#include <sys/param.h>
extern "C" {
@@ -460,81 +459,6 @@ TEST(FormatConverterTest, SurroundToStereo) {
free(out_buff);
}
-// Test 5.1 to Quad mix.
-TEST(FormatConverterTest, SurroundToQuad) {
- struct cras_fmt_conv* c;
- struct cras_audio_format in_fmt;
- struct cras_audio_format out_fmt;
-
- size_t out_frames;
- int16_t* in_buff;
- int16_t* out_buff;
- unsigned int i;
- const size_t buf_size = 4096;
- unsigned int in_buf_size = 4096;
-
- ResetStub();
- in_fmt.format = SND_PCM_FORMAT_S16_LE;
- out_fmt.format = SND_PCM_FORMAT_S16_LE;
- in_fmt.num_channels = 6;
- out_fmt.num_channels = 4;
- in_fmt.frame_rate = 48000;
- out_fmt.frame_rate = 48000;
- for (i = 0; i < CRAS_CH_MAX; i++)
- in_fmt.channel_layout[i] = surround_channel_center_layout[i];
-
- c = cras_fmt_conv_create(&in_fmt, &out_fmt, buf_size, 0);
- ASSERT_NE(c, (void*)NULL);
-
- out_frames = cras_fmt_conv_out_frames_to_in(c, buf_size);
- EXPECT_EQ(buf_size, out_frames);
-
- out_frames = cras_fmt_conv_in_frames_to_out(c, buf_size);
- EXPECT_EQ(buf_size, out_frames);
-
- in_buff = (int16_t*)malloc(buf_size * 2 * cras_get_format_bytes(&in_fmt));
-
- const int16_t in_fl = 100;
- const int16_t in_fr = 200;
- const int16_t in_rl = 200;
- const int16_t in_rr = 300;
- const int16_t in_fc = 60;
- const int16_t in_lfe = 90;
-
- for (i = 0; i < buf_size; i++) {
- in_buff[i * 6 + CRAS_CH_FL] = in_fl;
- in_buff[i * 6 + CRAS_CH_FR] = in_fr;
- in_buff[i * 6 + CRAS_CH_RL] = in_rl;
- in_buff[i * 6 + CRAS_CH_RR] = in_rr;
- in_buff[i * 6 + CRAS_CH_FC] = in_fc;
- in_buff[i * 6 + CRAS_CH_LFE] = in_lfe;
- }
- out_buff = (int16_t*)malloc(buf_size * 2 * cras_get_format_bytes(&out_fmt));
- out_frames = cras_fmt_conv_convert_frames(
- c, (uint8_t*)in_buff, (uint8_t*)out_buff, &in_buf_size, buf_size);
- EXPECT_EQ(buf_size, out_frames);
-
- // This is the sum of mtx[CRAS_CH_FL] coefficients.
- const float normalize_factor = 1.0 / (1 + 0.707 + 0.5);
-
- for (i = 0; i < buf_size; i++) {
- int16_t lfe = 0.5 * normalize_factor * in_lfe;
- int16_t center = 0.707 * normalize_factor * in_fc;
- int16_t fl = normalize_factor * in_fl + center + lfe;
- int16_t fr = normalize_factor * in_fr + center + lfe;
- int16_t rl = normalize_factor * in_rl + lfe;
- int16_t rr = normalize_factor * in_rr + lfe;
-
- EXPECT_EQ(fl, out_buff[i * 4 + CRAS_CH_FL]);
- EXPECT_EQ(fr, out_buff[i * 4 + CRAS_CH_FR]);
- EXPECT_EQ(rl, out_buff[i * 4 + CRAS_CH_RL]);
- EXPECT_EQ(rr, out_buff[i * 4 + CRAS_CH_RR]);
- }
- cras_fmt_conv_destroy(&c);
- free(in_buff);
- free(out_buff);
-}
-
// Test Quad to Stereo mix.
TEST(FormatConverterTest, QuadToStereo) {
struct cras_fmt_conv* c;
diff --git a/cras/src/tests/hfp_ag_profile_unittest.cc b/cras/src/tests/hfp_ag_profile_unittest.cc
index 3ecd2407..56c99088 100644
--- a/cras/src/tests/hfp_ag_profile_unittest.cc
+++ b/cras/src/tests/hfp_ag_profile_unittest.cc
@@ -167,25 +167,6 @@ int cras_bt_add_profile(DBusConnection* conn, struct cras_bt_profile* profile) {
return 0;
}
-int cras_bt_rm_profile(DBusConnection* conn, struct cras_bt_profile* profile) {
- internal_bt_profile = NULL;
- return 0;
-}
-
-int cras_bt_register_profile(DBusConnection* conn,
- struct cras_bt_profile* profile) {
- return 0;
-}
-
-int cras_bt_register_profiles(DBusConnection* conn) {
- return 0;
-}
-
-int cras_bt_unregister_profile(DBusConnection* conn,
- struct cras_bt_profile* profile) {
- return 0;
-}
-
struct hfp_info* hfp_info_create() {
return NULL;
}
@@ -243,22 +224,11 @@ struct hfp_slc_handle* hfp_slc_create(int fd,
int hfp_slc_get_selected_codec(struct hfp_slc_handle* handle) {
return HFP_CODEC_ID_CVSD;
}
-int hfp_slc_get_ag_codec_negotiation_supported(struct hfp_slc_handle* handle) {
- return 1;
-}
int hfp_slc_get_hf_codec_negotiation_supported(struct hfp_slc_handle* handle) {
return 1;
}
-int hfp_slc_get_hf_supports_battery_indicator(struct hfp_slc_handle* handle) {
- return 0;
-}
-
-int hfp_slc_get_hf_battery_level(struct hfp_slc_handle* handle) {
- return -1;
-}
-
struct cras_bt_device* cras_a2dp_connected_device() {
return NULL;
}
@@ -270,10 +240,6 @@ int cras_bt_device_supports_profile(const struct cras_bt_device* device,
void cras_a2dp_suspend_connected_device(struct cras_bt_device* device) {}
-const char* cras_bt_device_address(const struct cras_bt_device* device) {
- return "";
-}
-
int cras_bt_device_audio_gateway_initialized(struct cras_bt_device* device) {
return 0;
}
@@ -286,22 +252,10 @@ void cras_bt_device_notify_profile_dropped(
cras_bt_device_notify_profile_dropped_profile = profile;
}
-void hfp_info_set_wbs_logger(struct hfp_info* info,
- struct packet_status_logger* wbs_logger) {}
-
-void cras_observer_notify_bt_battery_changed(const char* address,
- uint32_t level) {
- return;
-}
-
bool cras_system_get_bt_wbs_enabled() {
return true;
}
-int cras_server_metrics_hfp_wideband_selected_codec(int codec) {
- return HFP_CODEC_ID_MSBC;
-}
-
} // extern "C"
int main(int argc, char** argv) {
diff --git a/cras/src/tests/hfp_alsa_iodev_unittest.cc b/cras/src/tests/hfp_alsa_iodev_unittest.cc
index 8756c201..a4d5ba94 100644
--- a/cras/src/tests/hfp_alsa_iodev_unittest.cc
+++ b/cras/src/tests/hfp_alsa_iodev_unittest.cc
@@ -22,7 +22,6 @@ struct hfp_alsa_io {
static struct cras_iodev fake_sco_out, fake_sco_in;
static struct cras_bt_device* fake_device;
static struct hfp_slc_handle* fake_slc;
-static struct cras_audio_format fake_format;
static size_t cras_bt_device_append_iodev_called;
static size_t cras_bt_device_rm_iodev_called;
@@ -58,7 +57,6 @@ _FAKE_CALL1(open_dev);
_FAKE_CALL1(update_supported_formats);
_FAKE_CALL1(configure_dev);
_FAKE_CALL1(close_dev);
-_FAKE_CALL1(output_underrun);
_FAKE_CALL2(frames_queued);
_FAKE_CALL1(delay_frames);
_FAKE_CALL3(get_buffer);
@@ -68,7 +66,6 @@ _FAKE_CALL3(update_active_node);
_FAKE_CALL1(start);
_FAKE_CALL2(no_stream);
_FAKE_CALL1(is_free_running);
-_FAKE_CALL2(get_valid_frames);
static void ResetStubData() {
cras_bt_device_append_iodev_called = 0;
@@ -133,14 +130,6 @@ static void ResetStubData() {
fake_sco_out.is_free_running = fake_sco_in.is_free_running =
(int (*)(const struct cras_iodev*))fake_is_free_running;
fake_is_free_running_called = 0;
-
- fake_sco_out.output_underrun =
- (int (*)(struct cras_iodev*))fake_output_underrun;
- fake_output_underrun_called = 0;
-
- fake_sco_out.get_valid_frames =
- (int (*)(struct cras_iodev*, struct timespec*))fake_get_valid_frames;
- fake_get_valid_frames_called = 0;
}
namespace {
@@ -227,8 +216,7 @@ TEST_F(HfpAlsaIodev, UpdateSupportedFormat) {
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
iodev->update_supported_formats(iodev);
- // update_supported_format on alsa_io is not called.
- EXPECT_EQ(0, fake_update_supported_formats_called);
+ EXPECT_EQ(1, fake_update_supported_formats_called);
for (size_t i = 0; i < 2; ++i) {
EXPECT_EQ(supported_rates[i], iodev->supported_rates[i]);
EXPECT_EQ(supported_channel_counts[i], iodev->supported_channel_counts[i]);
@@ -241,23 +229,13 @@ TEST_F(HfpAlsaIodev, UpdateSupportedFormat) {
TEST_F(HfpAlsaIodev, ConfigureDev) {
struct cras_iodev* iodev;
size_t buf_size = 8192;
- struct hfp_alsa_io* hfp_alsa_io;
fake_sco_out.direction = CRAS_STREAM_OUTPUT;
fake_sco_out.buffer_size = buf_size;
iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc,
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
- hfp_alsa_io = (struct hfp_alsa_io*)iodev;
- iodev->format = &fake_format;
iodev->configure_dev(iodev);
- EXPECT_EQ(fake_format.num_channels, hfp_alsa_io->aio->format->num_channels);
- EXPECT_EQ(fake_format.frame_rate, hfp_alsa_io->aio->format->frame_rate);
- EXPECT_EQ(fake_format.format, hfp_alsa_io->aio->format->format);
- for (int i = 0; i < CRAS_CH_MAX; i++)
- EXPECT_EQ(fake_format.channel_layout[i],
- hfp_alsa_io->aio->format->channel_layout[i]);
-
EXPECT_EQ(1, fake_configure_dev_called);
EXPECT_EQ(1, hfp_set_call_status_called);
EXPECT_EQ(buf_size, iodev->buffer_size);
@@ -273,7 +251,6 @@ TEST_F(HfpAlsaIodev, CloseDev) {
CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
iodev->close_dev(iodev);
- EXPECT_EQ(1, hfp_set_call_status_called);
EXPECT_EQ(1, cras_iodev_free_format_called);
EXPECT_EQ(1, fake_close_dev_called);
@@ -415,38 +392,6 @@ TEST_F(HfpAlsaIodev, IsFreeRunning) {
hfp_alsa_iodev_destroy(iodev);
}
-TEST_F(HfpAlsaIodev, OutputUnderrun) {
- struct cras_iodev* iodev;
-
- fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc,
- CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
- iodev->min_cb_level = 0xab;
- iodev->max_cb_level = 0xcd;
-
- iodev->output_underrun(iodev);
-
- EXPECT_EQ(0xab, fake_sco_out.min_cb_level);
- EXPECT_EQ(0xcd, fake_sco_out.max_cb_level);
- EXPECT_EQ(1, fake_output_underrun_called);
-
- hfp_alsa_iodev_destroy(iodev);
-}
-
-TEST_F(HfpAlsaIodev, GetValidFrames) {
- struct cras_iodev* iodev;
- struct timespec ts;
-
- fake_sco_out.direction = CRAS_STREAM_OUTPUT;
- iodev = hfp_alsa_iodev_create(&fake_sco_out, fake_device, fake_slc,
- CRAS_BT_DEVICE_PROFILE_HFP_AUDIOGATEWAY);
-
- iodev->get_valid_frames(iodev, &ts);
-
- EXPECT_EQ(1, fake_get_valid_frames_called);
-
- hfp_alsa_iodev_destroy(iodev);
-}
} // namespace
extern "C" {
@@ -477,9 +422,6 @@ void cras_iodev_set_active_node(struct cras_iodev* iodev,
iodev->active_node = node;
}
-// From ewma_power
-void ewma_power_disable(struct ewma_power* ewma) {}
-
size_t cras_system_get_volume() {
return 0;
}
@@ -507,10 +449,6 @@ const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
return "/fake/object/path";
}
-int cras_bt_device_get_stable_id(const struct cras_bt_device* device) {
- return 123;
-}
-
void cras_iodev_free_resources(struct cras_iodev* iodev) {
cras_iodev_free_resources_called++;
}
diff --git a/cras/src/tests/hfp_info_unittest.cc b/cras/src/tests/hfp_info_unittest.cc
index 24f536ae..482c3a99 100644
--- a/cras/src/tests/hfp_info_unittest.cc
+++ b/cras/src/tests/hfp_info_unittest.cc
@@ -3,15 +3,10 @@
* found in the LICENSE file.
*/
-#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdint.h>
#include <time.h>
-using testing::MatchesRegex;
-using testing::internal::CaptureStdout;
-using testing::internal::GetCapturedStdout;
-
extern "C" {
#include "cras_hfp_info.c"
#include "sbc_codec_stub.h"
@@ -43,7 +38,7 @@ namespace {
TEST(HfpInfo, AddRmDev) {
ResetStubData();
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
dev.direction = CRAS_STREAM_OUTPUT;
@@ -61,7 +56,7 @@ TEST(HfpInfo, AddRmDev) {
TEST(HfpInfo, AddRmDevInvalid) {
ResetStubData();
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
dev.direction = CRAS_STREAM_OUTPUT;
@@ -82,10 +77,10 @@ TEST(HfpInfo, AcquirePlaybackBuffer) {
ResetStubData();
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
- hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(1, 48, info);
dev.direction = CRAS_STREAM_OUTPUT;
ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
@@ -130,10 +125,10 @@ TEST(HfpInfo, AcquireCaptureBuffer) {
ResetStubData();
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
- hfp_info_start(1, 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(1, 48, info);
dev.direction = CRAS_STREAM_INPUT;
ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
@@ -178,11 +173,11 @@ TEST(HfpInfo, HfpReadWriteFD) {
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
dev.direction = CRAS_STREAM_INPUT;
- hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(sock[1], 48, info);
ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
/* Mock the sco fd and send some fake data */
@@ -229,10 +224,10 @@ TEST(HfpInfo, StartHfpInfo) {
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
- hfp_info_start(sock[0], 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(sock[0], 48, info);
ASSERT_EQ(1, hfp_info_running(info));
ASSERT_EQ(cb_data, (void*)info);
@@ -252,16 +247,16 @@ TEST(HfpInfo, StartHfpInfoAndRead) {
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
/* Start and send two chunk of fake data */
- hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(sock[1], 48, info);
send(sock[0], sample, 48, 0);
send(sock[0], sample, 48, 0);
/* Trigger thread callback */
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
dev.direction = CRAS_STREAM_INPUT;
ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
@@ -273,7 +268,7 @@ TEST(HfpInfo, StartHfpInfoAndRead) {
/* Trigger thread callback after idev added. */
ts.tv_sec = 0;
ts.tv_nsec = 5000000;
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
rc = hfp_buf_queued(info, dev.direction);
ASSERT_EQ(48 / 2, rc);
@@ -297,15 +292,15 @@ TEST(HfpInfo, StartHfpInfoAndWrite) {
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_CVSD);
ASSERT_NE(info, (void*)NULL);
- hfp_info_start(sock[1], 48, HFP_CODEC_ID_CVSD, info);
+ hfp_info_start(sock[1], 48, info);
send(sock[0], sample, 48, 0);
send(sock[0], sample, 48, 0);
/* Trigger thread callback */
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
/* Without odev in presence, zero packet should be sent. */
rc = recv(sock[0], sample, 48, 0);
@@ -319,7 +314,7 @@ TEST(HfpInfo, StartHfpInfoAndWrite) {
/* Put some fake data and trigger thread callback again */
buf_increment_write(info->playback_buf, 1008);
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
/* Assert some samples written */
rc = recv(sock[0], sample, 48, 0);
@@ -331,44 +326,30 @@ TEST(HfpInfo, StartHfpInfoAndWrite) {
}
void send_mSBC_packet(int fd, unsigned seq, int broken_pkt) {
- /* The first three bytes of hci_sco_buf are h2 header, frame count and mSBC
- * sync word. The second octet of H2 header is composed by 4 bits fixed 0x8
- * and 4 bits sequence number 0000, 0011, 1100, 1111.
+ /* These three bytes are h2 header, frame count and mSBC sync word.
+ * The second octet of H2 header is composed by 4 bits fixed 0x8 and 4 bits
+ * sequence number 0000, 0011, 1100, 1111.
*/
- uint8_t headers[4] = {0x08, 0x38, 0xc8, 0xf8};
- uint8_t hci_sco_buf[] = {
- 0x01, 0x00, 0xAD, 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb,
- 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6,
- 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd,
- 0xb6, 0xdb, 0x77, 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c};
- struct msghdr msg = {0};
- struct iovec iov;
- struct cmsghdr* cmsg;
- const unsigned int control_size = CMSG_SPACE(sizeof(int));
- char control[control_size] = {0};
- uint8_t pkt_status = 0;
-
- hci_sco_buf[1] = headers[seq % 4];
-
- /* Assume typical 60 bytes case. */
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- iov.iov_base = hci_sco_buf;
- iov.iov_len = 60;
- msg.msg_control = control;
- msg.msg_controllen = control_size;
-
+ uint8_t headers[4][3] = {{0x01, 0x08, 0xAD},
+ {0x01, 0x38, 0xAD},
+ {0x01, 0xc8, 0xAD},
+ {0x01, 0xf8, 0xAD}};
+ /* These three bytes are HCI SCO Data packet header, we only care the
+ * Packet_Status_Flag bits, which are the bit 4 to 5 in the second octet.
+ */
+ uint8_t sco_header[] = {0x01, 0x01, 0x3c};
+ uint8_t zero_frame[] = {
+ 0xad, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x77, 0x6d, 0xb6, 0xdd,
+ 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d, 0xb6,
+ 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77, 0x6d,
+ 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6d, 0xdd, 0xb6, 0xdb, 0x77,
+ 0x6d, 0xb6, 0xdd, 0xdb, 0x6d, 0xb7, 0x76, 0xdb, 0x6c};
if (broken_pkt)
- pkt_status = 0x11;
+ sco_header[1] = 0x11;
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_level = SOL_BLUETOOTH;
- cmsg->cmsg_type = BT_SCM_PKT_STATUS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(pkt_status));
- memcpy(CMSG_DATA(cmsg), &pkt_status, sizeof(pkt_status));
-
- sendmsg(fd, &msg, 0);
+ send(fd, sco_header, 3, 0);
+ send(fd, headers[seq % 4], 3, 0);
+ send(fd, zero_frame, 57, 0);
}
TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
@@ -382,19 +363,17 @@ TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
set_sbc_codec_decoded_out(MSBC_CODE_SIZE);
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_MSBC);
ASSERT_NE(info, (void*)NULL);
- ASSERT_EQ(0, get_msbc_codec_create_called());
- ASSERT_EQ(0, cras_msbc_plc_create_called);
-
- /* Start and send an mSBC packets with all zero samples */
- hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
ASSERT_EQ(2, get_msbc_codec_create_called());
ASSERT_EQ(1, cras_msbc_plc_create_called);
+
+ /* Start and send an mSBC packets with all zero samples */
+ hfp_info_start(sock[1], 63, info);
send_mSBC_packet(sock[0], pkt_count++, 0);
/* Trigger thread callback */
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
/* Expect one empty mSBC packet is send, because no odev in presence. */
rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
@@ -409,7 +388,7 @@ TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
send_mSBC_packet(sock[0], pkt_count, 0);
/* Trigger thread callback after idev added. */
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
ASSERT_EQ(MSBC_PKT_SIZE, rc);
@@ -422,7 +401,7 @@ TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
*/
pkt_count++;
send_mSBC_packet(sock[0], pkt_count, 0);
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
ASSERT_EQ(MSBC_PKT_SIZE, rc);
@@ -439,7 +418,7 @@ TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
set_sbc_codec_decoded_fail(1);
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
ASSERT_EQ(MSBC_PKT_SIZE, rc);
@@ -455,7 +434,7 @@ TEST(HfpInfo, StartHfpInfoAndReadMsbc) {
set_sbc_codec_decoded_fail(1);
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
rc = recv(sock[0], sample, MSBC_PKT_SIZE, 0);
ASSERT_EQ(MSBC_PKT_SIZE, rc);
@@ -480,14 +459,14 @@ TEST(HfpInfo, StartHfpInfoAndWriteMsbc) {
set_sbc_codec_encoded_out(57);
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- info = hfp_info_create();
+ info = hfp_info_create(HFP_CODEC_ID_MSBC);
ASSERT_NE(info, (void*)NULL);
- hfp_info_start(sock[1], 63, HFP_CODEC_ID_MSBC, info);
+ hfp_info_start(sock[1], 63, info);
send(sock[0], sample, 63, 0);
/* Trigger thread callback */
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
dev.direction = CRAS_STREAM_OUTPUT;
ASSERT_EQ(0, hfp_info_add_iodev(info, dev.direction, dev.format));
@@ -498,7 +477,7 @@ TEST(HfpInfo, StartHfpInfoAndWriteMsbc) {
/* Put some fake data and trigger thread callback again */
send(sock[0], sample, 63, 0);
buf_increment_write(info->playback_buf, 240);
- thread_cb((struct hfp_info*)cb_data, POLLIN);
+ thread_cb((struct hfp_info*)cb_data);
/* Assert some samples written */
rc = recv(sock[0], sample, 60, 0);
@@ -509,26 +488,6 @@ TEST(HfpInfo, StartHfpInfoAndWriteMsbc) {
hfp_info_destroy(info);
}
-TEST(HfpInfo, WBSLoggerPacketStatusDumpBinary) {
- struct packet_status_logger logger;
- char log_regex[64];
- int num_wraps[5] = {0, 0, 0, 1, 1};
- int wp[5] = {40, 150, 162, 100, 32};
-
- /* Expect the log line wraps at correct length to avoid feedback redact. */
- snprintf(log_regex, 64, "([01D]{%d}\n)*", PACKET_STATUS_LOG_LINE_WRAP);
-
- packet_status_logger_init(&logger);
- logger.size = PACKET_STATUS_LEN_BYTES * 8;
- for (int i = 0; i < 5; i++) {
- CaptureStdout();
- logger.num_wraps = num_wraps[i];
- logger.wp = wp[i];
- packet_status_logger_dump_binary(&logger);
- EXPECT_THAT(GetCapturedStdout(), MatchesRegex(log_regex));
- }
-}
-
} // namespace
extern "C" {
@@ -537,10 +496,7 @@ struct audio_thread* cras_iodev_list_get_audio_thread() {
return NULL;
}
-void audio_thread_add_events_callback(int fd,
- thread_callback cb,
- void* data,
- int events) {
+void audio_thread_add_callback(int fd, thread_callback cb, void* data) {
thread_cb = cb;
cb_data = data;
return;
@@ -574,10 +530,6 @@ int cras_msbc_plc_handle_good_frames(struct cras_msbc_plc* plc,
cras_msbc_plc_handle_good_frames_called++;
return MSBC_CODE_SIZE;
}
-void packet_status_logger_init(struct packet_status_logger* logger) {}
-
-void packet_status_logger_update(struct packet_status_logger* logger,
- bool val) {}
}
int main(int argc, char** argv) {
diff --git a/cras/src/tests/hfp_iodev_unittest.cc b/cras/src/tests/hfp_iodev_unittest.cc
index 1275ef2c..9bfb2dda 100644
--- a/cras/src/tests/hfp_iodev_unittest.cc
+++ b/cras/src/tests/hfp_iodev_unittest.cc
@@ -43,7 +43,7 @@ static size_t hfp_fill_output_with_zeros_called;
static size_t hfp_force_output_level_called;
static size_t hfp_force_output_level_target;
static size_t fake_buffer_size = 500;
-static cras_audio_area* mock_audio_area;
+static cras_audio_area* dummy_audio_area;
void ResetStubData() {
cras_bt_device_append_iodev_called = 0;
@@ -73,9 +73,9 @@ void ResetStubData() {
fake_info = reinterpret_cast<struct hfp_info*>(0x123);
- if (!mock_audio_area) {
- mock_audio_area = (cras_audio_area*)calloc(
- 1, sizeof(*mock_audio_area) + sizeof(cras_channel_area) * 2);
+ if (!dummy_audio_area) {
+ dummy_audio_area = (cras_audio_area*)calloc(
+ 1, sizeof(*dummy_audio_area) + sizeof(cras_channel_area) * 2);
}
}
@@ -86,8 +86,8 @@ class HfpIodev : public testing::Test {
virtual void SetUp() { ResetStubData(); }
virtual void TearDown() {
- free(mock_audio_area);
- mock_audio_area = NULL;
+ free(dummy_audio_area);
+ dummy_audio_area = NULL;
}
};
@@ -243,9 +243,6 @@ void cras_iodev_set_active_node(struct cras_iodev* iodev,
iodev->active_node = node;
}
-// From ewma_power
-void ewma_power_disable(struct ewma_power* ewma) {}
-
// From system_state.
size_t cras_system_get_volume() {
return 0;
@@ -285,10 +282,6 @@ const char* cras_bt_device_object_path(const struct cras_bt_device* device) {
return "/fake/object/path";
}
-int cras_bt_device_get_stable_id(const struct cras_bt_device* device) {
- return 123;
-}
-
// From cras_hfp_info
int hfp_info_add_iodev(struct hfp_info* info,
enum CRAS_STREAM_DIRECTION direction,
@@ -313,7 +306,7 @@ int hfp_info_running(struct hfp_info* info) {
return hfp_info_running_return_val;
}
-int hfp_info_start(int fd, unsigned int mtu, int codec, struct hfp_info* info) {
+int hfp_info_start(int fd, unsigned int mtu, struct hfp_info* info) {
hfp_info_start_called++;
return 0;
}
@@ -358,7 +351,7 @@ void hfp_force_output_level(struct hfp_info* info, unsigned int level) {
}
void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
- iodev->area = mock_audio_area;
+ iodev->area = dummy_audio_area;
}
void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
@@ -367,14 +360,10 @@ void cras_iodev_free_resources(struct cras_iodev* iodev) {
cras_iodev_free_resources_called++;
}
-int cras_iodev_fill_odev_zeros(struct cras_iodev* odev, unsigned int frames) {
- return 0;
-}
-
void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
const struct cras_audio_format* fmt,
uint8_t* base_buffer) {
- mock_audio_area->channels[0].buf = base_buffer;
+ dummy_audio_area->channels[0].buf = base_buffer;
}
int hfp_set_call_status(struct hfp_slc_handle* handle, int call) {
@@ -389,18 +378,6 @@ int hfp_slc_get_selected_codec(struct hfp_slc_handle* handle) {
return HFP_CODEC_ID_CVSD;
}
-bool hfp_slc_get_wideband_speech_supported(struct hfp_slc_handle* handle) {
- return false;
-}
-
-int hfp_slc_codec_connection_setup(struct hfp_slc_handle* handle) {
- return 0;
-}
-
-int hfp_slc_is_hsp(struct hfp_slc_handle* handle) {
- return 0;
-}
-
} // extern "C"
int main(int argc, char** argv) {
diff --git a/cras/src/tests/hfp_slc_unittest.cc b/cras/src/tests/hfp_slc_unittest.cc
index 966278f4..f98a1f3e 100644
--- a/cras/src/tests/hfp_slc_unittest.cc
+++ b/cras/src/tests/hfp_slc_unittest.cc
@@ -17,7 +17,6 @@ extern "C" {
static struct hfp_slc_handle* handle;
static struct cras_telephony_handle fake_telephony;
static int cras_bt_device_update_hardware_volume_called;
-static int cras_observer_notify_bt_batter_changed_called;
static int slc_initialized_cb_called;
static int slc_disconnected_cb_called;
static int cras_system_add_select_fd_called;
@@ -36,7 +35,6 @@ void ResetStubData() {
slc_initialized_cb_called = 0;
cras_system_add_select_fd_called = 0;
cras_bt_device_update_hardware_volume_called = 0;
- cras_observer_notify_bt_batter_changed_called = 0;
slc_cb = NULL;
slc_cb_data = NULL;
}
@@ -61,8 +59,6 @@ TEST(HfpSlc, InitializeSlc) {
char* chp;
ResetStubData();
- btlog = cras_bt_event_log_init();
-
ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
handle = hfp_slc_create(sock[0], 0, AG_ENHANCED_CALL_STATUS, device,
slc_initialized_cb, slc_disconnected_cb);
@@ -112,7 +108,6 @@ TEST(HfpSlc, InitializeSlc) {
ASSERT_EQ(1, cras_bt_device_update_hardware_volume_called);
hfp_slc_destroy(handle);
- cras_bt_event_log_deinit(btlog);
}
TEST(HfpSlc, DisconnectSlc) {
@@ -134,108 +129,6 @@ TEST(HfpSlc, DisconnectSlc) {
hfp_slc_destroy(handle);
}
-TEST(HfpSlc, InitializeSlcSupportsHfIndicator) {
- int err;
- int sock[2];
- char buf[256];
- char* chp;
- ResetStubData();
-
- btlog = cras_bt_event_log_init();
-
- ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, sock));
- handle = hfp_slc_create(sock[0], 0, AG_ENHANCED_CALL_STATUS, device,
- slc_initialized_cb, slc_disconnected_cb);
-
- /* Fake that HF supports HF indicator. */
- err = write(sock[1], "AT+BRSF=256\r", 12);
- ASSERT_EQ(err, 12);
- slc_cb(slc_cb_data);
- err = read(sock[1], buf, 256);
-
- err = write(sock[1], "AT+CIND=?\r", 10);
- ASSERT_EQ(10, err);
- slc_cb(slc_cb_data);
- err = read(sock[1], buf, 256);
-
- /* Assert "\r\n+CIND: ... \r\n" response is received */
- chp = strstr(buf, "\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
- ASSERT_EQ(0, strncmp("\r\n+CIND:", chp, 8));
- chp += 2;
- chp = strstr(chp, "\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- /* Assert "\r\nOK\r\n" response is received */
- chp += 2;
- chp = strstr(chp, "\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
- ASSERT_EQ(0, strncmp("\r\nOK", chp, 4));
-
- err = write(sock[1], "AT+CMER=3,0,0,1\r", 16);
- ASSERT_EQ(16, err);
- slc_cb(slc_cb_data);
-
- ASSERT_NE((void*)NULL, cras_tm_timer_cb);
- ASSERT_EQ(0, slc_initialized_cb_called);
-
- /* Assert "\r\nOK\r\n" response is received */
- err = read(sock[1], buf, 256);
-
- chp = strstr(buf, "\r\nOK\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- err = write(sock[1], "AT+BIND=2\r", 10);
- ASSERT_EQ(err, 10);
- slc_cb(slc_cb_data);
-
- /* Assert "\r\nOK\r\n" response is received */
- err = read(sock[1], buf, 256);
-
- chp = strstr(buf, "\r\nOK\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- err = write(sock[1], "AT+BIND=?\r", 10);
- ASSERT_EQ(err, 10);
- slc_cb(slc_cb_data);
-
- /* Assert "\r\n+BIND: (2)\r\n" response is received */
- err = read(sock[1], buf, 256);
-
- chp = strstr(buf, "\r\n+BIND: (1,2)\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
- chp = strstr(buf, "\r\nOK\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- err = write(sock[1], "AT+BIND?\r", 9);
- ASSERT_EQ(err, 9);
- slc_cb(slc_cb_data);
-
- /* Assert "\r\n+BIND: 2,1\r\n" response is received */
- err = read(sock[1], buf, 256);
-
- chp = strstr(buf, "\r\n+BIND: 2,1\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
- chp = strstr(buf, "\r\nOK\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- ASSERT_EQ(1, slc_initialized_cb_called);
-
- err = write(sock[1], "AT+VGS=13\r", 10);
- ASSERT_EQ(err, 10);
- slc_cb(slc_cb_data);
-
- err = read(sock[1], buf, 256);
-
- chp = strstr(buf, "\r\nOK\r\n");
- ASSERT_NE((void*)NULL, (void*)chp);
-
- ASSERT_EQ(1, cras_bt_device_update_hardware_volume_called);
-
- hfp_slc_destroy(handle);
- cras_bt_event_log_deinit(btlog);
-}
-
TEST(HfpSlc, CodecNegotiation) {
int codec;
int err;
@@ -274,26 +167,37 @@ TEST(HfpSlc, CodecNegotiation) {
codec = hfp_slc_get_selected_codec(handle);
EXPECT_EQ(HFP_CODEC_ID_MSBC, codec);
- /* Fake HF selects mSBC codec. */
- err = write(sock[1], "AT+BCS=2\r", 9);
+ /* Assert CRAS initiates codec selection to mSBC. */
+ memset(buf, 0, 256);
+ err = read(sock[1], buf, 256);
+ pos = strstr(buf, "\r\n+BCS:2\r\n");
+ ASSERT_NE((void*)NULL, pos);
+
+ err = write(sock[1], "AT+VGS=9\r", 9);
ASSERT_EQ(err, 9);
+ slc_cb(slc_cb_data);
- err = hfp_slc_codec_connection_setup(handle);
/* Assert CRAS initiates codec selection to mSBC. */
memset(buf, 0, 256);
err = read(sock[1], buf, 256);
pos = strstr(buf, "\r\n+BCS:2\r\n");
ASSERT_NE((void*)NULL, pos);
- err = write(sock[1], "AT+VGS=9\r", 9);
+ /* Fake that receiving codec selection from HF. */
+ err = write(sock[1], "AT+BCS=2\r", 9);
ASSERT_EQ(err, 9);
slc_cb(slc_cb_data);
+ memset(buf, 0, 256);
+ err = read(sock[1], buf, 256);
+ pos = strstr(buf, "\r\n+BCS:2\r\n");
+ ASSERT_EQ((void*)NULL, pos);
+
hfp_slc_destroy(handle);
cras_bt_event_log_deinit(btlog);
}
-TEST(HfpSlc, CodecNegotiationCapabilityChanged) {
+TEST(HfpSlc, CodecNegotiationTimeout) {
int codec;
int err;
int sock[2];
@@ -327,41 +231,30 @@ TEST(HfpSlc, CodecNegotiationCapabilityChanged) {
ASSERT_EQ(err, 16);
slc_cb(slc_cb_data);
+ ASSERT_NE((void*)NULL, cras_tm_timer_cb);
+
/* Assert that AG side prefers mSBC codec. */
codec = hfp_slc_get_selected_codec(handle);
EXPECT_EQ(HFP_CODEC_ID_MSBC, codec);
- /* Fake HF selects mSBC codec. */
- err = write(sock[1], "AT+BCS=2\r", 9);
- ASSERT_EQ(err, 9);
-
- err = hfp_slc_codec_connection_setup(handle);
/* Assert CRAS initiates codec selection to mSBC. */
memset(buf, 0, 256);
err = read(sock[1], buf, 256);
pos = strstr(buf, "\r\n+BCS:2\r\n");
ASSERT_NE((void*)NULL, pos);
- /* Fake that HF changes supported codecs. */
- err = write(sock[1], "AT+BAC=1\r", 9);
- ASSERT_EQ(err, 9);
- slc_cb(slc_cb_data);
- err = read(sock[1], buf, 256);
+ /* Assume codec negotiation failed. so timeout is reached. */
+ cras_tm_timer_cb(NULL, cras_tm_timer_cb_data);
- /* Fake HF selects CVSD codec. */
- err = write(sock[1], "AT+BCS=1\r", 9);
- ASSERT_EQ(err, 9);
+ codec = hfp_slc_get_selected_codec(handle);
+ EXPECT_EQ(HFP_CODEC_ID_CVSD, codec);
- err = hfp_slc_codec_connection_setup(handle);
- /* Assert CRAS initiates codec selection to CVSD. */
+ /* Expects CRAS fallback and selects to CVSD codec. */
memset(buf, 0, 256);
err = read(sock[1], buf, 256);
pos = strstr(buf, "\r\n+BCS:1\r\n");
ASSERT_NE((void*)NULL, pos);
- codec = hfp_slc_get_selected_codec(handle);
- EXPECT_EQ(HFP_CODEC_ID_CVSD, codec);
-
hfp_slc_destroy(handle);
cras_bt_event_log_deinit(btlog);
}
@@ -393,20 +286,11 @@ int cras_system_add_select_fd(int fd,
void cras_system_rm_select_fd(int fd) {}
-const char* cras_bt_device_address(struct cras_bt_device* device) {
- return "";
-}
-
void cras_bt_device_update_hardware_volume(struct cras_bt_device* device,
int volume) {
cras_bt_device_update_hardware_volume_called++;
}
-void cras_observer_notify_bt_battery_changed(const char* address,
- uint32_t level) {
- cras_observer_notify_bt_batter_changed_called++;
-}
-
/* To return fake errno */
int* __errno_location() {
return &fake_errno;
@@ -426,13 +310,6 @@ struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
return reinterpret_cast<struct cras_timer*>(0x404);
}
-int cras_poll(struct pollfd* fds,
- nfds_t nfds,
- struct timespec* timeout,
- const sigset_t* sigmask) {
- return 1;
-}
-
void cras_tm_cancel_timer(struct cras_tm* tm, struct cras_timer* t) {}
}
diff --git a/cras/src/tests/input_data_unittest.cc b/cras/src/tests/input_data_unittest.cc
index 3c6ae9f1..f1c3fd71 100644
--- a/cras/src/tests/input_data_unittest.cc
+++ b/cras/src/tests/input_data_unittest.cc
@@ -14,16 +14,12 @@ extern "C" {
namespace {
-#define FAKE_CRAS_APM_PTR reinterpret_cast<struct cras_apm*>(0x99)
-
#ifdef HAVE_WEBRTC_APM
static struct cras_audio_area apm_area;
static unsigned int cras_apm_list_process_offset_val;
static unsigned int cras_apm_list_process_called;
-static struct cras_apm* cras_apm_list_get_active_ret = NULL;
-static bool cras_apm_list_get_use_tuned_settings_val;
+static struct cras_apm* cras_apm_list_get_ret = NULL;
#endif // HAVE_WEBRTC_APM
-static float cras_rstream_get_volume_scaler_val;
TEST(InputData, GetForInputStream) {
void* dev_ptr = reinterpret_cast<void*>(0x123);
@@ -59,7 +55,7 @@ TEST(InputData, GetForInputStream) {
EXPECT_EQ(600, offset);
#ifdef HAVE_WEBRTC_APM
EXPECT_EQ(0, cras_apm_list_process_called);
- cras_apm_list_get_active_ret = FAKE_CRAS_APM_PTR;
+ cras_apm_list_get_ret = reinterpret_cast<struct cras_apm*>(0x99);
#endif // HAVE_WEBRTC_APM
input_data_get_for_stream(data, &stream, offsets, &area, &offset);
@@ -79,44 +75,10 @@ TEST(InputData, GetForInputStream) {
buffer_share_destroy(offsets);
}
-TEST(InputData, GetSWCaptureGain) {
- void* dev_ptr = reinterpret_cast<void*>(0x123);
- struct input_data* data = NULL;
- struct cras_rstream stream;
- float gain;
-
- cras_rstream_get_volume_scaler_val = 0.8f;
- stream.stream_id = 123;
-
-#ifdef HAVE_WEBRTC_APM
- data = input_data_create(dev_ptr);
-
- cras_apm_list_get_active_ret = FAKE_CRAS_APM_PTR;
- cras_apm_list_get_use_tuned_settings_val = 1;
- gain = input_data_get_software_gain_scaler(data, 0.7f, &stream);
- EXPECT_FLOAT_EQ(1.0f, gain);
-
- cras_apm_list_get_active_ret = NULL;
- gain = input_data_get_software_gain_scaler(data, 0.7f, &stream);
- EXPECT_FLOAT_EQ(0.56f, gain);
-
- cras_apm_list_get_active_ret = FAKE_CRAS_APM_PTR;
- cras_apm_list_get_use_tuned_settings_val = 0;
- gain = input_data_get_software_gain_scaler(data, 0.6f, &stream);
- EXPECT_FLOAT_EQ(0.48f, gain);
- input_data_destroy(&data);
-#endif // HAVE_WEBRTC_APM
-
- data = input_data_create(dev_ptr);
- gain = input_data_get_software_gain_scaler(data, 0.6f, &stream);
- EXPECT_FLOAT_EQ(0.48f, gain);
- input_data_destroy(&data);
-}
-
extern "C" {
#ifdef HAVE_WEBRTC_APM
-struct cras_apm* cras_apm_list_get_active_apm(void* stream_ptr, void* dev_ptr) {
- return cras_apm_list_get_active_ret;
+struct cras_apm* cras_apm_list_get(struct cras_apm_list* list, void* dev_ptr) {
+ return cras_apm_list_get_ret;
}
int cras_apm_list_process(struct cras_apm* apm,
struct float_buffer* input,
@@ -129,16 +91,10 @@ int cras_apm_list_process(struct cras_apm* apm,
struct cras_audio_area* cras_apm_list_get_processed(struct cras_apm* apm) {
return &apm_area;
}
-void cras_apm_list_remove_apm(struct cras_apm_list* list, void* dev_ptr) {}
+void cras_apm_list_remove(struct cras_apm_list* list, void* dev_ptr) {}
void cras_apm_list_put_processed(struct cras_apm* apm, unsigned int frames) {}
-bool cras_apm_list_get_use_tuned_settings(struct cras_apm* apm) {
- return cras_apm_list_get_use_tuned_settings_val;
-}
#endif // HAVE_WEBRTC_APM
-float cras_rstream_get_volume_scaler(struct cras_rstream* rstream) {
- return cras_rstream_get_volume_scaler_val;
-}
} // extern "C"
} // namespace
diff --git a/cras/src/tests/iodev_list_unittest.cc b/cras/src/tests/iodev_list_unittest.cc
index 8c71214a..798f2955 100644
--- a/cras/src/tests/iodev_list_unittest.cc
+++ b/cras/src/tests/iodev_list_unittest.cc
@@ -12,7 +12,6 @@ extern "C" {
#include "audio_thread.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
-#include "cras_main_thread_log.h"
#include "cras_observer_ops.h"
#include "cras_ramp.h"
#include "cras_rstream.h"
@@ -44,8 +43,8 @@ static struct audio_thread thread;
static struct cras_iodev loopback_input;
static int cras_iodev_close_called;
static struct cras_iodev* cras_iodev_close_dev;
-static struct cras_iodev mock_hotword_iodev;
-static struct cras_iodev mock_empty_iodev[2];
+static struct cras_iodev dummy_hotword_iodev;
+static struct cras_iodev dummy_empty_iodev[2];
static stream_callback* stream_add_cb;
static stream_callback* stream_rm_cb;
static struct cras_rstream* stream_list_get_ret;
@@ -84,7 +83,6 @@ static size_t cras_observer_notify_node_left_right_swapped_called;
static size_t cras_observer_notify_input_node_gain_called;
static int cras_iodev_open_called;
static int cras_iodev_open_ret[8];
-static struct cras_audio_format cras_iodev_open_fmt;
static int set_mute_called;
static std::vector<struct cras_iodev*> set_mute_dev_vector;
static std::vector<unsigned int> audio_thread_dev_start_ramp_dev_vector;
@@ -95,7 +93,6 @@ static struct cras_rstream* audio_thread_disconnect_stream_stream;
static int audio_thread_disconnect_stream_called;
static struct cras_iodev fake_sco_in_dev, fake_sco_out_dev;
static struct cras_ionode fake_sco_in_node, fake_sco_out_node;
-static int server_state_hotword_pause_at_suspend;
int dev_idx_in_vector(std::vector<unsigned int> v, unsigned int idx) {
return std::find(v.begin(), v.end(), idx) != v.end();
@@ -132,10 +129,6 @@ class IoDevTestSuite : public testing::Test {
channel_counts_[0] = 2;
channel_counts_[1] = 0;
- fmt_.format = SND_PCM_FORMAT_S16_LE;
- fmt_.frame_rate = 48000;
- fmt_.num_channels = 2;
-
memset(&d1_, 0, sizeof(d1_));
memset(&d2_, 0, sizeof(d2_));
memset(&d3_, 0, sizeof(d3_));
@@ -234,17 +227,14 @@ class IoDevTestSuite : public testing::Test {
DL_APPEND(fake_sco_out_dev.nodes, &fake_sco_out_node);
fake_sco_in_node.is_sco_pcm = 0;
fake_sco_out_node.is_sco_pcm = 0;
- mock_empty_iodev[0].state = CRAS_IODEV_STATE_CLOSE;
- mock_empty_iodev[0].update_active_node = update_active_node;
- mock_empty_iodev[1].state = CRAS_IODEV_STATE_CLOSE;
- mock_empty_iodev[1].update_active_node = update_active_node;
- mock_hotword_iodev.update_active_node = update_active_node;
- server_state_hotword_pause_at_suspend = 0;
+ dummy_empty_iodev[0].state = CRAS_IODEV_STATE_CLOSE;
+ dummy_empty_iodev[0].update_active_node = update_active_node;
+ dummy_empty_iodev[1].state = CRAS_IODEV_STATE_CLOSE;
+ dummy_empty_iodev[1].update_active_node = update_active_node;
+ dummy_hotword_iodev.update_active_node = update_active_node;
}
- virtual void TearDown() {
- cras_iodev_list_reset();
- }
+ virtual void TearDown() { cras_iodev_list_reset(); }
static void set_volume_1(struct cras_iodev* iodev) { set_volume_1_called_++; }
@@ -276,7 +266,6 @@ class IoDevTestSuite : public testing::Test {
struct cras_iodev d1_;
struct cras_iodev d2_;
struct cras_iodev d3_;
- struct cras_audio_format fmt_;
size_t sample_rates_[3];
size_t channel_counts_[2];
static int set_volume_1_called_;
@@ -314,8 +303,6 @@ TEST_F(IoDevTestSuite, SetSuspendResume) {
rc = cras_iodev_list_add_output(&d1_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
-
audio_thread_add_open_dev_called = 0;
cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 1));
@@ -361,138 +348,6 @@ TEST_F(IoDevTestSuite, SetSuspendResume) {
EXPECT_EQ(3, cras_observer_notify_active_node_called);
}
-/* Check that the suspend/resume call of active iodev will be triggered and
- * fallback device will be transciently enabled while adding a new stream whose
- * channel count is higher than the active iodev. */
-TEST_F(IoDevTestSuite, ReopenDevForHigherChannels) {
- struct cras_rstream rstream, rstream2;
- struct cras_rstream* stream_list = NULL;
- int rc;
-
- memset(&rstream, 0, sizeof(rstream));
- memset(&rstream2, 0, sizeof(rstream2));
- rstream.format = fmt_;
- rstream2.format = fmt_;
- rstream2.format.num_channels = 6;
-
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_OUTPUT;
- rc = cras_iodev_list_add_output(&d1_);
- ASSERT_EQ(0, rc);
-
- d1_.format = &fmt_;
- d1_.info.max_supported_channels = 2;
-
- audio_thread_add_open_dev_called = 0;
- cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
- cras_make_node_id(d1_.info.idx, 1));
- DL_APPEND(stream_list, &rstream);
- stream_list_get_ret = stream_list;
- stream_add_cb(&rstream);
- EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
- EXPECT_EQ(1, cras_iodev_open_called);
- EXPECT_EQ(2, cras_iodev_open_fmt.num_channels);
-
- audio_thread_add_stream_called = 0;
- audio_thread_add_open_dev_called = 0;
- cras_iodev_open_called = 0;
-
- /* stream_list should be descending ordered by channel count. */
- DL_PREPEND(stream_list, &rstream2);
- stream_list_get_ret = stream_list;
- stream_add_cb(&rstream2);
- /* The channel count(=6) of rstream2 exceeds d1's max_supported_channels(=2),
- * rstream2 will be added directly to d1, which will not be re-opened. */
- EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(0, audio_thread_add_open_dev_called);
- EXPECT_EQ(0, cras_iodev_open_called);
-
- d1_.info.max_supported_channels = 6;
- stream_rm_cb(&rstream2);
-
- audio_thread_add_stream_called = 0;
- audio_thread_add_open_dev_called = 0;
- cras_iodev_open_called = 0;
-
- stream_add_cb(&rstream2);
- /* Added both rstreams to fallback device, then re-opened d1. */
- EXPECT_EQ(4, audio_thread_add_stream_called);
- EXPECT_EQ(2, audio_thread_add_open_dev_called);
- EXPECT_EQ(2, cras_iodev_open_called);
- EXPECT_EQ(6, cras_iodev_open_fmt.num_channels);
-
- cras_iodev_list_deinit();
-}
-
-/* Check that after resume, all output devices enter ramp mute state if there is
- * any output stream. */
-TEST_F(IoDevTestSuite, RampMuteAfterResume) {
- struct cras_rstream rstream, rstream2;
- struct cras_rstream* stream_list = NULL;
- int rc;
-
- memset(&rstream, 0, sizeof(rstream));
-
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_OUTPUT;
- d1_.initial_ramp_request = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
- rc = cras_iodev_list_add_output(&d1_);
- ASSERT_EQ(0, rc);
-
- d2_.direction = CRAS_STREAM_INPUT;
- d2_.initial_ramp_request = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
- rc = cras_iodev_list_add_input(&d2_);
- ASSERT_EQ(0, rc);
-
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
- audio_thread_add_open_dev_called = 0;
- cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
- cras_make_node_id(d1_.info.idx, 1));
-
- rstream.direction = CRAS_STREAM_OUTPUT;
- DL_APPEND(stream_list, &rstream);
- stream_add_cb(&rstream);
- EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
-
- rstream2.direction = CRAS_STREAM_INPUT;
- DL_APPEND(stream_list, &rstream2);
- stream_add_cb(&rstream2);
-
- /* Suspend and resume */
- observer_ops->suspend_changed(NULL, 1);
- stream_list_get_ret = stream_list;
- observer_ops->suspend_changed(NULL, 0);
-
- /* Test only output device that has stream will be muted after resume */
- EXPECT_EQ(d1_.initial_ramp_request, CRAS_IODEV_RAMP_REQUEST_RESUME_MUTE);
- EXPECT_EQ(CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK,
- d2_.initial_ramp_request);
-
- /* Reset d1 ramp_mute and remove output stream to test again */
- d1_.initial_ramp_request = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
- DL_DELETE(stream_list, &rstream);
- stream_list_get_ret = stream_list;
- stream_rm_cb(&rstream);
-
- /* Suspend and resume */
- observer_ops->suspend_changed(NULL, 1);
- stream_list_get_ret = stream_list;
- observer_ops->suspend_changed(NULL, 0);
-
- EXPECT_EQ(CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK,
- d1_.initial_ramp_request);
- EXPECT_EQ(CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK,
- d2_.initial_ramp_request);
-
- cras_iodev_list_deinit();
-}
-
TEST_F(IoDevTestSuite, InitDevFailShouldEnableFallback) {
int rc;
struct cras_rstream rstream;
@@ -505,8 +360,6 @@ TEST_F(IoDevTestSuite, InitDevFailShouldEnableFallback) {
rc = cras_iodev_list_add_output(&d1_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
-
cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 0));
@@ -540,9 +393,6 @@ TEST_F(IoDevTestSuite, InitDevWithEchoRef) {
rc = cras_iodev_list_add_input(&d2_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 0));
/* No close call happened, because no stream exists. */
@@ -588,9 +438,6 @@ TEST_F(IoDevTestSuite, SelectNodeOpenFailShouldScheduleRetry) {
rc = cras_iodev_list_add_output(&d2_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 1));
DL_APPEND(stream_list, &rstream);
@@ -660,15 +507,12 @@ TEST_F(IoDevTestSuite, InitDevFailShouldScheduleRetry) {
struct cras_rstream* stream_list = NULL;
memset(&rstream, 0, sizeof(rstream));
- rstream.format = fmt_;
cras_iodev_list_init();
d1_.direction = CRAS_STREAM_OUTPUT;
rc = cras_iodev_list_add_output(&d1_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
-
cras_iodev_list_select_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 0));
@@ -683,7 +527,8 @@ TEST_F(IoDevTestSuite, InitDevFailShouldScheduleRetry) {
EXPECT_EQ(2, cras_iodev_open_called);
EXPECT_EQ(1, audio_thread_add_stream_called);
EXPECT_EQ(0, update_active_node_called);
- EXPECT_EQ(&mock_empty_iodev[CRAS_STREAM_OUTPUT], audio_thread_add_stream_dev);
+ EXPECT_EQ(&dummy_empty_iodev[CRAS_STREAM_OUTPUT],
+ audio_thread_add_stream_dev);
EXPECT_NE((void*)NULL, cras_tm_timer_cb);
EXPECT_EQ(1, cras_tm_create_timer_called);
@@ -694,7 +539,6 @@ TEST_F(IoDevTestSuite, InitDevFailShouldScheduleRetry) {
EXPECT_EQ(1, cras_tm_create_timer_called);
EXPECT_EQ(1, audio_thread_add_stream_called);
- mock_empty_iodev[CRAS_STREAM_OUTPUT].format = &fmt_;
cras_tm_timer_cb = NULL;
cras_iodev_open_ret[3] = -5;
stream_add_cb(&rstream);
@@ -718,8 +562,6 @@ TEST_F(IoDevTestSuite, PinnedStreamInitFailShouldScheduleRetry) {
rc = cras_iodev_list_add_output(&d1_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
-
rstream.is_pinned = 1;
rstream.pinned_dev_idx = d1_.info.idx;
@@ -775,9 +617,6 @@ TEST_F(IoDevTestSuite, SelectNode) {
rc = cras_iodev_list_add_output(&d2_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
audio_thread_add_open_dev_called = 0;
audio_thread_rm_open_dev_called = 0;
@@ -848,9 +687,6 @@ TEST_F(IoDevTestSuite, SelectPreviouslyEnabledNode) {
rc = cras_iodev_list_add_output(&d2_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
audio_thread_add_open_dev_called = 0;
audio_thread_rm_open_dev_called = 0;
device_enabled_count = 0;
@@ -983,7 +819,6 @@ TEST_F(IoDevTestSuite, AddWrongDirection) {
TEST_F(IoDevTestSuite, AddRemoveOutput) {
struct cras_iodev_info* dev_info;
int rc;
- cras_iodev_list_init();
rc = cras_iodev_list_add_output(&d1_);
EXPECT_EQ(0, rc);
@@ -1015,7 +850,6 @@ TEST_F(IoDevTestSuite, AddRemoveOutput) {
EXPECT_EQ(0, rc);
free(dev_info);
EXPECT_EQ(0, cras_observer_notify_active_node_called);
- cras_iodev_list_deinit();
}
// Test output_mute_changed callback.
@@ -1094,56 +928,39 @@ TEST_F(IoDevTestSuite, OutputMuteChangedToUnmute) {
// Test enable/disable an iodev.
TEST_F(IoDevTestSuite, EnableDisableDevice) {
- struct cras_rstream rstream;
- cras_iodev_list_init();
device_enabled_count = 0;
device_disabled_count = 0;
- memset(&rstream, 0, sizeof(rstream));
EXPECT_EQ(0, cras_iodev_list_add_output(&d1_));
EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
device_enabled_cb, device_disabled_cb, (void*)0xABCD));
- // Enable a device, fallback should be diabled accordingly.
+ // Enable a device.
cras_iodev_list_enable_dev(&d1_);
EXPECT_EQ(&d1_, device_enabled_dev);
EXPECT_EQ((void*)0xABCD, device_enabled_cb_data);
EXPECT_EQ(1, device_enabled_count);
- EXPECT_EQ(1, device_disabled_count);
EXPECT_EQ(&d1_, cras_iodev_list_get_first_enabled_iodev(CRAS_STREAM_OUTPUT));
- // Connect a normal stream.
- cras_iodev_open_called = 0;
- stream_add_cb(&rstream);
- EXPECT_EQ(1, cras_iodev_open_called);
-
- stream_list_has_pinned_stream_ret[d1_.info.idx] = 0;
- // Disable a device. Expect dev is closed because there's no pinned stream.
- update_active_node_called = 0;
+ // Disable a device.
cras_iodev_list_disable_dev(&d1_, false);
EXPECT_EQ(&d1_, device_disabled_dev);
- EXPECT_EQ(2, device_disabled_count);
+ EXPECT_EQ(1, device_disabled_count);
EXPECT_EQ((void*)0xABCD, device_disabled_cb_data);
- EXPECT_EQ(1, audio_thread_rm_open_dev_called);
- EXPECT_EQ(1, cras_iodev_close_called);
- EXPECT_EQ(&d1_, cras_iodev_close_dev);
- EXPECT_EQ(1, update_active_node_called);
-
EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(
device_enabled_cb, device_disabled_cb, (void*)0xCDEF));
EXPECT_EQ(2, cras_observer_notify_active_node_called);
EXPECT_EQ(0, cras_iodev_list_set_device_enabled_callback(NULL, NULL, NULL));
- cras_iodev_list_deinit();
}
// Test adding/removing an input dev to the list.
TEST_F(IoDevTestSuite, AddRemoveInput) {
struct cras_iodev_info* dev_info;
int rc, i;
- uint64_t found_mask;
+ uint32_t found_mask;
d1_.direction = CRAS_STREAM_INPUT;
d2_.direction = CRAS_STREAM_INPUT;
@@ -1176,8 +993,8 @@ TEST_F(IoDevTestSuite, AddRemoveInput) {
found_mask = 0;
for (i = 0; i < rc; i++) {
uint32_t idx = dev_info[i].idx;
- EXPECT_EQ(0, (found_mask & (static_cast<uint64_t>(1) << idx)));
- found_mask |= (static_cast<uint64_t>(1) << idx);
+ EXPECT_EQ(0, (found_mask & (1 << idx)));
+ found_mask |= (1 << idx);
}
}
if (rc > 0)
@@ -1213,7 +1030,6 @@ TEST_F(IoDevTestSuite, AddRemoveInputNoSem) {
d2_.direction = CRAS_STREAM_INPUT;
server_state_update_begin_return = NULL;
- cras_iodev_list_init();
rc = cras_iodev_list_add_input(&d1_);
EXPECT_EQ(0, rc);
@@ -1224,7 +1040,6 @@ TEST_F(IoDevTestSuite, AddRemoveInputNoSem) {
EXPECT_EQ(0, cras_iodev_list_rm_input(&d1_));
EXPECT_EQ(0, cras_iodev_list_rm_input(&d2_));
- cras_iodev_list_deinit();
}
// Test removing the last input.
@@ -1438,10 +1253,6 @@ TEST_F(IoDevTestSuite, AddActiveNode) {
rc = cras_iodev_list_add_output(&d3_);
ASSERT_EQ(0, rc);
- d1_.format = &fmt_;
- d2_.format = &fmt_;
- d3_.format = &fmt_;
-
audio_thread_add_open_dev_called = 0;
cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d3_.info.idx, 1));
@@ -1478,57 +1289,6 @@ TEST_F(IoDevTestSuite, AddActiveNode) {
cras_iodev_list_deinit();
}
-TEST_F(IoDevTestSuite, OutputDevIdleClose) {
- int rc;
- struct cras_rstream rstream;
-
- memset(&rstream, 0, sizeof(rstream));
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_OUTPUT;
- rc = cras_iodev_list_add_output(&d1_);
- EXPECT_EQ(0, rc);
-
- d1_.format = &fmt_;
-
- audio_thread_add_open_dev_called = 0;
- cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
- cras_make_node_id(d1_.info.idx, 1));
- EXPECT_EQ(0, audio_thread_add_open_dev_called);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
-
- // If a stream is added, the device should be opened.
- stream_add_cb(&rstream);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
-
- audio_thread_rm_open_dev_called = 0;
- audio_thread_drain_stream_return = 0;
- clock_gettime_retspec.tv_sec = 15;
- stream_rm_cb(&rstream);
- EXPECT_EQ(1, audio_thread_drain_stream_called);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
- EXPECT_EQ(1, cras_tm_create_timer_called);
-
- // Expect no rm dev happen because idle time not yet expire, and
- // new timer should be scheduled for the rest of the idle time.
- clock_gettime_retspec.tv_sec += 7;
- cras_tm_timer_cb(NULL, NULL);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
- EXPECT_EQ(2, cras_tm_create_timer_called);
-
- // Expect d1_ be closed upon unplug, and the timer stay armed.
- cras_iodev_list_rm_output(&d1_);
- EXPECT_EQ(1, audio_thread_rm_open_dev_called);
- EXPECT_EQ(0, cras_tm_cancel_timer_called);
-
- // When timer eventually fired expect there's no more new
- // timer scheduled because d1_ has closed already.
- clock_gettime_retspec.tv_sec += 4;
- cras_tm_timer_cb(NULL, NULL);
- EXPECT_EQ(2, cras_tm_create_timer_called);
- cras_iodev_list_deinit();
-}
-
TEST_F(IoDevTestSuite, DrainTimerCancel) {
int rc;
struct cras_rstream rstream;
@@ -1541,8 +1301,6 @@ TEST_F(IoDevTestSuite, DrainTimerCancel) {
rc = cras_iodev_list_add_output(&d1_);
EXPECT_EQ(0, rc);
- d1_.format = &fmt_;
-
audio_thread_add_open_dev_called = 0;
cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
cras_make_node_id(d1_.info.idx, 1));
@@ -1607,107 +1365,6 @@ TEST_F(IoDevTestSuite, RemoveThenSelectActiveNode) {
cras_iodev_list_deinit();
}
-TEST_F(IoDevTestSuite, CloseDevWithPinnedStream) {
- int rc;
- struct cras_rstream rstream1, rstream2;
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_OUTPUT;
- d1_.info.idx = 1;
- rc = cras_iodev_list_add_output(&d1_);
- EXPECT_EQ(0, rc);
-
- memset(&rstream1, 0, sizeof(rstream1));
- memset(&rstream2, 0, sizeof(rstream2));
- rstream2.is_pinned = 1;
- rstream2.pinned_dev_idx = d1_.info.idx;
-
- d1_.format = &fmt_;
- audio_thread_add_open_dev_called = 0;
- EXPECT_EQ(0, audio_thread_add_open_dev_called);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
-
- // Add a normal stream
- stream_add_cb(&rstream1);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
-
- // Add a pinned stream, expect another dev open call triggered.
- cras_iodev_open_called = 0;
- stream_add_cb(&rstream2);
- EXPECT_EQ(1, cras_iodev_open_called);
-
- // Force disable d1_ and make sure d1_ gets closed.
- audio_thread_rm_open_dev_called = 0;
- update_active_node_called = 0;
- cras_iodev_close_called = 0;
- cras_iodev_list_disable_dev(&d1_, 1);
- EXPECT_EQ(1, audio_thread_rm_open_dev_called);
- EXPECT_EQ(1, cras_iodev_close_called);
- EXPECT_EQ(&d1_, cras_iodev_close_dev);
- EXPECT_EQ(1, update_active_node_called);
-
- // Add back the two streams, one normal one pinned.
- audio_thread_add_open_dev_called = 0;
- audio_thread_rm_open_dev_called = 0;
- cras_iodev_open_called = 0;
- stream_add_cb(&rstream2);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
- EXPECT_EQ(1, cras_iodev_open_called);
- stream_add_cb(&rstream1);
-
- // Suspend d1_ and make sure d1_ gets closed.
- update_active_node_called = 0;
- cras_iodev_close_called = 0;
- cras_iodev_list_suspend_dev(d1_.info.idx);
- EXPECT_EQ(1, audio_thread_rm_open_dev_called);
- EXPECT_EQ(1, cras_iodev_close_called);
- EXPECT_EQ(&d1_, cras_iodev_close_dev);
- EXPECT_EQ(1, update_active_node_called);
-
- cras_iodev_list_resume_dev(d1_.info.idx);
-
- cras_iodev_list_deinit();
-}
-
-TEST_F(IoDevTestSuite, DisableDevWithPinnedStream) {
- int rc;
- struct cras_rstream rstream1;
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_OUTPUT;
- rc = cras_iodev_list_add_output(&d1_);
- EXPECT_EQ(0, rc);
-
- memset(&rstream1, 0, sizeof(rstream1));
- rstream1.is_pinned = 1;
- rstream1.pinned_dev_idx = d1_.info.idx;
-
- d1_.format = &fmt_;
- audio_thread_add_open_dev_called = 0;
- cras_iodev_list_add_active_node(CRAS_STREAM_OUTPUT,
- cras_make_node_id(d1_.info.idx, 1));
- EXPECT_EQ(0, audio_thread_add_open_dev_called);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
-
- // Add a pinned stream.
- cras_iodev_open_called = 0;
- stream_add_cb(&rstream1);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
- EXPECT_EQ(1, cras_iodev_open_called);
-
- // Disable d1_ expect no close dev triggered because pinned stream.
- stream_list_has_pinned_stream_ret[d1_.info.idx] = 1;
- audio_thread_rm_open_dev_called = 0;
- update_active_node_called = 0;
- cras_iodev_close_called = 0;
- cras_iodev_list_disable_dev(&d1_, 0);
- EXPECT_EQ(0, audio_thread_rm_open_dev_called);
- EXPECT_EQ(0, cras_iodev_close_called);
- EXPECT_EQ(0, update_active_node_called);
-
- cras_iodev_list_deinit();
-}
-
TEST_F(IoDevTestSuite, AddRemovePinnedStream) {
struct cras_rstream rstream;
@@ -1726,9 +1383,6 @@ TEST_F(IoDevTestSuite, AddRemovePinnedStream) {
d2_.info.idx = 2;
EXPECT_EQ(0, cras_iodev_list_add_output(&d2_));
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
// Setup pinned stream.
memset(&rstream, 0, sizeof(rstream));
rstream.is_pinned = 1;
@@ -1753,7 +1407,7 @@ TEST_F(IoDevTestSuite, AddRemovePinnedStream) {
EXPECT_EQ(2, update_active_node_called);
// Unselect d1_ and select to d2_
EXPECT_EQ(&d2_, update_active_node_iodev_val[0]);
- EXPECT_EQ(&mock_empty_iodev[CRAS_STREAM_OUTPUT],
+ EXPECT_EQ(&dummy_empty_iodev[CRAS_STREAM_OUTPUT],
update_active_node_iodev_val[1]);
// Remove pinned stream from d1, check d1 is closed after stream removed.
@@ -1788,9 +1442,6 @@ TEST_F(IoDevTestSuite, SuspendResumePinnedStream) {
d2_.direction = CRAS_STREAM_OUTPUT;
EXPECT_EQ(0, cras_iodev_list_add_output(&d2_));
- d1_.format = &fmt_;
- d2_.format = &fmt_;
-
// Setup pinned stream.
memset(&rstream, 0, sizeof(rstream));
rstream.is_pinned = 1;
@@ -1846,8 +1497,6 @@ TEST_F(IoDevTestSuite, HotwordStreamsAddedThenSuspendResume) {
d1_.direction = CRAS_STREAM_INPUT;
EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
- d1_.format = &fmt_;
-
memset(&rstream, 0, sizeof(rstream));
rstream.is_pinned = 1;
rstream.pinned_dev_idx = d1_.info.idx;
@@ -1870,14 +1519,14 @@ TEST_F(IoDevTestSuite, HotwordStreamsAddedThenSuspendResume) {
EXPECT_EQ(&d1_, audio_thread_disconnect_stream_dev);
EXPECT_EQ(2, audio_thread_add_stream_called);
EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_add_stream_dev);
+ EXPECT_EQ(&dummy_hotword_iodev, audio_thread_add_stream_dev);
/* Resume hotword streams, verify the stream disconnects from
* the empty iodev and connects back to the real hotword iodev. */
EXPECT_EQ(0, cras_iodev_list_resume_hotword_stream());
EXPECT_EQ(2, audio_thread_disconnect_stream_called);
EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_disconnect_stream_dev);
+ EXPECT_EQ(&dummy_hotword_iodev, audio_thread_disconnect_stream_dev);
EXPECT_EQ(3, audio_thread_add_stream_called);
EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
@@ -1893,8 +1542,6 @@ TEST_F(IoDevTestSuite, HotwordStreamsAddedAfterSuspend) {
d1_.direction = CRAS_STREAM_INPUT;
EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
- d1_.format = &fmt_;
-
memset(&rstream, 0, sizeof(rstream));
rstream.is_pinned = 1;
rstream.pinned_dev_idx = d1_.info.idx;
@@ -1911,7 +1558,7 @@ TEST_F(IoDevTestSuite, HotwordStreamsAddedAfterSuspend) {
/* Hotword stream connected, verify it is added to the empty iodev. */
EXPECT_EQ(0, stream_add_cb(&rstream));
EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_add_stream_dev);
+ EXPECT_EQ(&dummy_hotword_iodev, audio_thread_add_stream_dev);
EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
/* Resume hotword streams, now the existing hotword stream should disconnect
@@ -1919,7 +1566,7 @@ TEST_F(IoDevTestSuite, HotwordStreamsAddedAfterSuspend) {
EXPECT_EQ(0, cras_iodev_list_resume_hotword_stream());
EXPECT_EQ(1, audio_thread_disconnect_stream_called);
EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_disconnect_stream_dev);
+ EXPECT_EQ(&dummy_hotword_iodev, audio_thread_disconnect_stream_dev);
EXPECT_EQ(2, audio_thread_add_stream_called);
EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
@@ -1944,105 +1591,6 @@ TEST_F(IoDevTestSuite, GetSCOPCMIodevs) {
cras_iodev_list_deinit();
}
-TEST_F(IoDevTestSuite, HotwordStreamsPausedAtSystemSuspend) {
- struct cras_rstream rstream;
- struct cras_rstream* stream_list = NULL;
- cras_iodev_list_init();
-
- node1.type = CRAS_NODE_TYPE_HOTWORD;
- d1_.direction = CRAS_STREAM_INPUT;
- EXPECT_EQ(0, cras_iodev_list_add_input(&d1_));
-
- d1_.format = &fmt_;
-
- memset(&rstream, 0, sizeof(rstream));
- rstream.is_pinned = 1;
- rstream.pinned_dev_idx = d1_.info.idx;
- rstream.flags = HOTWORD_STREAM;
-
- /* Add a hotword stream. */
- EXPECT_EQ(0, stream_add_cb(&rstream));
- EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
- EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
-
- DL_APPEND(stream_list, &rstream);
- stream_list_get_ret = stream_list;
-
- server_state_hotword_pause_at_suspend = 1;
-
- /* Trigger system suspend. Verify hotword stream is moved to empty dev. */
- observer_ops->suspend_changed(NULL, 1);
- EXPECT_EQ(1, audio_thread_disconnect_stream_called);
- EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
- EXPECT_EQ(&d1_, audio_thread_disconnect_stream_dev);
- EXPECT_EQ(2, audio_thread_add_stream_called);
- EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_add_stream_dev);
-
- /* Trigger system resume. Verify hotword stream is moved to real dev.*/
- observer_ops->suspend_changed(NULL, 0);
- EXPECT_EQ(2, audio_thread_disconnect_stream_called);
- EXPECT_EQ(&rstream, audio_thread_disconnect_stream_stream);
- EXPECT_EQ(&mock_hotword_iodev, audio_thread_disconnect_stream_dev);
- EXPECT_EQ(3, audio_thread_add_stream_called);
- EXPECT_EQ(&rstream, audio_thread_add_stream_stream);
- EXPECT_EQ(&d1_, audio_thread_add_stream_dev);
-
- server_state_hotword_pause_at_suspend = 0;
- audio_thread_disconnect_stream_called = 0;
- audio_thread_add_stream_called = 0;
-
- /* Trigger system suspend. Verify hotword stream is not touched. */
- observer_ops->suspend_changed(NULL, 1);
- EXPECT_EQ(0, audio_thread_disconnect_stream_called);
- EXPECT_EQ(0, audio_thread_add_stream_called);
-
- /* Trigger system resume. Verify hotword stream is not touched.*/
- observer_ops->suspend_changed(NULL, 0);
- EXPECT_EQ(0, audio_thread_disconnect_stream_called);
- EXPECT_EQ(0, audio_thread_add_stream_called);
-
- cras_iodev_list_deinit();
-}
-
-TEST_F(IoDevTestSuite, SetNoiseCancellation) {
- struct cras_rstream rstream;
- struct cras_rstream* stream_list = NULL;
- int rc;
-
- memset(&rstream, 0, sizeof(rstream));
-
- cras_iodev_list_init();
-
- d1_.direction = CRAS_STREAM_INPUT;
- rc = cras_iodev_list_add_input(&d1_);
- ASSERT_EQ(0, rc);
-
- d1_.format = &fmt_;
-
- rstream.direction = CRAS_STREAM_INPUT;
-
- audio_thread_add_open_dev_called = 0;
- audio_thread_rm_open_dev_called = 0;
- cras_iodev_list_add_active_node(CRAS_STREAM_INPUT,
- cras_make_node_id(d1_.info.idx, 1));
- DL_APPEND(stream_list, &rstream);
- stream_add_cb(&rstream);
- stream_list_get_ret = stream_list;
- EXPECT_EQ(1, audio_thread_add_stream_called);
- EXPECT_EQ(1, audio_thread_add_open_dev_called);
-
- // reset_for_noise_cancellation causes device suspend & resume
- // While suspending d1_: rm d1_, open fallback
- // While resuming d1_: rm fallback, open d1_
- cras_iodev_list_reset_for_noise_cancellation();
- EXPECT_EQ(3, audio_thread_add_open_dev_called);
- EXPECT_EQ(2, audio_thread_rm_open_dev_called);
-
- cras_iodev_list_deinit();
-}
-
} // namespace
int main(int argc, char** argv) {
@@ -2053,7 +1601,6 @@ int main(int argc, char** argv) {
extern "C" {
// Stubs
-struct main_thread_event_log* main_log;
struct cras_server_state* cras_system_state_update_begin() {
return server_state_update_begin_return;
@@ -2065,10 +1612,6 @@ int cras_system_get_mute() {
return system_get_mute_return;
}
-bool cras_system_get_noise_cancellation_enabled() {
- return false;
-}
-
struct audio_thread* audio_thread_create() {
return &thread;
}
@@ -2139,9 +1682,9 @@ struct cras_iodev* empty_iodev_create(enum CRAS_STREAM_DIRECTION direction,
enum CRAS_NODE_TYPE node_type) {
struct cras_iodev* dev;
if (node_type == CRAS_NODE_TYPE_HOTWORD) {
- dev = &mock_hotword_iodev;
+ dev = &dummy_hotword_iodev;
} else {
- dev = &mock_empty_iodev[direction];
+ dev = &dummy_empty_iodev[direction];
}
dev->direction = direction;
if (dev->active_node == NULL) {
@@ -2180,8 +1723,6 @@ int cras_iodev_open(struct cras_iodev* iodev,
const struct cras_audio_format* fmt) {
if (cras_iodev_open_ret[cras_iodev_open_called] == 0)
iodev->state = CRAS_IODEV_STATE_OPEN;
- cras_iodev_open_fmt = *fmt;
- iodev->format = &cras_iodev_open_fmt;
return cras_iodev_open_ret[cras_iodev_open_called++];
}
@@ -2189,7 +1730,6 @@ int cras_iodev_close(struct cras_iodev* iodev) {
iodev->state = CRAS_IODEV_STATE_CLOSE;
cras_iodev_close_called++;
cras_iodev_close_dev = iodev;
- iodev->format = NULL;
return 0;
}
@@ -2208,19 +1748,13 @@ void cras_iodev_set_node_plugged(struct cras_ionode* node, int plugged) {
set_node_plugged_called++;
}
-bool cras_iodev_support_noise_cancellation(const struct cras_iodev* iodev) {
- return true;
-}
-
int cras_iodev_start_volume_ramp(struct cras_iodev* odev,
unsigned int old_volume,
unsigned int new_volume) {
cras_iodev_start_volume_ramp_called++;
return 0;
}
-bool cras_iodev_is_aec_use_case(const struct cras_ionode* node) {
- return 1;
-}
+
bool stream_list_has_pinned_stream(struct stream_list* list,
unsigned int dev_idx) {
return stream_list_has_pinned_stream_ret[dev_idx];
@@ -2336,13 +1870,12 @@ int audio_thread_dev_start_ramp(struct audio_thread* thread,
}
#ifdef HAVE_WEBRTC_APM
-struct cras_apm* cras_apm_list_add_apm(struct cras_apm_list* list,
- void* dev_ptr,
- const struct cras_audio_format* fmt,
- bool is_internal_dev) {
+struct cras_apm* cras_apm_list_add(struct cras_apm_list* list,
+ void* dev_ptr,
+ const struct cras_audio_format* fmt) {
return NULL;
}
-void cras_apm_list_remove_apm(struct cras_apm_list* list, void* dev_ptr) {}
+void cras_apm_list_remove(struct cras_apm_list* list, void* dev_ptr) {}
int cras_apm_list_init(const char* device_config_dir) {
return 0;
}
@@ -2355,8 +1888,4 @@ int clock_gettime(clockid_t clk_id, struct timespec* tp) {
return 0;
}
-bool cras_system_get_hotword_pause_at_suspend() {
- return !!server_state_hotword_pause_at_suspend;
-}
-
} // extern "C"
diff --git a/cras/src/tests/iodev_stub.cc b/cras/src/tests/iodev_stub.cc
index 2e84faac..25d59da0 100644
--- a/cras/src/tests/iodev_stub.cc
+++ b/cras/src/tests/iodev_stub.cc
@@ -21,30 +21,12 @@ struct cb_data {
std::unordered_map<cras_iodev*, cb_data> frames_queued_map;
std::unordered_map<cras_iodev*, cb_data> valid_frames_map;
std::unordered_map<cras_iodev*, timespec> drop_time_map;
-std::unordered_map<const cras_iodev*, double> est_rate_ratio_map;
-std::unordered_map<const cras_iodev*, int> update_rate_map;
-std::unordered_map<const cras_ionode*, int> on_internal_card_map;
} // namespace
void iodev_stub_reset() {
frames_queued_map.clear();
valid_frames_map.clear();
drop_time_map.clear();
- est_rate_ratio_map.clear();
- update_rate_map.clear();
- on_internal_card_map.clear();
-}
-
-void iodev_stub_est_rate_ratio(cras_iodev* iodev, double ratio) {
- est_rate_ratio_map.insert({iodev, ratio});
-}
-
-void iodev_stub_update_rate(cras_iodev* iodev, int data) {
- update_rate_map.insert({iodev, data});
-}
-
-void iodev_stub_on_internal_card(cras_ionode* node, int data) {
- on_internal_card_map.insert({node, data});
}
void iodev_stub_frames_queued(cras_iodev* iodev, int ret, timespec ts) {
@@ -85,11 +67,7 @@ int cras_iodev_get_valid_frames(struct cras_iodev* iodev,
}
double cras_iodev_get_est_rate_ratio(const struct cras_iodev* iodev) {
- auto elem = est_rate_ratio_map.find(iodev);
- if (elem != est_rate_ratio_map.end()) {
- return elem->second;
- }
- return 1.0f;
+ return 1.0;
}
int cras_iodev_get_dsp_delay(const struct cras_iodev* iodev) {
@@ -115,10 +93,6 @@ struct dev_stream* cras_iodev_rm_stream(struct cras_iodev* iodev,
int cras_iodev_update_rate(struct cras_iodev* iodev,
unsigned int level,
struct timespec* level_tstamp) {
- auto elem = update_rate_map.find(iodev);
- if (elem != update_rate_map.end()) {
- return elem->second;
- }
return 0;
}
@@ -176,9 +150,7 @@ int cras_iodev_odev_should_wake(const struct cras_iodev* odev) {
return 1;
}
-int cras_iodev_output_underrun(struct cras_iodev* odev,
- unsigned int hw_level,
- unsigned int frames_written) {
+int cras_iodev_output_underrun(struct cras_iodev* odev) {
return 0;
}
@@ -214,12 +186,4 @@ int cras_iodev_drop_frames_by_time(struct cras_iodev* iodev,
drop_time_map.insert({iodev, ts});
return 0;
}
-
-bool cras_iodev_is_on_internal_card(const struct cras_ionode* node) {
- auto elem = on_internal_card_map.find(node);
- if (elem != on_internal_card_map.end()) {
- return elem->second;
- }
- return 1;
-}
} // extern "C"
diff --git a/cras/src/tests/iodev_stub.h b/cras/src/tests/iodev_stub.h
index e8016dd3..dde1b9f4 100644
--- a/cras/src/tests/iodev_stub.h
+++ b/cras/src/tests/iodev_stub.h
@@ -10,12 +10,6 @@
void iodev_stub_reset();
-void iodev_stub_est_rate_ratio(cras_iodev* iodev, double ratio);
-
-void iodev_stub_update_rate(cras_iodev* iodev, int data);
-
-void iodev_stub_on_internal_card(cras_ionode* node, int data);
-
void iodev_stub_frames_queued(cras_iodev* iodev, int ret, timespec ts);
void iodev_stub_valid_frames(cras_iodev* iodev, int ret, timespec ts);
diff --git a/cras/src/tests/iodev_unittest.cc b/cras/src/tests/iodev_unittest.cc
index 24b2b38d..61f8f694 100644
--- a/cras/src/tests/iodev_unittest.cc
+++ b/cras/src/tests/iodev_unittest.cc
@@ -9,7 +9,6 @@ extern "C" {
#include "audio_thread_log.h"
#include "cras_audio_area.h"
#include "cras_iodev.h"
-#include "cras_main_thread_log.h"
#include "cras_ramp.h"
#include "cras_rstream.h"
#include "dev_stream.h"
@@ -60,7 +59,7 @@ static unsigned int cras_mix_mute_count;
static unsigned int cras_dsp_num_input_channels_return;
static unsigned int cras_dsp_num_output_channels_return;
struct cras_dsp_context* cras_dsp_context_new_return;
-static unsigned int cras_dsp_load_mock_pipeline_called;
+static unsigned int cras_dsp_load_dummy_pipeline_called;
static unsigned int rate_estimator_add_frames_num_frames;
static unsigned int rate_estimator_add_frames_called;
static int cras_system_get_mute_return;
@@ -74,6 +73,7 @@ static unsigned int post_dsp_hook_called;
static const uint8_t* post_dsp_hook_frames;
static void* post_dsp_hook_cb_data;
static int iodev_buffer_size;
+static long cras_system_get_capture_gain_ret_value;
static uint8_t audio_buffer[BUFFER_SIZE];
static struct cras_audio_area* audio_area;
static unsigned int put_buffer_nframes;
@@ -85,6 +85,7 @@ struct audio_thread_event_log* atlog;
static unsigned int simple_no_stream_called;
static int simple_no_stream_enable;
static int dev_stream_playback_frames_ret;
+static int get_num_underruns_ret;
static int device_monitor_reset_device_called;
static int output_underrun_called;
static int set_mute_called;
@@ -113,7 +114,6 @@ static int buffer_share_get_new_write_point_ret;
static int ext_mod_configure_called;
static struct input_data* input_data_create_ret;
static double rate_estimator_get_rate_ret;
-static int cras_audio_thread_event_dev_overrun_called;
static char* atlog_name;
@@ -148,7 +148,7 @@ void ResetStubData() {
cras_dsp_num_input_channels_return = 2;
cras_dsp_num_output_channels_return = 2;
cras_dsp_context_new_return = NULL;
- cras_dsp_load_mock_pipeline_called = 0;
+ cras_dsp_load_dummy_pipeline_called = 0;
rate_estimator_add_frames_num_frames = 0;
rate_estimator_add_frames_called = 0;
cras_system_get_mute_return = 0;
@@ -159,6 +159,7 @@ void ResetStubData() {
post_dsp_hook_called = 0;
post_dsp_hook_frames = NULL;
iodev_buffer_size = 0;
+ cras_system_get_capture_gain_ret_value = 0;
// Assume there is some data in audio buffer.
memset(audio_buffer, 0xff, sizeof(audio_buffer));
if (audio_area) {
@@ -180,6 +181,7 @@ void ResetStubData() {
atlog_rw_shm_fd = atlog_ro_shm_fd = -1;
atlog = audio_thread_event_log_init(atlog_name);
}
+ get_num_underruns_ret = 0;
device_monitor_reset_device_called = 0;
output_underrun_called = 0;
set_mute_called = 0;
@@ -209,7 +211,6 @@ void ResetStubData() {
buffer_share_add_id_called = 0;
ext_mod_configure_called = 0;
rate_estimator_get_rate_ret = 0;
- cras_audio_thread_event_dev_overrun_called = 0;
}
namespace {
@@ -268,14 +269,9 @@ class IoDevSetFormatTestSuite : public testing::Test {
iodev_.dsp_context = NULL;
cras_audio_format_set_channel_layout_called = 0;
-
- main_log = main_thread_event_log_init();
}
- virtual void TearDown() {
- cras_iodev_free_format(&iodev_);
- main_thread_event_log_deinit(main_log);
- }
+ virtual void TearDown() { cras_iodev_free_format(&iodev_); }
struct cras_iodev iodev_;
size_t sample_rates_[3];
@@ -1062,8 +1058,6 @@ TEST(IoNodePlug, PlugUnplugNode) {
struct cras_iodev iodev;
struct cras_ionode ionode, ionode2;
- main_log = main_thread_event_log_init();
-
memset(&iodev, 0, sizeof(iodev));
memset(&ionode, 0, sizeof(ionode));
memset(&ionode2, 0, sizeof(ionode2));
@@ -1085,7 +1079,6 @@ TEST(IoNodePlug, PlugUnplugNode) {
EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
cras_iodev_set_node_plugged(&ionode2, 0);
EXPECT_EQ(1, cras_iodev_list_disable_dev_called);
- main_thread_event_log_deinit(main_log);
}
TEST(IoDev, AddRemoveNode) {
@@ -1176,15 +1169,21 @@ TEST(IoDev, SoftwareGain) {
iodev.active_node = &ionode;
iodev.active_node->dev = &iodev;
- ionode.capture_gain = 2400;
+ ionode.capture_gain = 400;
ionode.software_volume_needed = 1;
+ ionode.max_software_gain = 3000;
+ // Check that system volume changes software volume if needed.
+ cras_system_get_capture_gain_ret_value = 2000;
+ // system_gain + node_gain = 2000 + 400 = 2400
// 2400 * 0.01 dB is 15.848931
EXPECT_FLOAT_EQ(15.848931, cras_iodev_get_software_gain_scaler(&iodev));
+ EXPECT_FLOAT_EQ(3000, cras_iodev_maximum_software_gain(&iodev));
// Software gain scaler should be 1.0 if software gain is not needed.
ionode.software_volume_needed = 0;
EXPECT_FLOAT_EQ(1.0, cras_iodev_get_software_gain_scaler(&iodev));
+ EXPECT_FLOAT_EQ(0, cras_iodev_maximum_software_gain(&iodev));
}
// This get_buffer implementation set returned frames larger than requested
@@ -1233,8 +1232,6 @@ TEST(IoDev, OpenOutputDeviceNoStart) {
iodev.configure_dev = configure_dev;
iodev.direction = CRAS_STREAM_OUTPUT;
iodev.format = &audio_fmt;
- iodev.get_buffer = get_buffer;
- iodev.put_buffer = put_buffer;
ResetStubData();
iodev.state = CRAS_IODEV_STATE_CLOSE;
@@ -1255,8 +1252,6 @@ TEST(IoDev, OpenOutputDeviceWithLowRateFmt) {
iodev.configure_dev = configure_dev;
iodev.direction = CRAS_STREAM_OUTPUT;
iodev.format = &audio_fmt;
- iodev.get_buffer = get_buffer;
- iodev.put_buffer = put_buffer;
ResetStubData();
cras_audio_format low_rate_fmt = audio_fmt;
@@ -1378,8 +1373,6 @@ TEST(IoDev, AddRmStream) {
iodev.no_stream = simple_no_stream;
iodev.format = &audio_fmt;
iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
- iodev.get_buffer = get_buffer;
- iodev.put_buffer = put_buffer;
rstream1.cb_threshold = 800;
stream1.stream = &rstream1;
stream1.is_running = 0;
@@ -1433,8 +1426,6 @@ TEST(IoDev, RmStreamUpdateFetchTime) {
iodev.no_stream = simple_no_stream;
iodev.format = &audio_fmt;
iodev.state = CRAS_IODEV_STATE_NORMAL_RUN;
- iodev.get_buffer = get_buffer;
- iodev.put_buffer = put_buffer;
rstream1.direction = CRAS_STREAM_OUTPUT;
rstream2.direction = CRAS_STREAM_OUTPUT;
rstream3.direction = CRAS_STREAM_OUTPUT;
@@ -1482,8 +1473,6 @@ TEST(IoDev, StartStreams) {
iodev1.configure_dev = configure_dev;
iodev1.format = &audio_fmt;
iodev1.state = CRAS_IODEV_STATE_NORMAL_RUN;
- iodev1.get_buffer = get_buffer;
- iodev1.put_buffer = put_buffer;
iodev2.configure_dev = configure_dev;
iodev2.format = &audio_fmt;
iodev2.state = CRAS_IODEV_STATE_NORMAL_RUN;
@@ -1733,7 +1722,7 @@ TEST(IoDev, PrepareOutputBeforeWriteSamples) {
// Assume device has ramp member.
iodev.ramp = reinterpret_cast<struct cras_ramp*>(0x1);
- iodev.initial_ramp_request = CRAS_IODEV_RAMP_REQUEST_UP_START_PLAYBACK;
+
// Case 4.1: Assume device with ramp is started and is in no stream state.
iodev.state = CRAS_IODEV_STATE_NO_STREAM_RUN;
// Assume sample is ready.
@@ -2112,13 +2101,18 @@ TEST(IoDev, FramesToPlayInSleep) {
EXPECT_EQ(got_frames, hw_level - fmt.frame_rate / 1000 * 5);
}
+static unsigned int get_num_underruns(const struct cras_iodev* iodev) {
+ return get_num_underruns_ret;
+}
+
TEST(IoDev, GetNumUnderruns) {
struct cras_iodev iodev;
memset(&iodev, 0, sizeof(iodev));
EXPECT_EQ(0, cras_iodev_get_num_underruns(&iodev));
- iodev.num_underruns = 10;
+ iodev.get_num_underruns = get_num_underruns;
+ get_num_underruns_ret = 10;
EXPECT_EQ(10, cras_iodev_get_num_underruns(&iodev));
}
@@ -2131,8 +2125,6 @@ TEST(IoDev, RequestReset) {
iodev.configure_dev = configure_dev;
iodev.direction = CRAS_STREAM_OUTPUT;
iodev.format = &audio_fmt;
- iodev.get_buffer = get_buffer;
- iodev.put_buffer = put_buffer;
iodev.state = CRAS_IODEV_STATE_CLOSE;
iodev_buffer_size = 1024;
@@ -2181,7 +2173,7 @@ TEST(IoDev, HandleOutputUnderrun) {
iodev.min_cb_level = frames;
// Default case, fill one block of zeros.
- EXPECT_EQ(0, cras_iodev_output_underrun(&iodev, 0, 0));
+ EXPECT_EQ(0, cras_iodev_output_underrun(&iodev));
EXPECT_EQ(frames, put_buffer_nframes);
zeros = (int16_t*)calloc(frames * 2, sizeof(*zeros));
@@ -2191,7 +2183,7 @@ TEST(IoDev, HandleOutputUnderrun) {
// Test iodev has output_underrun ops.
iodev.output_underrun = output_underrun;
- EXPECT_EQ(0, cras_iodev_output_underrun(&iodev, 0, 0));
+ EXPECT_EQ(0, cras_iodev_output_underrun(&iodev));
EXPECT_EQ(1, output_underrun_called);
}
@@ -2240,12 +2232,12 @@ TEST(IoDev, SetExtDspMod) {
EXPECT_EQ(3, cras_dsp_get_pipeline_called);
EXPECT_EQ(3, cras_dsp_pipeline_set_sink_ext_module_called);
- /* If pipeline doesn't exist, mock pipeline should be loaded. */
+ /* If pipeline doesn't exist, dummy pipeline should be loaded. */
cras_dsp_get_pipeline_ret = 0x0;
cras_iodev_set_ext_dsp_module(&iodev, &ext);
EXPECT_EQ(3, ext_mod_configure_called);
EXPECT_EQ(5, cras_dsp_get_pipeline_called);
- EXPECT_EQ(1, cras_dsp_load_mock_pipeline_called);
+ EXPECT_EQ(1, cras_dsp_load_dummy_pipeline_called);
EXPECT_EQ(4, cras_dsp_pipeline_set_sink_ext_module_called);
}
@@ -2357,71 +2349,8 @@ TEST(IoDev, DropDeviceFramesByTime) {
EXPECT_EQ(-360, rate_estimator_add_frames_num_frames);
}
-TEST(IoDev, AecUseCaseCheck) {
- struct cras_ionode node;
-
- /* test output types */
- node.type = CRAS_NODE_TYPE_INTERNAL_SPEAKER;
- EXPECT_EQ(1, cras_iodev_is_aec_use_case(&node));
- node.type = CRAS_NODE_TYPE_HEADPHONE;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
- node.type = CRAS_NODE_TYPE_HDMI;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
- node.type = CRAS_NODE_TYPE_USB;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
- node.type = CRAS_NODE_TYPE_BLUETOOTH;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
-
- /* test mic positions */
- node.type = CRAS_NODE_TYPE_MIC;
- node.position = NODE_POSITION_INTERNAL;
- EXPECT_EQ(1, cras_iodev_is_aec_use_case(&node));
- node.position = NODE_POSITION_FRONT;
- EXPECT_EQ(1, cras_iodev_is_aec_use_case(&node));
- node.position = NODE_POSITION_EXTERNAL;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
- node.position = NODE_POSITION_REAR;
- EXPECT_EQ(0, cras_iodev_is_aec_use_case(&node));
-}
-
-TEST(IoDev, DeviceOverrun) {
- struct cras_iodev iodev;
-
- iodev.buffer_size = 4096;
- iodev.largest_cb_level = 2048;
- cras_iodev_update_highest_hw_level(&iodev, 4096);
- EXPECT_EQ(0, cras_audio_thread_event_dev_overrun_called);
-
- iodev.largest_cb_level = 1024;
- iodev.highest_hw_level = 1024;
- cras_iodev_update_highest_hw_level(&iodev, 2048);
- EXPECT_EQ(0, cras_audio_thread_event_dev_overrun_called);
-
- cras_iodev_update_highest_hw_level(&iodev, 4096);
- EXPECT_EQ(1, cras_audio_thread_event_dev_overrun_called);
-
- cras_iodev_update_highest_hw_level(&iodev, 4096);
- EXPECT_EQ(1, cras_audio_thread_event_dev_overrun_called);
-}
-
-TEST(IoDev, OnInternalCard) {
- static struct cras_ionode node;
- node.type = CRAS_NODE_TYPE_INTERNAL_SPEAKER;
- EXPECT_EQ(1, cras_iodev_is_on_internal_card(&node));
- node.type = CRAS_NODE_TYPE_HEADPHONE;
- EXPECT_EQ(1, cras_iodev_is_on_internal_card(&node));
- node.type = CRAS_NODE_TYPE_MIC;
- EXPECT_EQ(1, cras_iodev_is_on_internal_card(&node));
- node.type = CRAS_NODE_TYPE_USB;
- EXPECT_EQ(0, cras_iodev_is_on_internal_card(&node));
- node.type = CRAS_NODE_TYPE_BLUETOOTH;
- EXPECT_EQ(0, cras_iodev_is_on_internal_card(&node));
-}
-
extern "C" {
-struct main_thread_event_log* main_log;
-
// From libpthread.
int pthread_create(pthread_t* thread,
const pthread_attr_t* attr,
@@ -2461,7 +2390,7 @@ unsigned int buffer_share_get_new_write_point(struct buffer_share* mix) {
return buffer_share_get_new_write_point_ret;
}
-int buffer_share_add_id(struct buffer_share* mix, unsigned int id, void* data) {
+int buffer_share_add_id(struct buffer_share* mix, unsigned int id) {
buffer_share_add_id_called++;
return 0;
}
@@ -2476,11 +2405,9 @@ unsigned int buffer_share_id_offset(const struct buffer_share* mix,
}
// From cras_system_state.
-void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type) {}
+void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {}
-void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type) {}
+void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {}
// From cras_dsp
struct cras_dsp_context* cras_dsp_context_new(int sample_rate,
@@ -2495,9 +2422,9 @@ void cras_dsp_context_free(struct cras_dsp_context* ctx) {
}
void cras_dsp_load_pipeline(struct cras_dsp_context* ctx) {}
-void cras_dsp_load_mock_pipeline(struct cras_dsp_context* ctx,
- unsigned int num_channels) {
- cras_dsp_load_mock_pipeline_called++;
+void cras_dsp_load_dummy_pipeline(struct cras_dsp_context* ctx,
+ unsigned int num_channels) {
+ cras_dsp_load_dummy_pipeline_called++;
}
void cras_dsp_set_variable_string(struct cras_dsp_context* ctx,
@@ -2614,6 +2541,10 @@ size_t cras_system_get_volume() {
return cras_system_get_volume_return;
}
+long cras_system_get_capture_gain() {
+ return cras_system_get_capture_gain_ret_value;
+}
+
int cras_system_get_mute() {
return cras_system_get_mute_return;
}
@@ -2759,12 +2690,11 @@ void input_data_destroy(struct input_data** data) {}
void input_data_set_all_streams_read(struct input_data* data,
unsigned int nframes) {}
-int cras_audio_thread_event_underrun() {
+int cras_audio_thread_event_severe_underrun() {
return 0;
}
-int cras_audio_thread_event_dev_overrun() {
- cras_audio_thread_event_dev_overrun_called++;
+int cras_audio_thread_event_underrun() {
return 0;
}
@@ -2772,22 +2702,6 @@ int cras_server_metrics_device_runtime(struct cras_iodev* iodev) {
return 0;
}
-int cras_server_metrics_device_volume(struct cras_iodev* iodev) {
- return 0;
-}
-
-void ewma_power_init(struct ewma_power* ewma, unsigned int rate){};
-
-void ewma_power_calculate(struct ewma_power* ewma,
- const int16_t* buf,
- unsigned int channels,
- unsigned int size){};
-
-void ewma_power_calculate_area(struct ewma_power* ewma,
- const int16_t* buf,
- struct cras_audio_area* area,
- unsigned int size){};
-
} // extern "C"
} // namespace
diff --git a/cras/src/tests/loopback_iodev_unittest.cc b/cras/src/tests/loopback_iodev_unittest.cc
index fde50375..3cdaffb6 100644
--- a/cras/src/tests/loopback_iodev_unittest.cc
+++ b/cras/src/tests/loopback_iodev_unittest.cc
@@ -7,11 +7,6 @@
#include <stdlib.h>
extern "C" {
-// For audio_thread_log.h use.
-struct audio_thread_event_log* atlog;
-int atlog_rw_shm_fd;
-int atlog_ro_shm_fd;
-#include "audio_thread_log.h"
#include "cras_audio_area.h"
#include "cras_iodev.h"
#include "cras_iodev_list.h"
@@ -29,7 +24,7 @@ static const unsigned int kFrameBytes = 4;
static const unsigned int kBufferSize = kBufferFrames * kFrameBytes;
static struct timespec time_now;
-static cras_audio_area* mock_audio_area;
+static cras_audio_area* dummy_audio_area;
static loopback_hook_data_t loop_hook;
static struct cras_iodev* enabled_dev;
static unsigned int cras_iodev_list_add_input_called;
@@ -41,13 +36,11 @@ static void* device_enabled_callback_cb_data;
static int cras_iodev_list_register_loopback_called;
static int cras_iodev_list_unregister_loopback_called;
-static char* atlog_name;
-
class LoopBackTestSuite : public testing::Test {
protected:
virtual void SetUp() {
- mock_audio_area = (cras_audio_area*)calloc(
- 1, sizeof(*mock_audio_area) + sizeof(cras_channel_area) * 2);
+ dummy_audio_area = (cras_audio_area*)calloc(
+ 1, sizeof(*dummy_audio_area) + sizeof(cras_channel_area) * 2);
for (unsigned int i = 0; i < kBufferSize; i++) {
buf_[i] = rand();
}
@@ -65,11 +58,6 @@ class LoopBackTestSuite : public testing::Test {
cras_iodev_list_set_device_enabled_callback_called = 0;
cras_iodev_list_register_loopback_called = 0;
cras_iodev_list_unregister_loopback_called = 0;
-
- ASSERT_FALSE(asprintf(&atlog_name, "/ATlog-%d", getpid()) < 0);
- /* To avoid un-used variable warning. */
- atlog_rw_shm_fd = atlog_ro_shm_fd = -1;
- atlog = audio_thread_event_log_init(atlog_name);
}
virtual void TearDown() {
@@ -77,9 +65,7 @@ class LoopBackTestSuite : public testing::Test {
EXPECT_EQ(1, cras_iodev_list_rm_input_called);
EXPECT_EQ(NULL, device_enabled_callback_cb);
EXPECT_EQ(NULL, device_disabled_callback_cb);
- free(mock_audio_area);
- audio_thread_event_log_deinit(atlog, atlog_name);
- free(atlog_name);
+ free(dummy_audio_area);
}
uint8_t buf_[kBufferSize];
@@ -224,7 +210,7 @@ extern "C" {
void cras_audio_area_config_buf_pointers(struct cras_audio_area* area,
const struct cras_audio_format* fmt,
uint8_t* base_buffer) {
- mock_audio_area->channels[0].buf = base_buffer;
+ dummy_audio_area->channels[0].buf = base_buffer;
}
void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
@@ -232,7 +218,7 @@ void cras_iodev_free_audio_area(struct cras_iodev* iodev) {}
void cras_iodev_free_format(struct cras_iodev* iodev) {}
void cras_iodev_init_audio_area(struct cras_iodev* iodev, int num_channels) {
- iodev->area = mock_audio_area;
+ iodev->area = dummy_audio_area;
}
void cras_iodev_add_node(struct cras_iodev* iodev, struct cras_ionode* node) {
diff --git a/cras/src/tests/metrics_stub.cc b/cras/src/tests/metrics_stub.cc
index 96e8918b..d0f19c37 100644
--- a/cras/src/tests/metrics_stub.cc
+++ b/cras/src/tests/metrics_stub.cc
@@ -26,7 +26,7 @@ int cras_server_metrics_longest_fetch_delay(unsigned delay_msec) {
return 0;
}
-int cras_server_metrics_missed_cb_event(struct cras_rstream* stream) {
+int cras_server_metrics_missed_cb_event(const struct cras_rstream* stream) {
return 0;
}
@@ -34,14 +34,6 @@ int cras_server_metrics_num_underruns(unsigned num_underruns) {
return 0;
}
-int cras_server_metrics_hfp_battery_indicator(int battery_indicator_support) {
- return 0;
-}
-
-int cras_server_metrics_hfp_battery_report(int battery_report) {
- return 0;
-}
-
int cras_server_metrics_hfp_wideband_support(bool supported) {
return 0;
}
@@ -50,17 +42,8 @@ int cras_server_metrics_hfp_packet_loss(float packet_loss_ratio) {
return 0;
}
-int cras_server_metrics_hfp_sco_connection_error(
- enum CRAS_METRICS_BT_SCO_ERROR_TYPE type) {
- return 0;
-}
-
int cras_server_metrics_busyloop(struct timespec* ts, unsigned count) {
return 0;
}
-int cras_server_metrics_busyloop_length(unsigned count) {
- return 0;
-}
-
} // extern "C"
diff --git a/cras/src/tests/observer_unittest.cc b/cras/src/tests/observer_unittest.cc
index 2a8fae2c..5c9ca141 100644
--- a/cras/src/tests/observer_unittest.cc
+++ b/cras/src/tests/observer_unittest.cc
@@ -11,8 +11,6 @@
extern "C" {
#include "cras_observer.c"
-#include "cras_observer.h"
-#include "cras_types.h"
}
namespace {
@@ -58,9 +56,6 @@ static size_t cb_num_active_streams_changed_called;
static std::vector<enum CRAS_STREAM_DIRECTION>
cb_num_active_streams_changed_dir;
static std::vector<uint32_t> cb_num_active_streams_changed_num;
-static size_t cb_num_input_streams_with_permission_called;
-static std::vector<std::vector<uint32_t>>
- cb_num_input_streams_with_permission_array;
static void ResetStubData() {
cras_alert_destroy_called = 0;
@@ -104,8 +99,6 @@ static void ResetStubData() {
cb_num_active_streams_changed_called = 0;
cb_num_active_streams_changed_dir.clear();
cb_num_active_streams_changed_num.clear();
- cb_num_input_streams_with_permission_called = 0;
- cb_num_input_streams_with_permission_array.clear();
}
/* System output volume changed. */
@@ -197,15 +190,6 @@ void cb_num_active_streams_changed(void* context,
cb_num_active_streams_changed_num.push_back(num_active_streams);
}
-void cb_num_input_streams_with_permission_changed(
- void* context,
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE]) {
- cb_num_input_streams_with_permission_called++;
- cb_context.push_back(context);
- cb_num_input_streams_with_permission_array.push_back(std::vector<uint32_t>(
- num_input_streams, num_input_streams + CRAS_NUM_CLIENT_TYPE));
-}
-
class ObserverTest : public testing::Test {
protected:
virtual void SetUp() {
@@ -214,7 +198,7 @@ class ObserverTest : public testing::Test {
ResetStubData();
rc = cras_observer_server_init();
ASSERT_EQ(0, rc);
- EXPECT_EQ(17, cras_alert_create_called);
+ EXPECT_EQ(15, cras_alert_create_called);
EXPECT_EQ(reinterpret_cast<void*>(output_volume_alert),
cras_alert_add_callback_map[g_observer->alerts.output_volume]);
EXPECT_EQ(reinterpret_cast<void*>(output_mute_alert),
@@ -256,9 +240,6 @@ class ObserverTest : public testing::Test {
EXPECT_EQ(reinterpret_cast<void*>(non_empty_audio_state_changed_alert),
cras_alert_add_callback_map[g_observer->alerts
.non_empty_audio_state_changed]);
- EXPECT_EQ(
- reinterpret_cast<void*>(bt_battery_changed_alert),
- cras_alert_add_callback_map[g_observer->alerts.bt_battery_changed]);
cras_observer_get_ops(NULL, &ops1_);
EXPECT_NE(0, cras_observer_ops_are_empty(&ops1_));
@@ -272,7 +253,7 @@ class ObserverTest : public testing::Test {
virtual void TearDown() {
cras_observer_server_free();
- EXPECT_EQ(17, cras_alert_destroy_called);
+ EXPECT_EQ(15, cras_alert_destroy_called);
ResetStubData();
}
@@ -594,37 +575,6 @@ TEST_F(ObserverTest, NotifyNumActiveStreams) {
DoObserverRemoveClear(num_active_streams_alert, data);
};
-TEST_F(ObserverTest, NotifyNumInputStreamsWithPermission) {
- struct cras_observer_alert_data_input_streams* data;
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE] = {};
- for (unsigned type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type) {
- num_input_streams[type] = (uint32_t)type;
- }
-
- cras_observer_notify_input_streams_with_permission(num_input_streams);
- ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
- ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void*>(NULL));
- data = reinterpret_cast<struct cras_observer_alert_data_input_streams*>(
- cras_alert_pending_data_value);
- for (unsigned type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type) {
- EXPECT_EQ(data->num_input_streams[type], num_input_streams[type]);
- }
-
- ops1_.num_input_streams_with_permission_changed =
- cb_num_input_streams_with_permission_changed;
- ops2_.num_input_streams_with_permission_changed =
- cb_num_input_streams_with_permission_changed;
- DoObserverAlert(num_input_streams_with_permission_alert, data);
- ASSERT_EQ(2, cb_num_input_streams_with_permission_called);
- for (auto cb_num_input_streams : cb_num_input_streams_with_permission_array) {
- ASSERT_EQ(cb_num_input_streams.size(), (size_t)CRAS_NUM_CLIENT_TYPE);
- for (unsigned type = 0; type < CRAS_NUM_CLIENT_TYPE; ++type) {
- EXPECT_EQ(cb_num_input_streams[type], num_input_streams[type]);
- }
- }
- DoObserverRemoveClear(num_input_streams_with_permission_alert, data);
-}
-
TEST_F(ObserverTest, NotifyHotwordTriggered) {
struct cras_observer_alert_data_hotword_triggered* data;
@@ -652,21 +602,6 @@ TEST_F(ObserverTest, NonEmpyAudioStateChanged) {
EXPECT_EQ(data->non_empty, 1);
}
-TEST_F(ObserverTest, BluetoothBatteryChanged) {
- struct cras_observer_alert_data_bt_battery_changed* data;
- const char* address = "test";
-
- cras_observer_notify_bt_battery_changed(address, 30);
- EXPECT_EQ(cras_alert_pending_alert_value,
- g_observer->alerts.bt_battery_changed);
- ASSERT_EQ(cras_alert_pending_data_size_value, sizeof(*data));
- ASSERT_NE(cras_alert_pending_data_value, reinterpret_cast<void*>(NULL));
- data = reinterpret_cast<struct cras_observer_alert_data_bt_battery_changed*>(
- cras_alert_pending_data_value);
- EXPECT_EQ(data->address, address);
- EXPECT_EQ(data->level, 30);
-}
-
// Stubs
extern "C" {
diff --git a/cras/src/tests/playback_rclient_unittest.cc b/cras/src/tests/playback_rclient_unittest.cc
index 31ceda74..aa24bc28 100644
--- a/cras/src/tests/playback_rclient_unittest.cc
+++ b/cras/src/tests/playback_rclient_unittest.cc
@@ -18,22 +18,24 @@ extern "C" {
#include "cras_playback_rclient.c"
#include "cras_rclient_util.c"
}
-static bool audio_format_valid;
static unsigned int cras_make_fd_nonblocking_called;
static unsigned int cras_observer_remove_called;
+static unsigned int cras_server_metrics_stream_config_called;
static int stream_list_add_called;
static int stream_list_add_return;
static unsigned int stream_list_rm_called;
-static struct cras_audio_shm mock_shm;
-static struct cras_rstream mock_rstream;
+static struct cras_audio_shm dummy_shm;
+static struct cras_rstream dummy_rstream;
+static unsigned int cras_rstream_config_init_with_message_called;
void ResetStubData() {
- audio_format_valid = true;
cras_make_fd_nonblocking_called = 0;
cras_observer_remove_called = 0;
+ cras_server_metrics_stream_config_called = 0;
stream_list_add_called = 0;
stream_list_add_return = 0;
stream_list_rm_called = 0;
+ cras_rstream_config_init_with_message_called = 0;
}
namespace {
@@ -108,12 +110,13 @@ TEST_F(CPRMessageSuite, StreamConnectMessage) {
cras_fill_connect_message(&msg, CRAS_STREAM_OUTPUT, stream_id,
CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_UNKNOWN,
480, 240, /*flags=*/0, /*effects=*/0, fmt,
- NO_DEVICE);
+ NO_DEVICE, /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
EXPECT_EQ(1, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
EXPECT_EQ(1, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -135,14 +138,16 @@ TEST_F(CPRMessageSuite, StreamConnectMessageInvalidDirection) {
continue;
cras_fill_connect_message(&msg, dir, stream_id, CRAS_STREAM_TYPE_DEFAULT,
CRAS_CLIENT_TYPE_UNKNOWN, 480, 240, /*flags=*/0,
- /*effects=*/0, fmt, NO_DEVICE);
+ /*effects=*/0, fmt, NO_DEVICE,
+ /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rc = rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_,
1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(0, cras_rstream_config_init_with_message_called);
EXPECT_EQ(0, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -162,14 +167,15 @@ TEST_F(CPRMessageSuite, StreamConnectMessageInvalidClientId) {
cras_fill_connect_message(&msg, CRAS_STREAM_OUTPUT, stream_id,
CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_UNKNOWN,
480, 240, /*flags=*/0, /*effects=*/0, fmt,
- NO_DEVICE);
+ NO_DEVICE, /*client_shm_size=*/0);
ASSERT_EQ(stream_id, msg.stream_id);
fd_ = 100;
rc =
rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
- EXPECT_EQ(0, rc);
+ EXPECT_EQ(-EINVAL, rc);
EXPECT_EQ(0, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(0, cras_rstream_config_init_with_message_called);
EXPECT_EQ(0, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
@@ -179,31 +185,40 @@ TEST_F(CPRMessageSuite, StreamConnectMessageInvalidClientId) {
EXPECT_EQ(stream_id, out_msg.stream_id);
}
-TEST_F(CPRMessageSuite, StreamConnectMessageInvalidAudioFormat) {
+/*
+ * TODO(yuhsaun): Remove this test when there are no client uses the old
+ * craslib. (CRAS_PROTO_VER = 3)
+ */
+TEST_F(CPRMessageSuite, StreamConnectMessageOldProtocal) {
struct cras_client_stream_connected out_msg;
int rc;
- struct cras_connect_message msg;
+ struct cras_connect_message_old msg;
cras_stream_id_t stream_id = 0x10002;
- cras_fill_connect_message(&msg, CRAS_STREAM_OUTPUT, stream_id,
- CRAS_STREAM_TYPE_DEFAULT, CRAS_CLIENT_TYPE_UNKNOWN,
- 480, 240, /*flags=*/0, /*effects=*/0, fmt,
- NO_DEVICE);
- ASSERT_EQ(stream_id, msg.stream_id);
- audio_format_valid = false; // stubs out verification failure.
+ msg.proto_version = 3;
+ msg.direction = CRAS_STREAM_OUTPUT;
+ msg.stream_id = stream_id;
+ msg.stream_type = CRAS_STREAM_TYPE_DEFAULT;
+ msg.buffer_frames = 480;
+ msg.cb_threshold = 240;
+ msg.flags = 0;
+ msg.effects = 0;
+ pack_cras_audio_format(&msg.format, &fmt);
+ msg.dev_idx = NO_DEVICE;
+ msg.header.id = CRAS_SERVER_CONNECT_STREAM;
+ msg.header.length = sizeof(struct cras_connect_message_old);
fd_ = 100;
rc =
rclient_->ops->handle_message_from_client(rclient_, &msg.header, &fd_, 1);
- EXPECT_EQ(0, rc);
- EXPECT_EQ(0, cras_make_fd_nonblocking_called);
- EXPECT_EQ(0, stream_list_add_called);
+ EXPECT_EQ(1, cras_make_fd_nonblocking_called);
+ EXPECT_EQ(1, cras_rstream_config_init_with_message_called);
+ EXPECT_EQ(1, stream_list_add_called);
EXPECT_EQ(0, stream_list_rm_called);
rc = read(pipe_fds_[0], &out_msg, sizeof(out_msg));
EXPECT_EQ(sizeof(out_msg), rc);
- EXPECT_EQ(-EINVAL, out_msg.err);
EXPECT_EQ(stream_id, out_msg.stream_id);
}
@@ -253,6 +268,11 @@ unsigned int cras_rstream_get_effects(const struct cras_rstream* stream) {
return 0;
}
+int cras_server_metrics_stream_config(struct cras_rstream_config* config) {
+ cras_server_metrics_stream_config_called++;
+ return 0;
+}
+
int cras_send_with_fds(int sockfd,
const void* buf,
size_t len,
@@ -282,27 +302,30 @@ int stream_list_add(struct stream_list* list,
struct cras_rstream** stream) {
int ret;
- *stream = &mock_rstream;
+ *stream = &dummy_rstream;
stream_list_add_called++;
ret = stream_list_add_return;
if (ret)
stream_list_add_return = -EINVAL;
- mock_rstream.shm = &mock_shm;
- mock_rstream.direction = config->direction;
- mock_rstream.stream_id = config->stream_id;
+ dummy_rstream.shm = &dummy_shm;
+ dummy_rstream.direction = config->direction;
+ dummy_rstream.stream_id = config->stream_id;
return ret;
}
-bool cras_audio_format_valid(const struct cras_audio_format* fmt) {
- return audio_format_valid;
+void cras_rstream_config_init_with_message(
+ struct cras_rclient* client,
+ const struct cras_connect_message* msg,
+ int* aud_fd,
+ int* client_shm_fd,
+ const struct cras_audio_format* remote_fmt,
+ struct cras_rstream_config* stream_config) {
+ cras_rstream_config_init_with_message_called++;
}
-void detect_rtc_stream_pair(struct stream_list* list,
- struct cras_rstream* stream) {
- return;
-}
+void cras_rstream_config_cleanup(struct cras_rstream_config* stream_config) {}
} // extern "C"
diff --git a/cras/src/tests/polled_interval_checker_unittest.cc b/cras/src/tests/polled_interval_checker_unittest.cc
index a4aff09c..c18fdf7e 100644
--- a/cras/src/tests/polled_interval_checker_unittest.cc
+++ b/cras/src/tests/polled_interval_checker_unittest.cc
@@ -70,7 +70,7 @@ TEST(PolledIntervalCheckerTest, DoesNotResetAutomatically) {
struct polled_interval* interval = create_interval();
- // Initial check.
+ // Sanity check.
EXPECT_FALSE(pic_interval_elapsed(interval));
// Increment time so the interval elapses.
@@ -100,7 +100,7 @@ TEST(PolledIntervalCheckerTest, Reset) {
struct polled_interval* interval = create_interval();
- // Initial check.
+ // Sanity check.
EXPECT_FALSE(pic_interval_elapsed(interval));
// Increment time so the interval elapses.
diff --git a/cras/src/tests/ramp_unittest.cc b/cras/src/tests/ramp_unittest.cc
index a661dffe..8d674799 100644
--- a/cras/src/tests/ramp_unittest.cc
+++ b/cras/src/tests/ramp_unittest.cc
@@ -315,22 +315,6 @@ TEST(RampTestSuite, RampDownWhileHalfWayRampUp) {
cras_ramp_destroy(ramp);
}
-TEST(RampTestSuite, NullWontCrash) {
- float from;
- float to;
- int duration_frames = 48000;
- int rc = 0;
- struct cras_ramp* ramp = NULL;
-
- ResetStubData();
-
- from = 0.0;
- to = 1.0;
- rc = cras_mute_ramp_start(ramp, from, to, duration_frames, NULL, NULL);
-
- EXPECT_EQ(-EINVAL, rc);
-}
-
TEST(RampTestSuite, RampDownWhileHalfWayRampDown) {
float from = 1.0;
float to = 0.0;
@@ -370,28 +354,6 @@ TEST(RampTestSuite, RampDownWhileHalfWayRampDown) {
cras_ramp_destroy(ramp);
}
-TEST(RampTestSuite, MuteRamp) {
- float from = 0.0;
- float to = 0.0;
- int duration_frames = 48000;
- struct cras_ramp* ramp;
- struct cras_ramp_action action;
-
- ResetStubData();
-
- ramp = cras_ramp_create();
- cras_mute_ramp_start(ramp, from, to, duration_frames, NULL, NULL);
-
- action = cras_ramp_get_current_action(ramp);
-
- EXPECT_EQ(CRAS_RAMP_ACTION_PARTIAL, action.type);
- EXPECT_FLOAT_EQ(0.0, action.scaler);
- EXPECT_FLOAT_EQ(0.0, action.increment);
- EXPECT_FLOAT_EQ(0.0, action.target);
-
- cras_ramp_destroy(ramp);
-}
-
TEST(RampTestSuite, PartialRamp) {
float from_one = 0.75;
float to_one = 0.4;
diff --git a/cras/src/tests/rate_estimator_unittest.cc b/cras/src/tests/rate_estimator_unittest.cc
index 778a3cda..66f7c586 100644
--- a/cras/src/tests/rate_estimator_unittest.cc
+++ b/cras/src/tests/rate_estimator_unittest.cc
@@ -95,10 +95,11 @@ TEST(RateEstimatorTest, EstimateRateSkewTooLarge) {
TEST(RateEstimatorTest, EstimateOutputSmooth) {
struct rate_estimator* re;
- struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
+ struct timespec t;
int rc;
re = rate_estimator_create(10010, &window, 0.9f);
+ t.tv_sec = 1;
rc = rate_estimator_check(re, 240, &t);
EXPECT_EQ(0, rc);
@@ -123,10 +124,11 @@ TEST(RateEstimatorTest, EstimateOutputSmooth) {
TEST(RateEstimatorTest, EstimateInputLinear) {
struct rate_estimator* re;
- struct timespec t = {.tv_sec = 1, .tv_nsec = 0};
+ struct timespec t;
int i, rc, level, tmp;
re = rate_estimator_create(10000, &window, 0.0f);
+ t.tv_sec = 1;
level = 1200;
for (i = 0; i < 20; i++) {
rc = rate_estimator_check(re, level, &t);
diff --git a/cras/src/tests/rstream_unittest.cc b/cras/src/tests/rstream_unittest.cc
index d8dae24c..69523f5f 100644
--- a/cras/src/tests/rstream_unittest.cc
+++ b/cras/src/tests/rstream_unittest.cc
@@ -16,8 +16,6 @@ extern "C" {
#include "cras_shm.h"
}
-#include "metrics_stub.h"
-
namespace {
class RstreamTestSuite : public testing::Test {
@@ -32,7 +30,6 @@ class RstreamTestSuite : public testing::Test {
config_.stream_id = 555;
config_.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- config_.client_type = CRAS_CLIENT_TYPE_UNKNOWN;
config_.direction = CRAS_STREAM_OUTPUT;
config_.dev_idx = NO_DEVICE;
config_.flags = 0;
@@ -379,7 +376,7 @@ unsigned int buffer_share_get_new_write_point(struct buffer_share* mix) {
return 0;
}
-int buffer_share_add_id(struct buffer_share* mix, unsigned int id, void* data) {
+int buffer_share_add_id(struct buffer_share* mix, unsigned int id) {
return 0;
}
@@ -391,36 +388,14 @@ unsigned int buffer_share_id_offset(const struct buffer_share* mix,
unsigned int id) {
return 0;
}
-void ewma_power_init(struct ewma_power* ewma, unsigned int rate) {}
-
-void ewma_power_calculate(struct ewma_power* ewma,
- const int16_t* buf,
- unsigned int channels,
- unsigned int size) {}
-void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type) {}
-
-void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction,
- enum CRAS_CLIENT_TYPE client_type) {}
-
-int cras_server_metrics_stream_create(
- const struct cras_rstream_config* config) {
- return 0;
-}
-
-int cras_server_metrics_stream_destroy(const struct cras_rstream* stream) {
- return 0;
-}
+void cras_system_state_stream_added(enum CRAS_STREAM_DIRECTION direction) {}
+void cras_system_state_stream_removed(enum CRAS_STREAM_DIRECTION direction) {}
#ifdef HAVE_WEBRTC_APM
-#define FAKE_CRAS_APM_PTR reinterpret_cast<struct cras_apm*>(0x99)
struct cras_apm_list* cras_apm_list_create(void* stream_ptr, uint64_t effects) {
return NULL;
}
-struct cras_apm* cras_apm_list_get_active_apm(void* stream_ptr, void* dev_ptr) {
- return FAKE_CRAS_APM_PTR;
-}
int cras_apm_list_destroy(struct cras_apm_list* list) {
return 0;
}
@@ -434,4 +409,8 @@ struct cras_audio_format* cras_apm_list_get_format(struct cras_apm* apm) {
return NULL;
}
#endif
+
+int cras_server_metrics_missed_cb_frequency(const struct cras_rstream* stream) {
+ return 0;
+}
}
diff --git a/cras/src/tests/server_metrics_unittest.cc b/cras/src/tests/server_metrics_unittest.cc
index e23906ec..94a689c5 100644
--- a/cras/src/tests/server_metrics_unittest.cc
+++ b/cras/src/tests/server_metrics_unittest.cc
@@ -132,6 +132,20 @@ TEST(ServerMetricsTestSuite, SetMetricHighestHardwareLevel) {
EXPECT_EQ(sent_msgs[0].data.value, hw_level);
}
+TEST(ServerMetricsTestSuite, SetMetricsLongestFetchDelay) {
+ ResetStubData();
+ unsigned int delay = 100;
+
+ cras_server_metrics_longest_fetch_delay(delay);
+
+ EXPECT_EQ(sent_msgs.size(), 1);
+ EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
+ EXPECT_EQ(sent_msgs[0].header.length,
+ sizeof(struct cras_server_metrics_message));
+ EXPECT_EQ(sent_msgs[0].metrics_type, LONGEST_FETCH_DELAY);
+ EXPECT_EQ(sent_msgs[0].data.value, delay);
+}
+
TEST(ServerMetricsTestSuite, SetMetricsNumUnderruns) {
ResetStubData();
unsigned int underrun = 10;
@@ -146,6 +160,79 @@ TEST(ServerMetricsTestSuite, SetMetricsNumUnderruns) {
EXPECT_EQ(sent_msgs[0].data.value, underrun);
}
+TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackFrequencyInputStream) {
+ ResetStubData();
+ struct cras_rstream stream;
+ struct timespec diff_ts;
+
+ stream.flags = 0;
+ stream.start_ts.tv_sec = 0;
+ stream.start_ts.tv_nsec = 0;
+ clock_gettime_retspec.tv_sec = 1000;
+ clock_gettime_retspec.tv_nsec = 0;
+ stream.num_missed_cb = 5;
+ stream.first_missed_cb_ts.tv_sec = 100;
+ stream.first_missed_cb_ts.tv_nsec = 0;
+
+ stream.direction = CRAS_STREAM_INPUT;
+ cras_server_metrics_missed_cb_frequency(&stream);
+
+ subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
+ EXPECT_EQ(sent_msgs.size(), 2);
+ EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
+ EXPECT_EQ(sent_msgs[0].header.length,
+ sizeof(struct cras_server_metrics_message));
+ EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FREQUENCY_INPUT);
+ EXPECT_EQ(sent_msgs[0].data.value,
+ stream.num_missed_cb * 86400 / diff_ts.tv_sec);
+
+ subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
+ &diff_ts);
+ EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
+ EXPECT_EQ(sent_msgs[1].header.length,
+ sizeof(struct cras_server_metrics_message));
+ EXPECT_EQ(sent_msgs[1].metrics_type,
+ MISSED_CB_FREQUENCY_AFTER_RESCHEDULING_INPUT);
+ EXPECT_EQ(sent_msgs[1].data.value,
+ (stream.num_missed_cb - 1) * 86400 / diff_ts.tv_sec);
+}
+
+TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackFrequencyOutputStream) {
+ ResetStubData();
+ struct cras_rstream stream;
+ struct timespec diff_ts;
+
+ stream.flags = 0;
+ stream.start_ts.tv_sec = 0;
+ stream.start_ts.tv_nsec = 0;
+ clock_gettime_retspec.tv_sec = 1000;
+ clock_gettime_retspec.tv_nsec = 0;
+ stream.num_missed_cb = 5;
+ stream.first_missed_cb_ts.tv_sec = 100;
+ stream.first_missed_cb_ts.tv_nsec = 0;
+ stream.direction = CRAS_STREAM_OUTPUT;
+ cras_server_metrics_missed_cb_frequency(&stream);
+
+ subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
+ EXPECT_EQ(sent_msgs.size(), 2);
+ EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
+ EXPECT_EQ(sent_msgs[0].header.length,
+ sizeof(struct cras_server_metrics_message));
+ EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FREQUENCY_OUTPUT);
+ EXPECT_EQ(sent_msgs[0].data.value,
+ stream.num_missed_cb * 86400 / diff_ts.tv_sec);
+
+ subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
+ &diff_ts);
+ EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
+ EXPECT_EQ(sent_msgs[1].header.length,
+ sizeof(struct cras_server_metrics_message));
+ EXPECT_EQ(sent_msgs[1].metrics_type,
+ MISSED_CB_FREQUENCY_AFTER_RESCHEDULING_OUTPUT);
+ EXPECT_EQ(sent_msgs[1].data.value,
+ (stream.num_missed_cb - 1) * 86400 / diff_ts.tv_sec);
+}
+
TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackEventInputStream) {
ResetStubData();
struct cras_rstream stream;
@@ -228,7 +315,7 @@ TEST(ServerMetricsTestSuite, SetMetricsMissedCallbackEventOutputStream) {
EXPECT_EQ(stream.num_missed_cb, 2);
}
-TEST(ServerMetricsTestSuite, SetMetricsStreamCreate) {
+TEST(ServerMetricsTestSuite, SetMetricsStreamConfig) {
ResetStubData();
struct cras_rstream_config config;
struct cras_audio_format format;
@@ -239,10 +326,10 @@ TEST(ServerMetricsTestSuite, SetMetricsStreamCreate) {
format.format = SND_PCM_FORMAT_S16_LE;
format.frame_rate = 48000;
config.client_type = CRAS_CLIENT_TYPE_TEST;
+
config.format = &format;
- cras_server_metrics_stream_create(&config);
+ cras_server_metrics_stream_config(&config);
- // Log stream config.
EXPECT_EQ(sent_msgs.size(), 1);
EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
EXPECT_EQ(sent_msgs[0].header.length,
@@ -256,75 +343,6 @@ TEST(ServerMetricsTestSuite, SetMetricsStreamCreate) {
EXPECT_EQ(sent_msgs[0].data.stream_config.client_type, CRAS_CLIENT_TYPE_TEST);
}
-TEST(ServerMetricsTestSuite, SetMetricsStreamDestroy) {
- ResetStubData();
- struct cras_rstream stream;
- struct timespec diff_ts;
-
- stream.flags = 0;
- stream.start_ts.tv_sec = 0;
- stream.start_ts.tv_nsec = 0;
- clock_gettime_retspec.tv_sec = 1000;
- clock_gettime_retspec.tv_nsec = 0;
- stream.num_missed_cb = 5;
- stream.first_missed_cb_ts.tv_sec = 100;
- stream.first_missed_cb_ts.tv_nsec = 0;
- stream.longest_fetch_interval.tv_sec = 1;
- stream.longest_fetch_interval.tv_nsec = 0;
- stream.sleep_interval_ts.tv_sec = 0;
- stream.sleep_interval_ts.tv_nsec = 5000000;
-
- stream.direction = CRAS_STREAM_INPUT;
- stream.client_type = CRAS_CLIENT_TYPE_TEST;
- stream.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- cras_server_metrics_stream_destroy(&stream);
-
- subtract_timespecs(&clock_gettime_retspec, &stream.start_ts, &diff_ts);
- EXPECT_EQ(sent_msgs.size(), 4);
-
- // Log missed cb frequency.
- EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
- EXPECT_EQ(sent_msgs[0].header.length,
- sizeof(struct cras_server_metrics_message));
- EXPECT_EQ(sent_msgs[0].metrics_type, MISSED_CB_FREQUENCY_INPUT);
- EXPECT_EQ(sent_msgs[0].data.value,
- stream.num_missed_cb * 86400 / diff_ts.tv_sec);
-
- // Log missed cb frequency after rescheduling.
- subtract_timespecs(&clock_gettime_retspec, &stream.first_missed_cb_ts,
- &diff_ts);
- EXPECT_EQ(sent_msgs[1].header.type, CRAS_MAIN_METRICS);
- EXPECT_EQ(sent_msgs[1].header.length,
- sizeof(struct cras_server_metrics_message));
- EXPECT_EQ(sent_msgs[1].metrics_type,
- MISSED_CB_FREQUENCY_AFTER_RESCHEDULING_INPUT);
- EXPECT_EQ(sent_msgs[1].data.value,
- (stream.num_missed_cb - 1) * 86400 / diff_ts.tv_sec);
-
- // Log stream runtime.
- EXPECT_EQ(sent_msgs[2].header.type, CRAS_MAIN_METRICS);
- EXPECT_EQ(sent_msgs[2].header.length,
- sizeof(struct cras_server_metrics_message));
- EXPECT_EQ(sent_msgs[2].metrics_type, STREAM_RUNTIME);
- EXPECT_EQ(sent_msgs[2].data.stream_data.client_type, CRAS_CLIENT_TYPE_TEST);
- EXPECT_EQ(sent_msgs[2].data.stream_data.stream_type,
- CRAS_STREAM_TYPE_DEFAULT);
- EXPECT_EQ(sent_msgs[2].data.stream_data.direction, CRAS_STREAM_INPUT);
- EXPECT_EQ(sent_msgs[2].data.stream_data.runtime.tv_sec, 1000);
-
- // Log longest fetch delay.
- EXPECT_EQ(sent_msgs[3].header.type, CRAS_MAIN_METRICS);
- EXPECT_EQ(sent_msgs[3].header.length,
- sizeof(struct cras_server_metrics_message));
- EXPECT_EQ(sent_msgs[3].metrics_type, LONGEST_FETCH_DELAY);
- EXPECT_EQ(sent_msgs[3].data.stream_data.client_type, CRAS_CLIENT_TYPE_TEST);
- EXPECT_EQ(sent_msgs[3].data.stream_data.stream_type,
- CRAS_STREAM_TYPE_DEFAULT);
- EXPECT_EQ(sent_msgs[3].data.stream_data.direction, CRAS_STREAM_INPUT);
- EXPECT_EQ(sent_msgs[3].data.stream_data.runtime.tv_sec, 0);
- EXPECT_EQ(sent_msgs[3].data.stream_data.runtime.tv_nsec, 995000000);
-}
-
TEST(ServerMetricsTestSuite, SetMetricsBusyloop) {
ResetStubData();
struct timespec time = {40, 0};
@@ -342,20 +360,6 @@ TEST(ServerMetricsTestSuite, SetMetricsBusyloop) {
EXPECT_EQ(sent_msgs[0].data.timespec_data.count, 3);
}
-TEST(ServerMetricsTestSuite, SetMetricsBusyloopLength) {
- ResetStubData();
- unsigned length = 5;
-
- cras_server_metrics_busyloop_length(length);
-
- EXPECT_EQ(sent_msgs.size(), 1);
- EXPECT_EQ(sent_msgs[0].header.type, CRAS_MAIN_METRICS);
- EXPECT_EQ(sent_msgs[0].header.length,
- sizeof(struct cras_server_metrics_message));
- EXPECT_EQ(sent_msgs[0].metrics_type, BUSYLOOP_LENGTH);
- EXPECT_EQ(sent_msgs[0].data.value, 5);
-}
-
extern "C" {
int cras_main_message_add_handler(enum CRAS_MAIN_MESSAGE_TYPE type,
diff --git a/cras/src/tests/stream_list_unittest.cc b/cras/src/tests/stream_list_unittest.cc
index 500774f1..8f3c2e3e 100644
--- a/cras/src/tests/stream_list_unittest.cc
+++ b/cras/src/tests/stream_list_unittest.cc
@@ -28,20 +28,13 @@ static int removed_cb(struct cras_rstream* rstream) {
static unsigned int create_called;
static struct cras_rstream_config* create_config;
+static struct cras_rstream dummy_rstream;
static int create_rstream_cb(struct cras_rstream_config* stream_config,
struct cras_rstream** stream) {
create_called++;
create_config = stream_config;
- *stream = (struct cras_rstream*)malloc(sizeof(struct cras_rstream));
- (*stream)->stream_id = stream_config->stream_id;
- (*stream)->direction = stream_config->direction;
- if (stream_config->format)
- (*stream)->format = *(stream_config->format);
- (*stream)->cb_threshold = stream_config->cb_threshold;
- (*stream)->client_type = stream_config->client_type;
- (*stream)->stream_type = stream_config->stream_type;
- clock_gettime(CLOCK_MONOTONIC_RAW, &(*stream)->start_ts);
-
+ *stream = &dummy_rstream;
+ dummy_rstream.stream_id = 0x3003;
return 0;
}
@@ -50,7 +43,6 @@ static struct cras_rstream* destroyed_stream;
static void destroy_rstream_cb(struct cras_rstream* rstream) {
destroy_called++;
destroyed_stream = rstream;
- free(rstream);
}
static void reset_test_data() {
@@ -65,10 +57,6 @@ TEST(StreamList, AddRemove) {
struct cras_rstream* s1;
struct cras_rstream_config s1_config;
- s1_config.stream_id = 0x3003;
- s1_config.direction = CRAS_STREAM_OUTPUT;
- s1_config.format = NULL;
-
reset_test_data();
l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
destroy_rstream_cb, NULL);
@@ -84,117 +72,6 @@ TEST(StreamList, AddRemove) {
stream_list_destroy(l);
}
-TEST(StreamList, AddInDescendingOrderByChannels) {
- struct stream_list* l;
- struct cras_rstream* s1;
- struct cras_rstream* s2;
- struct cras_rstream* s3;
- struct cras_audio_format s1_format, s2_format, s3_format;
- struct cras_rstream_config s1_config, s2_config, s3_config;
-
- s1_config.stream_id = 0x4001;
- s1_config.direction = CRAS_STREAM_INPUT;
- s1_format.num_channels = 6;
- s1_config.format = &s1_format;
-
- s2_config.stream_id = 0x4002;
- s2_config.direction = CRAS_STREAM_OUTPUT;
- s2_format.num_channels = 8;
- s2_config.format = &s2_format;
-
- s3_config.stream_id = 0x4003;
- s3_config.direction = CRAS_STREAM_OUTPUT;
- s3_format.num_channels = 2;
- s3_config.format = &s3_format;
-
- reset_test_data();
- l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
- destroy_rstream_cb, NULL);
- stream_list_add(l, &s1_config, &s1);
- EXPECT_EQ(1, add_called);
- EXPECT_EQ(1, create_called);
- EXPECT_EQ(6, stream_list_get(l)->format.num_channels);
-
- stream_list_add(l, &s2_config, &s2);
- EXPECT_EQ(2, add_called);
- EXPECT_EQ(2, create_called);
- EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
- EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
-
- stream_list_add(l, &s3_config, &s3);
- EXPECT_EQ(3, add_called);
- EXPECT_EQ(3, create_called);
- EXPECT_EQ(8, stream_list_get(l)->format.num_channels);
- EXPECT_EQ(6, stream_list_get(l)->next->format.num_channels);
- EXPECT_EQ(2, stream_list_get(l)->next->next->format.num_channels);
- EXPECT_EQ(0, stream_list_rm(l, 0x4001));
- EXPECT_EQ(0, stream_list_rm(l, 0x4002));
- EXPECT_EQ(0, stream_list_rm(l, 0x4003));
- stream_list_destroy(l);
-}
-
-TEST(StreamList, DetectRtcStreamPair) {
- struct stream_list* l;
- struct cras_rstream *s1, *s2, *s3, *s4;
- struct cras_rstream_config s1_config, s2_config, s3_config, s4_config;
-
- s1_config.stream_id = 0x5001;
- s1_config.direction = CRAS_STREAM_OUTPUT;
- s1_config.cb_threshold = 480;
- s1_config.client_type = CRAS_CLIENT_TYPE_CHROME;
- s1_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- s1_config.format = NULL;
-
- s2_config.stream_id = 0x5002;
- s2_config.direction = CRAS_STREAM_INPUT;
- s2_config.cb_threshold = 480;
- s2_config.client_type = CRAS_CLIENT_TYPE_CHROME;
- s2_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- s2_config.format = NULL;
-
- // s3 is not a RTC stream because the cb threshold is not 480.
- s3_config.stream_id = 0x5003;
- s3_config.direction = CRAS_STREAM_INPUT;
- s3_config.cb_threshold = 500;
- s3_config.client_type = CRAS_CLIENT_TYPE_CHROME;
- s3_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- s3_config.format = NULL;
-
- // s4 is not a RTC stream because it is not from the same client with s1.
- s4_config.stream_id = 0x5004;
- s4_config.direction = CRAS_STREAM_INPUT;
- s4_config.cb_threshold = 480;
- s4_config.client_type = CRAS_CLIENT_TYPE_LACROS;
- s4_config.stream_type = CRAS_STREAM_TYPE_DEFAULT;
- s4_config.format = NULL;
-
- reset_test_data();
- l = stream_list_create(added_cb, removed_cb, create_rstream_cb,
- destroy_rstream_cb, NULL);
- stream_list_add(l, &s1_config, &s1);
- EXPECT_EQ(1, add_called);
- EXPECT_EQ(1, create_called);
- EXPECT_EQ(&s1_config, create_config);
-
- stream_list_add(l, &s2_config, &s2);
- detect_rtc_stream_pair(l, s2);
- stream_list_add(l, &s3_config, &s3);
- detect_rtc_stream_pair(l, s3);
- stream_list_add(l, &s4_config, &s4);
- detect_rtc_stream_pair(l, s4);
-
- EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s1->stream_type);
- EXPECT_EQ(CRAS_STREAM_TYPE_VOICE_COMMUNICATION, s2->stream_type);
- EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s3->stream_type);
- EXPECT_EQ(CRAS_STREAM_TYPE_DEFAULT, s4->stream_type);
-
- EXPECT_EQ(0, stream_list_rm(l, 0x5001));
- EXPECT_EQ(0, stream_list_rm(l, 0x5002));
- EXPECT_EQ(0, stream_list_rm(l, 0x5003));
- EXPECT_EQ(0, stream_list_rm(l, 0x5004));
- stream_list_destroy(l);
-}
-
extern "C" {
struct cras_timer* cras_tm_create_timer(struct cras_tm* tm,
diff --git a/cras/src/tests/system_state_unittest.cc b/cras/src/tests/system_state_unittest.cc
index 45224bc9..9e7ecc8b 100644
--- a/cras/src/tests/system_state_unittest.cc
+++ b/cras/src/tests/system_state_unittest.cc
@@ -4,11 +4,9 @@
#include <gtest/gtest.h>
#include <stdio.h>
-#include <string.h>
extern "C" {
#include "cras_alert.h"
-#include "cras_board_config.h"
#include "cras_shm.h"
#include "cras_system_state.h"
#include "cras_types.h"
@@ -35,13 +33,10 @@ static char* device_config_dir;
static const char* cras_alsa_card_config_dir;
static size_t cras_observer_notify_output_volume_called;
static size_t cras_observer_notify_output_mute_called;
+static size_t cras_observer_notify_capture_gain_called;
static size_t cras_observer_notify_capture_mute_called;
static size_t cras_observer_notify_suspend_changed_called;
static size_t cras_observer_notify_num_active_streams_called;
-static size_t cras_observer_notify_input_streams_with_permission_called;
-static size_t cras_iodev_list_reset_for_noise_cancellation_called;
-static struct cras_board_config fake_board_config;
-static size_t cras_alert_process_all_pending_alerts_called;
static void ResetStubData() {
cras_alsa_card_create_called = 0;
@@ -58,19 +53,15 @@ static void ResetStubData() {
cras_alsa_card_config_dir = NULL;
cras_observer_notify_output_volume_called = 0;
cras_observer_notify_output_mute_called = 0;
+ cras_observer_notify_capture_gain_called = 0;
cras_observer_notify_capture_mute_called = 0;
cras_observer_notify_suspend_changed_called = 0;
cras_observer_notify_num_active_streams_called = 0;
- cras_observer_notify_input_streams_with_permission_called = 0;
- cras_alert_process_all_pending_alerts_called = 0;
- cras_iodev_list_reset_for_noise_cancellation_called = 0;
- memset(&fake_board_config, 0, sizeof(fake_board_config));
}
static int add_stub(int fd,
- void (*cb)(void* data, int revents),
+ void (*cb)(void* data),
void* callback_data,
- int events,
void* select_data) {
add_stub_called++;
select_data_value = select_data;
@@ -90,11 +81,7 @@ static int add_task_stub(void (*cb)(void* data),
return 0;
}
-static void callback_stub(void* data, int revents) {
- callback_stub_called++;
-}
-
-static void task_stub(void* data) {
+static void callback_stub(void* data) {
callback_stub_called++;
}
@@ -116,6 +103,7 @@ static void do_sys_init() {
TEST(SystemStateSuite, DefaultVolume) {
do_sys_init();
EXPECT_EQ(100, cras_system_get_volume());
+ EXPECT_EQ(2000, cras_system_get_capture_gain());
EXPECT_EQ(0, cras_system_get_mute());
EXPECT_EQ(0, cras_system_get_capture_mute());
cras_system_state_deinit();
@@ -143,6 +131,46 @@ TEST(SystemStateSuite, SetMinMaxVolume) {
cras_system_state_deinit();
}
+TEST(SystemStateSuite, SetCaptureVolume) {
+ do_sys_init();
+ cras_system_set_capture_gain(0);
+ EXPECT_EQ(0, cras_system_get_capture_gain());
+ cras_system_set_capture_gain(3000);
+ EXPECT_EQ(3000, cras_system_get_capture_gain());
+ // Check that it is limited to the minimum allowed gain.
+ cras_system_set_capture_gain(-10000);
+ EXPECT_EQ(-5000, cras_system_get_capture_gain());
+ cras_system_state_deinit();
+ EXPECT_EQ(3, cras_observer_notify_capture_gain_called);
+}
+
+TEST(SystemStateSuite, SetCaptureVolumeStoreTarget) {
+ do_sys_init();
+ cras_system_set_capture_gain_limits(-2000, 2000);
+ cras_system_set_capture_gain(3000);
+ // Gain is within the limit.
+ EXPECT_EQ(2000, cras_system_get_capture_gain());
+
+ // Assume the range is changed.
+ cras_system_set_capture_gain_limits(-4000, 4000);
+
+ // Gain is also changed because target gain is re-applied.
+ EXPECT_EQ(3000, cras_system_get_capture_gain());
+
+ cras_system_state_deinit();
+}
+
+TEST(SystemStateSuite, SetMinMaxCaptureGain) {
+ do_sys_init();
+ cras_system_set_capture_gain(3000);
+ cras_system_set_capture_gain_limits(-2000, 2000);
+ EXPECT_EQ(-2000, cras_system_get_min_capture_gain());
+ EXPECT_EQ(2000, cras_system_get_max_capture_gain());
+ // Current gain is adjusted for range.
+ EXPECT_EQ(2000, cras_system_get_capture_gain());
+ cras_system_state_deinit();
+}
+
TEST(SystemStateSuite, SetUserMute) {
ResetStubData();
do_sys_init();
@@ -279,7 +307,6 @@ TEST(SystemStateSuite, Suspend) {
cras_system_set_suspended(1);
EXPECT_EQ(1, cras_observer_notify_suspend_changed_called);
- EXPECT_EQ(1, cras_alert_process_all_pending_alerts_called);
EXPECT_EQ(1, cras_system_get_suspended());
cras_system_set_suspended(0);
@@ -330,7 +357,7 @@ TEST(SystemSettingsRegisterSelectDescriptor, AddSelectFd) {
ResetStubData();
do_sys_init();
- rc = cras_system_add_select_fd(7, callback_stub, stub_data, POLLIN);
+ rc = cras_system_add_select_fd(7, callback_stub, stub_data);
EXPECT_NE(0, rc);
EXPECT_EQ(0, add_stub_called);
EXPECT_EQ(0, rm_stub_called);
@@ -342,7 +369,7 @@ TEST(SystemSettingsRegisterSelectDescriptor, AddSelectFd) {
EXPECT_EQ(-EEXIST, rc);
EXPECT_EQ(0, add_stub_called);
EXPECT_EQ(0, rm_stub_called);
- rc = cras_system_add_select_fd(7, callback_stub, stub_data, POLLIN);
+ rc = cras_system_add_select_fd(7, callback_stub, stub_data);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, add_stub_called);
EXPECT_EQ(select_data, select_data_value);
@@ -359,13 +386,13 @@ TEST(SystemSettingsAddTask, AddTask) {
int rc;
do_sys_init();
- rc = cras_system_add_task(task_stub, stub_data);
+ rc = cras_system_add_task(callback_stub, stub_data);
EXPECT_NE(0, rc);
EXPECT_EQ(0, add_task_stub_called);
rc = cras_system_set_add_task_handler(add_task_stub, task_data);
EXPECT_EQ(0, rc);
EXPECT_EQ(0, add_task_stub_called);
- rc = cras_system_add_task(task_stub, stub_data);
+ rc = cras_system_add_task(callback_stub, stub_data);
EXPECT_EQ(0, rc);
EXPECT_EQ(1, add_task_stub_called);
EXPECT_EQ(task_data, task_data_value);
@@ -378,11 +405,11 @@ TEST(SystemSettingsStreamCount, StreamCount) {
do_sys_init();
EXPECT_EQ(0, cras_system_state_get_active_streams());
- cras_system_state_stream_added(CRAS_STREAM_OUTPUT, CRAS_CLIENT_TYPE_CHROME);
+ cras_system_state_stream_added(CRAS_STREAM_OUTPUT);
EXPECT_EQ(1, cras_system_state_get_active_streams());
struct cras_timespec ts1;
cras_system_state_get_last_stream_active_time(&ts1);
- cras_system_state_stream_removed(CRAS_STREAM_OUTPUT, CRAS_CLIENT_TYPE_CHROME);
+ cras_system_state_stream_removed(CRAS_STREAM_OUTPUT);
EXPECT_EQ(0, cras_system_state_get_active_streams());
struct cras_timespec ts2;
cras_system_state_get_last_stream_active_time(&ts2);
@@ -395,11 +422,9 @@ TEST(SystemSettingsStreamCount, StreamCountByDirection) {
do_sys_init();
EXPECT_EQ(0, cras_system_state_get_active_streams());
- cras_system_state_stream_added(CRAS_STREAM_OUTPUT, CRAS_CLIENT_TYPE_CHROME);
- cras_system_state_stream_added(CRAS_STREAM_INPUT, CRAS_CLIENT_TYPE_CHROME);
- cras_system_state_stream_added(CRAS_STREAM_POST_MIX_PRE_DSP,
- CRAS_CLIENT_TYPE_CHROME);
- EXPECT_EQ(1, cras_observer_notify_input_streams_with_permission_called);
+ cras_system_state_stream_added(CRAS_STREAM_OUTPUT);
+ cras_system_state_stream_added(CRAS_STREAM_INPUT);
+ cras_system_state_stream_added(CRAS_STREAM_POST_MIX_PRE_DSP);
EXPECT_EQ(
1, cras_system_state_get_active_streams_by_direction(CRAS_STREAM_OUTPUT));
EXPECT_EQ(
@@ -408,11 +433,9 @@ TEST(SystemSettingsStreamCount, StreamCountByDirection) {
CRAS_STREAM_POST_MIX_PRE_DSP));
EXPECT_EQ(3, cras_system_state_get_active_streams());
EXPECT_EQ(3, cras_observer_notify_num_active_streams_called);
- cras_system_state_stream_removed(CRAS_STREAM_OUTPUT, CRAS_CLIENT_TYPE_CHROME);
- cras_system_state_stream_removed(CRAS_STREAM_INPUT, CRAS_CLIENT_TYPE_CHROME);
- cras_system_state_stream_removed(CRAS_STREAM_POST_MIX_PRE_DSP,
- CRAS_CLIENT_TYPE_CHROME);
- EXPECT_EQ(2, cras_observer_notify_input_streams_with_permission_called);
+ cras_system_state_stream_removed(CRAS_STREAM_OUTPUT);
+ cras_system_state_stream_removed(CRAS_STREAM_INPUT);
+ cras_system_state_stream_removed(CRAS_STREAM_POST_MIX_PRE_DSP);
EXPECT_EQ(
0, cras_system_state_get_active_streams_by_direction(CRAS_STREAM_OUTPUT));
EXPECT_EQ(
@@ -425,50 +448,12 @@ TEST(SystemSettingsStreamCount, StreamCountByDirection) {
cras_system_state_deinit();
}
-TEST(SystemStateSuite, IgnoreUCMSuffix) {
- fake_board_config.ucm_ignore_suffix = strdup("TEST1,TEST2,TEST3");
- do_sys_init();
-
- EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix("TEST1"));
- EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix("TEST2"));
- EXPECT_EQ(1, cras_system_check_ignore_ucm_suffix("TEST3"));
- EXPECT_EQ(0, cras_system_check_ignore_ucm_suffix("TEST4"));
- cras_system_state_deinit();
-}
-
-TEST(SystemStateSuite, SetNoiseCancellationEnabled) {
- ResetStubData();
- do_sys_init();
-
- EXPECT_EQ(0, cras_system_get_noise_cancellation_enabled());
-
- cras_system_set_noise_cancellation_enabled(0);
- EXPECT_EQ(0, cras_system_get_noise_cancellation_enabled());
- EXPECT_EQ(0, cras_iodev_list_reset_for_noise_cancellation_called);
-
- cras_system_set_noise_cancellation_enabled(1);
- EXPECT_EQ(1, cras_system_get_noise_cancellation_enabled());
- EXPECT_EQ(1, cras_iodev_list_reset_for_noise_cancellation_called);
-
- cras_system_set_noise_cancellation_enabled(1);
- EXPECT_EQ(1, cras_system_get_noise_cancellation_enabled());
- // cras_iodev_list_reset_for_noise_cancellation shouldn't be called if state
- // is already enabled/disabled.
- EXPECT_EQ(1, cras_iodev_list_reset_for_noise_cancellation_called);
-
- cras_system_set_noise_cancellation_enabled(0);
- EXPECT_EQ(0, cras_system_get_noise_cancellation_enabled());
- EXPECT_EQ(2, cras_iodev_list_reset_for_noise_cancellation_called);
-
- cras_system_state_deinit();
-}
-
extern "C" {
struct cras_alsa_card* cras_alsa_card_create(
struct cras_alsa_card_info* info,
const char* device_config_dir,
- struct cras_device_blocklist* blocklist) {
+ struct cras_device_blacklist* blacklist) {
cras_alsa_card_create_called++;
cras_alsa_card_config_dir = device_config_dir;
return kFakeAlsaCard;
@@ -482,12 +467,12 @@ size_t cras_alsa_card_get_index(const struct cras_alsa_card* alsa_card) {
return 0;
}
-struct cras_device_blocklist* cras_device_blocklist_create(
+struct cras_device_blacklist* cras_device_blacklist_create(
const char* config_path) {
return NULL;
}
-void cras_device_blocklist_destroy(struct cras_device_blocklist* blocklist) {}
+void cras_device_blacklist_destroy(struct cras_device_blacklist* blacklist) {}
struct cras_alert* cras_alert_create(cras_alert_prepare prepare,
unsigned int flags) {
@@ -536,6 +521,10 @@ void cras_observer_notify_output_mute(int muted,
cras_observer_notify_output_mute_called++;
}
+void cras_observer_notify_capture_gain(int32_t gain) {
+ cras_observer_notify_capture_gain_called++;
+}
+
void cras_observer_notify_capture_mute(int muted, int mute_locked) {
cras_observer_notify_capture_mute_called++;
}
@@ -549,24 +538,6 @@ void cras_observer_notify_num_active_streams(enum CRAS_STREAM_DIRECTION dir,
cras_observer_notify_num_active_streams_called++;
}
-void cras_observer_notify_input_streams_with_permission(
- uint32_t num_input_streams[CRAS_NUM_CLIENT_TYPE]) {
- cras_observer_notify_input_streams_with_permission_called++;
-}
-
-void cras_board_config_get(const char* config_path,
- struct cras_board_config* board_config) {
- *board_config = fake_board_config;
-}
-
-void cras_alert_process_all_pending_alerts() {
- cras_alert_process_all_pending_alerts_called++;
-}
-
-void cras_iodev_list_reset_for_noise_cancellation() {
- cras_iodev_list_reset_for_noise_cancellation_called++;
-}
-
} // extern "C"
} // namespace
diff --git a/cras/src/tests/timing_unittest.cc b/cras/src/tests/timing_unittest.cc
index 964f30c3..beba2f72 100644
--- a/cras/src/tests/timing_unittest.cc
+++ b/cras/src/tests/timing_unittest.cc
@@ -93,9 +93,10 @@ class TimingSuite : public testing::Test {
// Set response for frames_queued.
iodev_stub_frames_queued(dev->dev.get(), dev_level, *level_timestamp);
- struct timespec dev_time;
+ struct timespec dev_time, now;
dev_time.tv_sec = level_timestamp->tv_sec + 500; // Far in the future.
- dev_io_next_output_wake(&dev_list_, &dev_time);
+ clock_gettime(CLOCK_MONOTONIC_RAW, &now);
+ dev_io_next_output_wake(&dev_list_, &dev_time, &now);
return dev_time;
}
};
@@ -111,21 +112,20 @@ int clock_gettime(clockid_t clk_id, struct timespec* tp) {
// Add a new input stream, make sure the initial next_cb_ts is 0.
TEST_F(TimingSuite, NewInputStreamInit) {
- struct open_dev* odev_list_ = NULL;
- struct open_dev* idev_list_ = NULL;
+ struct open_dev* dev_list_ = NULL;
cras_audio_format format;
fill_audio_format(&format, 48000);
DevicePtr dev =
create_device(CRAS_STREAM_INPUT, 1024, &format, CRAS_NODE_TYPE_MIC);
- DL_APPEND(idev_list_, dev->odev.get());
+ DL_APPEND(dev_list_, dev->odev.get());
struct cras_iodev* iodev = dev->odev->dev;
ShmPtr shm = create_shm(480);
RstreamPtr rstream =
create_rstream(1, CRAS_STREAM_INPUT, 480, &format, shm.get());
- dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
+ dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
EXPECT_EQ(0, rstream->next_cb_ts.tv_sec);
EXPECT_EQ(0, rstream->next_cb_ts.tv_nsec);
@@ -807,68 +807,23 @@ TEST_F(TimingSuite, HotwordStreamBulkDataIsNotPending) {
// When a new output stream is added, there are two rules to determine the
// initial next_cb_ts.
-// 1. If there is a matched input stream, use the next_cb_ts and
-// sleep_interval_ts from that input stream as the initial values.
-// 2. If the device already has streams, the next_cb_ts will be the earliest
+// 1. If the device already has streams, the next_cb_ts will be the earliest
// next callback time from these streams.
-// 3. If there are no other streams, the next_cb_ts will be set to the time
+// 2. If there are no other streams, the next_cb_ts will be set to the time
// when the valid frames in device is lower than cb_threshold. (If it is
// already lower than cb_threshold, set next_cb_ts to now.)
// Test rule 1.
-// There is a matched input stream. The next_cb_ts of the newly added output
-// stream will use the next_cb_ts from the input stream.
-TEST_F(TimingSuite, NewOutputStreamInitExistMatchedStream) {
- struct open_dev* odev_list_ = NULL;
- struct open_dev* idev_list_ = NULL;
-
- cras_audio_format format;
- fill_audio_format(&format, 48000);
- DevicePtr out_dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
- CRAS_NODE_TYPE_HEADPHONE);
- DL_APPEND(odev_list_, out_dev->odev.get());
- struct cras_iodev* out_iodev = out_dev->odev->dev;
-
- DevicePtr in_dev =
- create_device(CRAS_STREAM_INPUT, 1024, &format, CRAS_NODE_TYPE_MIC);
- DL_APPEND(idev_list_, in_dev->odev.get());
-
- StreamPtr in_stream = create_stream(1, 1, CRAS_STREAM_INPUT, 480, &format);
- add_stream_to_dev(in_dev->dev, in_stream);
- in_stream->rstream->next_cb_ts.tv_sec = 54321;
- in_stream->rstream->next_cb_ts.tv_nsec = 12345;
- in_stream->rstream->sleep_interval_ts.tv_sec = 321;
- in_stream->rstream->sleep_interval_ts.tv_nsec = 123;
-
- ShmPtr shm = create_shm(480);
- RstreamPtr rstream =
- create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
-
- dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &out_iodev, 1);
-
- EXPECT_EQ(in_stream->rstream->next_cb_ts.tv_sec, rstream->next_cb_ts.tv_sec);
- EXPECT_EQ(in_stream->rstream->next_cb_ts.tv_nsec,
- rstream->next_cb_ts.tv_nsec);
- EXPECT_EQ(in_stream->rstream->sleep_interval_ts.tv_sec,
- rstream->sleep_interval_ts.tv_sec);
- EXPECT_EQ(in_stream->rstream->sleep_interval_ts.tv_nsec,
- rstream->sleep_interval_ts.tv_nsec);
-
- dev_stream_destroy(out_iodev->streams);
-}
-
-// Test rule 2.
// The device already has streams, the next_cb_ts will be the earliest
// next_cb_ts from these streams.
TEST_F(TimingSuite, NewOutputStreamInitStreamInDevice) {
- struct open_dev* odev_list_ = NULL;
- struct open_dev* idev_list_ = NULL;
+ struct open_dev* dev_list_ = NULL;
cras_audio_format format;
fill_audio_format(&format, 48000);
DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
CRAS_NODE_TYPE_HEADPHONE);
- DL_APPEND(odev_list_, dev->odev.get());
+ DL_APPEND(dev_list_, dev->odev.get());
struct cras_iodev* iodev = dev->odev->dev;
StreamPtr stream = create_stream(1, 1, CRAS_STREAM_OUTPUT, 480, &format);
@@ -880,7 +835,7 @@ TEST_F(TimingSuite, NewOutputStreamInitStreamInDevice) {
RstreamPtr rstream =
create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
- dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
+ dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
EXPECT_EQ(stream->rstream->next_cb_ts.tv_sec, rstream->next_cb_ts.tv_sec);
EXPECT_EQ(stream->rstream->next_cb_ts.tv_nsec, rstream->next_cb_ts.tv_nsec);
@@ -888,18 +843,17 @@ TEST_F(TimingSuite, NewOutputStreamInitStreamInDevice) {
dev_stream_destroy(iodev->streams->next);
}
-// Test rule 3.
+// Test rule 2.
// The there are no streams and no frames in device buffer. The next_cb_ts
// will be set to now.
TEST_F(TimingSuite, NewOutputStreamInitNoStreamNoFramesInDevice) {
- struct open_dev* odev_list_ = NULL;
- struct open_dev* idev_list_ = NULL;
+ struct open_dev* dev_list_ = NULL;
cras_audio_format format;
fill_audio_format(&format, 48000);
DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
CRAS_NODE_TYPE_HEADPHONE);
- DL_APPEND(odev_list_, dev->odev.get());
+ DL_APPEND(dev_list_, dev->odev.get());
struct cras_iodev* iodev = dev->odev->dev;
struct timespec start;
@@ -909,7 +863,7 @@ TEST_F(TimingSuite, NewOutputStreamInitNoStreamNoFramesInDevice) {
RstreamPtr rstream =
create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
- dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
+ dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
EXPECT_EQ(start.tv_sec, rstream->next_cb_ts.tv_sec);
EXPECT_EQ(start.tv_nsec, rstream->next_cb_ts.tv_nsec);
@@ -922,14 +876,13 @@ TEST_F(TimingSuite, NewOutputStreamInitNoStreamNoFramesInDevice) {
// next_cb_ts will be set to the time that valid frames in device is lower
// than cb_threshold.
TEST_F(TimingSuite, NewOutputStreamInitNoStreamSomeFramesInDevice) {
- struct open_dev* odev_list_ = NULL;
- struct open_dev* idev_list_ = NULL;
+ struct open_dev* dev_list_ = NULL;
cras_audio_format format;
fill_audio_format(&format, 48000);
DevicePtr dev = create_device(CRAS_STREAM_OUTPUT, 1024, &format,
CRAS_NODE_TYPE_HEADPHONE);
- DL_APPEND(odev_list_, dev->odev.get());
+ DL_APPEND(dev_list_, dev->odev.get());
struct cras_iodev* iodev = dev->odev->dev;
struct timespec start;
@@ -941,7 +894,7 @@ TEST_F(TimingSuite, NewOutputStreamInitNoStreamSomeFramesInDevice) {
RstreamPtr rstream =
create_rstream(1, CRAS_STREAM_OUTPUT, 480, &format, shm.get());
- dev_io_append_stream(&odev_list_, &idev_list_, rstream.get(), &iodev, 1);
+ dev_io_append_stream(&dev_list_, rstream.get(), &iodev, 1);
// The next_cb_ts should be 10ms from now. At that time there are
// only 480 valid frames in the device.
@@ -1210,12 +1163,6 @@ int input_data_put_for_stream(struct input_data* data,
return 0;
}
-float input_data_get_software_gain_scaler(struct input_data* data,
- float idev_sw_gain_scaler,
- struct cras_rstream* stream) {
- return 1.0;
-}
-
struct cras_audio_format* cras_rstream_post_processing_format(
const struct cras_rstream* stream,
void* dev_ptr) {
@@ -1226,15 +1173,6 @@ int cras_audio_thread_event_drop_samples() {
return 0;
}
-int cras_audio_thread_event_severe_underrun() {
- return 0;
-}
-
-void* buffer_share_get_data(const struct buffer_share* mix, unsigned int id) {
- return NULL;
-};
-void cras_apm_list_start_apm(struct cras_apm_list* list, void* dev_ptr){};
-void cras_apm_list_stop_apm(struct cras_apm_list* list, void* dev_ptr){};
} // extern "C"
} // namespace
diff --git a/cras/src/tools/cras_monitor/cras_monitor.c b/cras/src/tools/cras_monitor/cras_monitor.c
index 19252773..d021669a 100644
--- a/cras/src/tools/cras_monitor/cras_monitor.c
+++ b/cras/src/tools/cras_monitor/cras_monitor.c
@@ -31,6 +31,11 @@ static void output_mute_changed(void *context, int muted, int user_muted,
muted, user_muted, mute_locked);
}
+static void capture_gain_changed(void *context, int32_t gain)
+{
+ printf("capture gain: %d\n", gain);
+}
+
static void capture_mute_changed(void *context, int muted, int mute_locked)
{
printf("capture mute: muted: %d, mute_locked: %d\n", muted,
@@ -266,6 +271,8 @@ int main(int argc, char **argv)
output_volume_changed);
cras_client_set_output_mute_changed_callback(client,
output_mute_changed);
+ cras_client_set_capture_gain_changed_callback(client,
+ capture_gain_changed);
cras_client_set_capture_mute_changed_callback(client,
capture_mute_changed);
cras_client_set_nodes_changed_callback(client, nodes_changed);
diff --git a/cras/src/tools/cras_test_client/cras_test_client.c b/cras/src/tools/cras_test_client/cras_test_client.c
index 7a851852..a7845069 100644
--- a/cras/src/tools/cras_test_client/cras_test_client.c
+++ b/cras/src/tools/cras_test_client/cras_test_client.c
@@ -310,7 +310,7 @@ put_stdin_samples(struct cras_client *client, cras_stream_id_t stream_id,
int rc = 0;
uint32_t frame_bytes = cras_client_format_bytes_per_frame(aud_format);
- rc = read(0, playback_samples, (size_t)frames * (size_t)frame_bytes);
+ rc = read(0, playback_samples, frames * frame_bytes);
if (rc <= 0) {
terminate_stream_loop();
return -1;
@@ -354,50 +354,30 @@ static void print_dev_info(const struct cras_iodev_info *devs, int num_devs)
{
unsigned i;
- printf("\tID\tMaxCha\tName\n");
+ printf("\tID\tName\n");
for (i = 0; i < num_devs; i++)
- printf("\t%u\t%u\t%s\n", devs[i].idx,
- devs[i].max_supported_channels, devs[i].name);
+ printf("\t%u\t%s\n", devs[i].idx, devs[i].name);
}
-static void print_node_info(struct cras_client *client,
- const struct cras_ionode_info *nodes, int num_nodes,
+static void print_node_info(const struct cras_ionode_info *nodes, int num_nodes,
int is_input)
{
unsigned i;
- printf("\tStable Id\t ID\t%4s UI Plugged\tL/R swapped\t "
- "Time Hotword\tType\t\tMaxCha Name\n",
+ printf("\tStable Id\t ID\t%4s Plugged\tL/R swapped\t "
+ "Time Hotword\tType\t\t Name\n",
is_input ? "Gain" : " Vol");
- for (i = 0; i < num_nodes; i++) {
- char max_channels_str[7];
- if (is_input) {
- // Print "X" as don't-care for input nodes because
- // cras_client_get_max_supported_channels() is only valid for outputs.
- strcpy(max_channels_str, " X");
- } else {
- uint32_t max_channels;
- int rc = cras_client_get_max_supported_channels(
- client,
- cras_make_node_id(nodes[i].iodev_idx,
- nodes[i].ionode_idx),
- &max_channels);
- if (rc)
- max_channels = 0;
- sprintf(max_channels_str, "%6u", max_channels);
- }
- printf("\t(%08x)\t%u:%u\t%5g %f %7s\t%14s\t%10ld %-7s\t%-16s%-6s%c%s\n",
+ for (i = 0; i < num_nodes; i++)
+ printf("\t(%08x)\t%u:%u\t%5g %7s\t%14s\t%10ld %-7s\t%-16s%c%s\n",
nodes[i].stable_id, nodes[i].iodev_idx,
nodes[i].ionode_idx,
is_input ? nodes[i].capture_gain / 100.0 :
(double)nodes[i].volume,
- nodes[i].ui_gain_scaler, nodes[i].plugged ? "yes" : "no",
+ nodes[i].plugged ? "yes" : "no",
nodes[i].left_right_swapped ? "yes" : "no",
(long)nodes[i].plugged_time.tv_sec,
nodes[i].active_hotword_model, nodes[i].type,
- max_channels_str, nodes[i].active ? '*' : ' ',
- nodes[i].name);
- }
+ nodes[i].active ? '*' : ' ', nodes[i].name);
}
static void print_device_lists(struct cras_client *client)
@@ -416,7 +396,7 @@ static void print_device_lists(struct cras_client *client)
printf("Output Devices:\n");
print_dev_info(devs, num_devs);
printf("Output Nodes:\n");
- print_node_info(client, nodes, num_nodes, 0);
+ print_node_info(nodes, num_nodes, 0);
num_devs = MAX_IODEVS;
num_nodes = MAX_IONODES;
@@ -425,7 +405,7 @@ static void print_device_lists(struct cras_client *client)
printf("Input Devices:\n");
print_dev_info(devs, num_devs);
printf("Input Nodes:\n");
- print_node_info(client, nodes, num_nodes, 1);
+ print_node_info(nodes, num_nodes, 1);
}
static void print_attached_client_list(struct cras_client *client)
@@ -460,11 +440,13 @@ static void print_active_stream_info(struct cras_client *client)
static void print_system_volumes(struct cras_client *client)
{
printf("System Volume (0-100): %zu %s\n"
- "Capture Muted : %s\n",
+ "Capture Gain (%.2f - %.2f): %.2fdB %s\n",
cras_client_get_system_volume(client),
cras_client_get_system_muted(client) ? "(Muted)" : "",
- cras_client_get_system_capture_muted(client) ? "Muted" :
- "Not muted");
+ cras_client_get_system_min_capture_gain(client) / 100.0,
+ cras_client_get_system_max_capture_gain(client) / 100.0,
+ cras_client_get_system_capture_gain(client) / 100.0,
+ cras_client_get_system_capture_muted(client) ? "(Muted)" : "");
}
static void print_user_muted(struct cras_client *client)
@@ -493,26 +475,6 @@ static void convert_time(unsigned int *sec, unsigned int *nsec,
*nsec = nsec_offset;
}
-static float get_ewma_power_as_float(uint32_t data)
-{
- float f = 0.0f;
-
- /* Convert from the uint32_t log type back to float.
- * If data cannot be assigned to float, default value will
- * be printed as -inf to hint the problem.
- */
- if (sizeof(uint32_t) == sizeof(float))
- memcpy(&f, &data, sizeof(float));
- else
- printf("%-30s float to uint32_t\n", "MEMORY_NOT_ALIGNED");
-
- /* Convert to dBFS and set to zero if it's
- * insignificantly low. Picking the same threshold
- * 1.0e-10f as in Chrome.
- */
- return (f < 1.0e-10f) ? -INFINITY : 10.0f * log10f(f);
-}
-
static void show_alog_tag(const struct audio_thread_event_log *log,
unsigned int tag_idx, int32_t sec_offset,
int32_t nsec_offset)
@@ -524,23 +486,22 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
unsigned int data2 = log->log[tag_idx].data2;
unsigned int data3 = log->log[tag_idx].data3;
time_t lt;
- struct tm t;
+ struct tm *t;
/* Skip unused log entries. */
if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
return;
- /* Convert from monotonic raw clock to realtime clock. */
+ /* Convert from monotomic raw clock to realtime clock. */
convert_time(&sec, &nsec, sec_offset, nsec_offset);
lt = sec;
- localtime_r(&lt, &t);
- strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", &t);
+ t = localtime(&lt);
+ strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", t);
printf("%s.%09u cras atlog ", time_str, nsec);
/* Prepare realtime string for arguments. */
switch (tag) {
- case AUDIO_THREAD_A2DP_FLUSH:
case AUDIO_THREAD_READ_AUDIO_TSTAMP:
case AUDIO_THREAD_FILL_AUDIO_TSTAMP:
case AUDIO_THREAD_STREAM_RESCHEDULE:
@@ -553,16 +514,16 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
}
convert_time(&sec, &nsec, sec_offset, nsec_offset);
lt = sec;
- localtime_r(&lt, &t);
- strftime(time_str, 128, " %H:%M:%S", &t);
+ t = localtime(&lt);
+ strftime(time_str, 128, " %H:%M:%S", t);
switch (tag) {
case AUDIO_THREAD_WAKE:
printf("%-30s num_fds:%d\n", "WAKE", (int)data1);
break;
case AUDIO_THREAD_SLEEP:
- printf("%-30s sleep:%09d.%09d non_empty %u\n", "SLEEP",
- (int)data1, (int)data2, (int)data3);
+ printf("%-30s sleep:%09d.%09d\n", "SLEEP", (int)data1,
+ (int)data2);
break;
case AUDIO_THREAD_READ_AUDIO:
printf("%-30s dev:%u hw_level:%u read:%u\n", "READ_AUDIO",
@@ -572,30 +533,25 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
printf("%-30s dev:%u tstamp:%s.%09u\n", "READ_AUDIO_TSTAMP",
data1, time_str, nsec);
break;
- case AUDIO_THREAD_READ_AUDIO_DONE: {
- float f = get_ewma_power_as_float(data2);
- printf("%-30s read_remainder:%u power:%f dBFS\n",
- "READ_AUDIO_DONE", data1, f);
+ case AUDIO_THREAD_READ_AUDIO_DONE:
+ printf("%-30s read_remainder:%u\n", "READ_AUDIO_DONE", data1);
break;
- }
case AUDIO_THREAD_READ_OVERRUN:
printf("%-30s dev:%u stream:%x num_overruns:%u\n",
"READ_AUDIO_OVERRUN", data1, data2, data3);
break;
case AUDIO_THREAD_FILL_AUDIO:
- printf("%-30s dev:%u hw_level:%u min_cb_level:%u\n",
- "FILL_AUDIO", data1, data2, data3);
+ printf("%-30s dev:%u hw_level:%u\n", "FILL_AUDIO", data1,
+ data2);
break;
case AUDIO_THREAD_FILL_AUDIO_TSTAMP:
printf("%-30s dev:%u tstamp:%s.%09u\n", "FILL_AUDIO_TSTAMP",
data1, time_str, nsec);
break;
- case AUDIO_THREAD_FILL_AUDIO_DONE: {
- float f = get_ewma_power_as_float(data3);
- printf("%-30s hw_level:%u total_written:%u power:%f dBFS\n",
- "FILL_AUDIO_DONE", data1, data2, f);
+ case AUDIO_THREAD_FILL_AUDIO_DONE:
+ printf("%-30s hw_level:%u total_written:%u min_cb_level:%u\n",
+ "FILL_AUDIO_DONE", data1, data2, data3);
break;
- }
case AUDIO_THREAD_WRITE_STREAMS_WAIT:
printf("%-30s stream:%x\n", "WRITE_STREAMS_WAIT", data1);
break;
@@ -613,26 +569,19 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
printf("%-30s id:%x shm_frames:%u cb_pending:%u\n",
"WRITE_STREAMS_STREAM", data1, data2, data3);
break;
- case AUDIO_THREAD_FETCH_STREAM: {
- float f = get_ewma_power_as_float(data3);
- printf("%-30s id:%x cbth:%u power:%f dBFS\n",
- "WRITE_STREAMS_FETCH_STREAM", data1, data2, f);
+ case AUDIO_THREAD_FETCH_STREAM:
+ printf("%-30s id:%x cbth:%u delay:%u\n",
+ "WRITE_STREAMS_FETCH_STREAM", data1, data2, data3);
break;
- }
case AUDIO_THREAD_STREAM_ADDED:
printf("%-30s id:%x dev:%u\n", "STREAM_ADDED", data1, data2);
break;
case AUDIO_THREAD_STREAM_REMOVED:
printf("%-30s id:%x\n", "STREAM_REMOVED", data1);
break;
- break;
- case AUDIO_THREAD_A2DP_FLUSH:
- printf("%-30s state %u next flush time:%s.%09u\n", "A2DP_FLUSH",
- data1, time_str, nsec);
- break;
- case AUDIO_THREAD_A2DP_THROTTLE_TIME:
- printf("%-30s %u ms, queued:%u\n", "A2DP_THROTTLE_TIME",
- data1 * 1000 + data2 / 1000000, data3);
+ case AUDIO_THREAD_A2DP_ENCODE:
+ printf("%-30s proc:%d queued:%u readable:%u\n", "A2DP_ENCODE",
+ data1, data2, data3);
break;
case AUDIO_THREAD_A2DP_WRITE:
printf("%-30s written:%d queued:%u\n", "A2DP_WRITE", data1,
@@ -688,8 +637,7 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
printf("%-30s dev:%u\n", "DEV_REMOVED", data1);
break;
case AUDIO_THREAD_IODEV_CB:
- printf("%-30s revents:%u events:%u\n", "IODEV_CB", data1,
- data2);
+ printf("%-30s is_write:%u\n", "IODEV_CB", data1);
break;
case AUDIO_THREAD_PB_MSG:
printf("%-30s msg_id:%u\n", "PB_MSG", data1);
@@ -727,21 +675,6 @@ static void show_alog_tag(const struct audio_thread_event_log *log,
printf("%-30s dev:%u frames:%u\n", "DEV_DROP_FRAMES", data1,
data2);
break;
- case AUDIO_THREAD_LOOPBACK_PUT:
- printf("%-30s nframes_committed:%u\n", "LOOPBACK_PUT", data1);
- break;
- case AUDIO_THREAD_LOOPBACK_GET:
- printf("%-30s nframes_requested:%u avail:%u\n", "LOOPBACK_GET",
- data1, data2);
- break;
- case AUDIO_THREAD_LOOPBACK_SAMPLE_HOOK:
- printf("%-30s frames_to_copy:%u frames_copied:%u\n",
- "LOOPBACK_SAMPLE", data1, data2);
- break;
- case AUDIO_THREAD_DEV_OVERRUN:
- printf("%-30s dev:%u hw_level:%u\n", "DEV_OVERRUN", data1,
- data2);
- break;
default:
printf("%-30s tag:%u\n", "UNKNOWN", tag);
break;
@@ -802,8 +735,8 @@ static void print_audio_debug_info(const struct audio_debug_info *info)
for (i = 0; i < info->num_streams; i++) {
int channel;
- printf("stream: 0x%" PRIx64 " dev: %u\n",
- info->streams[i].stream_id,
+ printf("stream: %llu dev: %u\n",
+ (unsigned long long)info->streams[i].stream_id,
(unsigned int)info->streams[i].dev_idx);
printf("direction: %s\n",
(info->streams[i].direction == CRAS_STREAM_INPUT) ?
@@ -875,92 +808,6 @@ static void audio_debug_info(struct cras_client *client)
pthread_mutex_unlock(&done_mutex);
}
-static void show_mainlog_tag(const struct main_thread_event_log *log,
- unsigned int tag_idx, int32_t sec_offset,
- int32_t nsec_offset)
-{
- unsigned int tag = (log->log[tag_idx].tag_sec >> 24) & 0xff;
- unsigned int sec = log->log[tag_idx].tag_sec & 0x00ffffff;
- unsigned int nsec = log->log[tag_idx].nsec;
- unsigned int data1 = log->log[tag_idx].data1;
- unsigned int data2 = log->log[tag_idx].data2;
- unsigned int data3 = log->log[tag_idx].data3;
- time_t lt;
- struct tm t;
-
- /* Skip unused log entries. */
- if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
- return;
-
- /* Convert from monotomic raw clock to realtime clock. */
- convert_time(&sec, &nsec, sec_offset, nsec_offset);
- lt = sec;
- localtime_r(&lt, &t);
- strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", &t);
-
- printf("%s.%09u cras mainlog ", time_str, nsec);
-
- switch (tag) {
- case MAIN_THREAD_DEV_CLOSE:
- printf("%-30s dev %u\n", "DEV_CLOSE", data1);
- break;
- case MAIN_THREAD_DEV_DISABLE:
- printf("%-30s dev %u force %u\n", "DEV_DISABLE", data1, data2);
- break;
- case MAIN_THREAD_DEV_INIT:
- printf("%-30s dev %u ch %u rate %u\n", "DEV_INIT", data1, data2,
- data3);
- break;
- case MAIN_THREAD_DEV_REOPEN:
- printf("%-30s new ch %u old ch %u rate %u\n", "DEV_REOPEN",
- data1, data2, data3);
- break;
- case MAIN_THREAD_ADD_ACTIVE_NODE:
- printf("%-30s dev %u\n", "ADD_ACTIVE_NODE", data1);
- break;
- case MAIN_THREAD_SELECT_NODE:
- printf("%-30s dev %u\n", "SELECT_NODE", data1);
- break;
- case MAIN_THREAD_ADD_TO_DEV_LIST:
- printf("%-30s dev %u %s\n", "ADD_TO_DEV_LIST", data1,
- (data2 == CRAS_STREAM_OUTPUT) ? "output" : "input");
- break;
- case MAIN_THREAD_NODE_PLUGGED:
- printf("%-30s dev %u %s\n", "NODE_PLUGGED", data1,
- data2 ? "plugged" : "unplugged");
- break;
- case MAIN_THREAD_INPUT_NODE_GAIN:
- printf("%-30s dev %u gain %u\n", "INPUT_NODE_GAIN", data1,
- data2);
- break;
- case MAIN_THREAD_OUTPUT_NODE_VOLUME:
- printf("%-30s dev %u volume %u\n", "OUTPUT_NODE_VOLUME", data1,
- data2);
- break;
- case MAIN_THREAD_SET_OUTPUT_USER_MUTE:
- printf("%-30s mute %u\n", "SET_OUTPUT_USER_MUTE", data1);
- break;
- case MAIN_THREAD_RESUME_DEVS:
- printf("RESUME_DEVS\n");
- break;
- case MAIN_THREAD_SUSPEND_DEVS:
- printf("SUSPEND_DEVS\n");
- break;
- case MAIN_THREAD_STREAM_ADDED:
- printf("%-30s %s stream 0x%x buffer frames %u\n",
- "STREAM_ADDED",
- (data2 == CRAS_STREAM_OUTPUT ? "output" : "input"),
- data1, data3);
- break;
- case MAIN_THREAD_STREAM_REMOVED:
- printf("%-30s stream 0x%x\n", "STREAM_REMOVED", data1);
- break;
- default:
- printf("%-30s\n", "UNKNOWN");
- break;
- }
-}
-
static void show_btlog_tag(const struct cras_bt_event_log *log,
unsigned int tag_idx, int32_t sec_offset,
int32_t nsec_offset)
@@ -971,17 +818,17 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
unsigned int data1 = log->log[tag_idx].data1;
unsigned int data2 = log->log[tag_idx].data2;
time_t lt;
- struct tm t;
+ struct tm *t;
/* Skip unused log entries. */
if (log->log[tag_idx].tag_sec == 0 && log->log[tag_idx].nsec == 0)
return;
- /* Convert from monotonic raw clock to realtime clock. */
+ /* Convert from monotomic raw clock to realtime clock. */
convert_time(&sec, &nsec, sec_offset, nsec_offset);
lt = sec;
- localtime_r(&lt, &t);
- strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", &t);
+ t = localtime(&lt);
+ strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", t);
printf("%s.%09u cras btlog ", time_str, nsec);
@@ -993,7 +840,7 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
printf("%-30s\n", "ADAPTER_REMOVED");
break;
case BT_A2DP_CONFIGURED:
- printf("%-30s connected profiles 0x%.2x\n", "A2DP_CONFIGURED",
+ printf("%-30s connected profiles %u\n", "A2DP_CONFIGURED",
data1);
break;
case BT_A2DP_START:
@@ -1003,8 +850,8 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
printf("%-30s\n", "A2DP_SUSPENDED");
break;
case BT_AUDIO_GATEWAY_INIT:
- printf("%-30s supported profiles 0x%.2x\n",
- "AUDIO_GATEWAY_INIT", data1);
+ printf("%-30s supported profiles %u\n", "AUDIO_GATEWAY_INIT",
+ data1);
break;
case BT_AUDIO_GATEWAY_START:
printf("%-30s \n", "AUDIO_GATEWAY_START");
@@ -1017,34 +864,18 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
printf("%-30s dir %u codec id %u\n", "CODEC_SELECTION", data1,
data2);
break;
- case BT_DEV_CONNECTED:
- printf("%-30s supported profiles 0x%.2x stable_id 0x%08x\n",
- "DEV_CONNECTED", data1, data2);
- break;
- case BT_DEV_DISCONNECTED:
- printf("%-30s supported profiles 0x%.2x stable_id 0x%08x\n",
- "DEV_DISCONNECTED", data1, data2);
+ case BT_DEV_CONNECTED_CHANGE:
+ printf("%-30s profiles %u now %u\n", "DEV_CONENCTED_CHANGE",
+ data1, data2);
break;
case BT_DEV_CONN_WATCH_CB:
- printf("%-30s %u retries left, supported profiles 0x%.2x\n",
+ printf("%-30s %u retries left, supported profiles %u\n",
"DEV_CONN_WATCH_CB", data1, data2);
break;
case BT_DEV_SUSPEND_CB:
- printf("%-30s profiles supported %u, reason %u\n",
+ printf("%-30s profiles supported %u, connected %u\n",
"DEV_SUSPEND_CB", data1, data2);
break;
- case BT_HFP_HF_INDICATOR:
- printf("%-30s HF read AG %s indicator\n", "HFP_HF_INDICATOR",
- data1 ? "enabled" : "supported");
- break;
- case BT_HFP_SET_SPEAKER_GAIN:
- printf("%-30s HF set speaker gain %u\n", "HFP_SET_SPEAKER_GAIN",
- data1);
- break;
- case BT_HFP_UPDATE_SPEAKER_GAIN:
- printf("%-30s HF update speaker gain %u\n",
- "HFP_UPDATE_SPEAKER_GAIN", data1);
- break;
case BT_HFP_NEW_CONNECTION:
printf("%-30s\n", "HFP_NEW_CONNECTION");
break;
@@ -1052,8 +883,8 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
printf("%-30s\n", "HFP_REQUEST_DISCONNECT");
break;
case BT_HFP_SUPPORTED_FEATURES:
- printf("%-30s role %s features 0x%.4x\n",
- "HFP_SUPPORTED_FEATURES", data1 ? "AG" : "HF", data2);
+ printf("%-30s role %s features %u\n", "HFP_SUPPORTED_FEATURES",
+ data1 ? "AG" : "HF", data2);
break;
case BT_HSP_NEW_CONNECTION:
printf("%-30s\n", "HSP_NEW_CONNECTION");
@@ -1062,7 +893,7 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
printf("%-30s\n", "HSP_REQUEST_DISCONNECT");
break;
case BT_NEW_AUDIO_PROFILE_AFTER_CONNECT:
- printf("%-30s old 0x%.2x, new 0x%.2x\n",
+ printf("%-30s old %u, new %u\n",
"NEW_AUDIO_PROFILE_AFTER_CONNECT", data1, data2);
break;
case BT_RESET:
@@ -1079,42 +910,18 @@ static void show_btlog_tag(const struct cras_bt_event_log *log,
case BT_TRANSPORT_RELEASE:
printf("%-30s\n", "TRANSPORT_RELEASE");
break;
- case BT_TRANSPORT_SET_VOLUME:
- printf("%-30s %d\n", "TRANSPORT_SET_VOLUME", data1);
- break;
- case BT_TRANSPORT_UPDATE_VOLUME:
- printf("%-30s %d\n", "TRANSPORT_UPDATE_VOLUME", data1);
- break;
default:
printf("%-30s\n", "UNKNOWN");
break;
}
}
-static void convert_to_time_str(const struct timespec *ts, time_t sec_offset,
- int32_t nsec_offset)
-{
- time_t lt = ts->tv_sec;
- struct tm t;
- unsigned int time_nsec;
-
- /* Assuming tv_nsec doesn't exceed 10^9 */
- time_nsec = ts->tv_nsec;
- convert_time((unsigned int *)&lt, &time_nsec, sec_offset, nsec_offset);
- localtime_r(&lt, &t);
- strftime(time_str, 128, "%Y-%m-%dT%H:%M:%S", &t);
- snprintf(time_str + strlen(time_str), 128 - strlen(time_str), ".%09u",
- time_nsec);
-}
-
static void cras_bt_debug_info(struct cras_client *client)
{
const struct cras_bt_debug_info *info;
time_t sec_offset;
int32_t nsec_offset;
int i, j;
- struct timespec ts;
- struct packet_status_logger wbs_logger;
info = cras_client_get_bt_debug_info(client);
fill_time_offset(&sec_offset, &nsec_offset);
@@ -1127,47 +934,6 @@ static void cras_bt_debug_info(struct cras_client *client)
j %= info->bt_log.len;
}
- printf("-------------WBS packet loss------------\n");
- wbs_logger = info->wbs_logger;
-
- packet_status_logger_begin_ts(&wbs_logger, &ts);
- convert_to_time_str(&ts, sec_offset, nsec_offset);
- printf("%s [begin]\n", time_str);
-
- packet_status_logger_end_ts(&wbs_logger, &ts);
- convert_to_time_str(&ts, sec_offset, nsec_offset);
- printf("%s [end]\n", time_str);
-
- printf("In hex format:\n");
- packet_status_logger_dump_hex(&wbs_logger);
-
- printf("In binary format:\n");
- packet_status_logger_dump_binary(&wbs_logger);
-
- /* Signal main thread we are done after the last chunk. */
- pthread_mutex_lock(&done_mutex);
- pthread_cond_signal(&done_cond);
- pthread_mutex_unlock(&done_mutex);
-}
-
-static void main_thread_debug_info(struct cras_client *client)
-{
- const struct main_thread_debug_info *info;
- time_t sec_offset;
- int32_t nsec_offset;
- int i, j;
-
- info = cras_client_get_main_thread_debug_info(client);
- fill_time_offset(&sec_offset, &nsec_offset);
- j = info->main_log.write_pos;
- i = 0;
- printf("Main debug log:\n");
- for (; i < info->main_log.len; i++) {
- show_mainlog_tag(&info->main_log, j, sec_offset, nsec_offset);
- j++;
- j %= info->main_log.len;
- }
-
/* Signal main thread we are done after the last chunk. */
pthread_mutex_lock(&done_mutex);
pthread_cond_signal(&done_cond);
@@ -1184,9 +950,6 @@ static void print_cras_audio_thread_snapshot(
printf("Event type: ");
switch (snapshot->event_type) {
- case AUDIO_THREAD_EVENT_A2DP_THROTTLE:
- printf("a2dp throttle\n");
- break;
case AUDIO_THREAD_EVENT_BUSYLOOP:
printf("busyloop\n");
break;
@@ -1199,9 +962,6 @@ static void print_cras_audio_thread_snapshot(
case AUDIO_THREAD_EVENT_DROP_SAMPLES:
printf("drop samples\n");
break;
- case AUDIO_THREAD_EVENT_DEV_OVERRUN:
- printf("device overrun\n");
- break;
case AUDIO_THREAD_EVENT_DEBUG:
printf("debug\n");
break;
@@ -1309,6 +1069,7 @@ static int run_file_io_stream(struct cras_client *client, int fd,
struct timespec sleep_ts;
float volume_scaler = 1.0;
size_t sys_volume = 100;
+ long cap_gain = 0;
int mute = 0;
int8_t layout[CRAS_CH_MAX];
@@ -1457,6 +1218,14 @@ static int run_file_io_stream(struct cras_client *client, int fd,
sys_volume = sys_volume == 0 ? 0 : sys_volume - 1;
cras_client_set_system_volume(client, sys_volume);
break;
+ case 'K':
+ cap_gain = MIN(cap_gain + 100, 5000);
+ cras_client_set_system_capture_gain(client, cap_gain);
+ break;
+ case 'J':
+ cap_gain = cap_gain == -5000 ? -5000 : cap_gain - 100;
+ cras_client_set_system_capture_gain(client, cap_gain);
+ break;
case 'm':
mute = !mute;
cras_client_set_system_mute(client, mute);
@@ -1469,16 +1238,19 @@ static int run_file_io_stream(struct cras_client *client, int fd,
break;
case 'v':
printf("Volume: %zu%s Min dB: %ld Max dB: %ld\n"
- "Capture: %s\n",
+ "Capture: %ld%s Min dB: %ld Max dB: %ld\n",
cras_client_get_system_volume(client),
cras_client_get_system_muted(client) ?
"(Muted)" :
"",
cras_client_get_system_min_volume(client),
cras_client_get_system_max_volume(client),
+ cras_client_get_system_capture_gain(client),
cras_client_get_system_capture_muted(client) ?
- "Muted" :
- "Not muted");
+ "(Muted)" :
+ "",
+ cras_client_get_system_min_capture_gain(client),
+ cras_client_get_system_max_capture_gain(client));
break;
case '\'':
play_short_sound_periods_left =
@@ -1607,22 +1379,6 @@ static void show_cras_bt_debug_info(struct cras_client *client)
pthread_mutex_unlock(&done_mutex);
}
-static void show_main_thread_debug_info(struct cras_client *client)
-{
- struct timespec wait_time;
- cras_client_run_thread(client);
- cras_client_connected_wait(client); /* To synchronize data. */
- cras_client_update_main_thread_debug_info(client,
- main_thread_debug_info);
-
- clock_gettime(CLOCK_REALTIME, &wait_time);
- wait_time.tv_sec += 2;
-
- pthread_mutex_lock(&done_mutex);
- pthread_cond_timedwait(&done_cond, &done_mutex, &wait_time);
- pthread_mutex_unlock(&done_mutex);
-}
-
static void hotword_models_cb(struct cras_client *client,
const char *hotword_models)
{
@@ -1653,7 +1409,7 @@ static void check_output_plugged(struct cras_client *client, const char *name)
cras_client_output_dev_plugged(client, name) ? "Yes" : "No");
}
-/* Repeatedly mute and un-mute the output until there is an error. */
+/* Repeatedly mute and unmute the output until there is an error. */
static void mute_loop_test(struct cras_client *client, int auto_reconnect)
{
int mute = 0;
@@ -1718,9 +1474,6 @@ static void cras_show_continuous_atlog(struct cras_client *client)
fill_time_offset(&sec_offset, &nsec_offset);
- /* Set stdout buffer to line buffered mode. */
- setlinebuf(stdout);
-
while (1) {
len = cras_client_read_atlog(client, &atlog_read_idx, &missing,
&log);
@@ -1794,7 +1547,6 @@ static struct option long_options[] = {
{"connection_type", required_argument, 0, 'K'},
{"loopback_file", required_argument, 0, 'L'},
{"mute_loop_test", required_argument, 0, 'M'},
- {"dump_main", no_argument, 0, 'N'},
{"playback_file", required_argument, 0, 'P'},
{"stream_type", required_argument, 0, 'T'},
{0, 0, 0, 0}
@@ -1818,7 +1570,7 @@ static void show_usage()
printf("--capture_file <name> - "
"Name of file to record to.\n");
printf("--capture_gain <dB> - "
- "Set system capture gain in dB*100 (100 = 1dB).\n");
+ "Set system caputre gain in dB*100 (100 = 1dB).\n");
printf("--capture_mute <0|1> - "
"Set capture mute state.\n");
printf("--channel_layout <layout_str> - "
@@ -1832,17 +1584,11 @@ static void show_usage()
" "
" 1 - For playback client.\n"
" "
- " 2 - For capture client.\n"
- " "
- " 3 - For legacy client in vms.\n"
- " "
- " 4 - For unified client in vms.\n");
+ " 2 - For capture client.\n");
printf("--dump_audio_thread - "
"Dumps audio thread info.\n");
printf("--dump_bt - "
"Dumps debug info for bt audio\n");
- printf("--dump_main - "
- "Dumps debug info from main thread\n");
printf("--dump_dsp - "
"Print status of dsp to syslog.\n");
printf("--dump_server_info - "
@@ -1867,7 +1613,7 @@ static void show_usage()
printf("--mute <0|1> - "
"Set system mute state.\n");
printf("--mute_loop_test <0|1> - "
- "Continuously loop mute/un-mute.\n"
+ "Continuously loop mute/umute.\n"
" "
"Argument: 0 - stop on error.\n"
" "
@@ -1921,7 +1667,7 @@ static void show_usage()
printf("--suspend <0|1> - "
"Set audio suspend state.\n");
printf("--swap_left_right <N>:<M>:<0|1> - "
- "Swap or un-swap (1 or 0) the left and right channel for the "
+ "Swap or unswap (1 or 0) the left and right channel for the "
"ionode with the given index M on the device with index N\n");
printf("--stream_type <N> - "
"Specify the type of the stream.\n");
@@ -2044,6 +1790,15 @@ int main(int argc, char **argv)
}
break;
}
+ case 'g': {
+ long gain = atol(optarg);
+ rc = cras_client_set_system_capture_gain(client, gain);
+ if (rc < 0) {
+ fprintf(stderr, "problem setting capture\n");
+ goto destroy_exit;
+ }
+ break;
+ }
case 'h':
show_usage();
break;
@@ -2240,8 +1995,7 @@ int main(int argc, char **argv)
s = strtok(optarg, ":");
nch = atoi(s);
- coeff = (float *)calloc((size_t)nch * (size_t)nch,
- sizeof(*coeff));
+ coeff = (float *)calloc(nch * nch, sizeof(*coeff));
for (size = 0; size < nch * nch; size++) {
s = strtok(NULL, ",");
if (NULL == s)
@@ -2362,9 +2116,6 @@ int main(int argc, char **argv)
case 'M':
mute_loop_test(client, atoi(optarg));
break;
- case 'N':
- show_main_thread_debug_info(client);
- break;
case 'P':
playback_file = optarg;
break;
@@ -2377,15 +2128,6 @@ int main(int argc, char **argv)
}
}
- if (optind < argc) {
- printf("Warning: un-welcome arguments: ");
- while (optind < argc)
- printf("%s ", argv[optind++]);
- printf("\n");
- rc = 1;
- goto destroy_exit;
- }
-
duration_frames = duration_seconds * rate;
if (block_size == NOT_ASSIGNED)
block_size = get_block_size(PLAYBACK_BUFFERED_TIME_IN_US, rate);
diff --git a/cros_alsa/.gitignore b/cros_alsa/.gitignore
deleted file mode 100644
index b659239f..00000000
--- a/cros_alsa/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-target/
-.*.rustfmt
-Cargo.lock
diff --git a/cros_alsa/.rustfmt.toml b/cros_alsa/.rustfmt.toml
deleted file mode 100644
index a2db3012..00000000
--- a/cros_alsa/.rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-use_field_init_shorthand = true
-use_try_shorthand = true
diff --git a/cros_alsa/Cargo.toml b/cros_alsa/Cargo.toml
deleted file mode 100644
index 2e006e40..00000000
--- a/cros_alsa/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "cros_alsa"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "The Chromium OS alsa-lib wrapper"
-
-[dependencies]
-alsa-sys = "0.2.0"
-cros_alsa_derive = "*"
-libc = "0.2.65"
-remain = "0.2.1"
-
-[patch.crates-io]
-cros_alsa_derive = { path = "cros_alsa_derive" }
diff --git a/cros_alsa/cros_alsa_derive/Cargo.toml b/cros_alsa/cros_alsa_derive/Cargo.toml
deleted file mode 100644
index 6a4da288..00000000
--- a/cros_alsa/cros_alsa_derive/Cargo.toml
+++ /dev/null
@@ -1,14 +0,0 @@
-[package]
-name = "cros_alsa_derive"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "Derive macros of cors_alsa."
-
-[lib]
-proc-macro = true
-
-[dependencies]
-proc-macro2 = "^1"
-quote = "^1"
-syn = "^1"
diff --git a/cros_alsa/cros_alsa_derive/src/common.rs b/cros_alsa/cros_alsa_derive/src/common.rs
deleted file mode 100644
index 2daaa3be..00000000
--- a/cros_alsa/cros_alsa_derive/src/common.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! This mod provides common constants, structs and functions used across cros_alsa_derive.
-use std::convert::TryFrom;
-
-use syn::{Lit, Meta, NestedMeta, Result};
-
-/// Attribute name of cros_alsa.
-const CROS_ALSA: &str = "cros_alsa";
-
-/// const for `#[cros_alsa(path = "...")]`
-const PATH: &str = "path";
-
-/// Possible `#[cros_alsa("...")]` derive macro helper attributes.
-pub enum CrosAlsaAttr {
- /// Use `#[cros_alsa(path = "crate")]` to replace the crate path of cros_alsa in derive macros.
- Path(syn::Path),
-}
-
-impl CrosAlsaAttr {
- /// Return true if the value is a `Path` variant.
- pub fn is_path(&self) -> bool {
- use CrosAlsaAttr::*;
- match self {
- Path(_) => true,
- // suppress unreachable_patterns warning because there is only one CrosAlsaAttr variant.
- #[allow(unreachable_patterns)]
- _ => false,
- }
- }
-}
-
-impl TryFrom<syn::NestedMeta> for CrosAlsaAttr {
- type Error = syn::Error;
- fn try_from(meta_item: NestedMeta) -> Result<CrosAlsaAttr> {
- match meta_item {
- // Parse `#[cros_alsa(path = "crate")]`
- NestedMeta::Meta(Meta::NameValue(m)) if m.path.is_ident(PATH) => {
- if let Lit::Str(lit_str) = &m.lit {
- return Ok(CrosAlsaAttr::Path(lit_str.parse()?));
- }
- Err(syn::Error::new_spanned(
- &m.lit,
- "expected a valid path for cros_alsa_derive::CrosAlsaAttr::Path",
- ))
- }
- _ => Err(syn::Error::new_spanned(
- meta_item,
- "unrecognized cros_alsa_derive::CrosAlsaAttr",
- )),
- }
- }
-}
-
-/// Parses `#[cros_alsa(path = "...")]` into a list of `CrosAlsaAttr`.
-/// It's used to replace the crate path of cros_alsa in derive macros.
-pub fn parse_cros_alsa_attr(attrs: &[syn::Attribute]) -> Result<Vec<CrosAlsaAttr>> {
- attrs
- .iter()
- .flat_map(|attr| get_cros_alsa_meta_items(attr))
- .flatten()
- .map(CrosAlsaAttr::try_from)
- .collect()
-}
-
-/// Parses and collects `NestedMeta` under `cros_alsa` attribute.
-fn get_cros_alsa_meta_items(attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>> {
- if !attr.path.is_ident(CROS_ALSA) {
- return Ok(Vec::new());
- }
- match attr.parse_meta() {
- Ok(Meta::List(meta)) => Ok(meta.nested.into_iter().collect()),
- _ => Err(syn::Error::new_spanned(attr, "expected #[cros_alsa(...)]")),
- }
-}
diff --git a/cros_alsa/cros_alsa_derive/src/control.rs b/cros_alsa/cros_alsa_derive/src/control.rs
deleted file mode 100644
index 584a5418..00000000
--- a/cros_alsa/cros_alsa_derive/src/control.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! This mod provides derive macros for cros_alsa::control.
-
-use proc_macro::TokenStream;
-use proc_macro2::Span;
-use quote::quote;
-
-use crate::common::{parse_cros_alsa_attr, CrosAlsaAttr};
-
-/// The provide default implementation for `ControlOps`.
-/// Users could hold `Ctl` and `ElemID` as `handle` and `id` in their control structure and use
-/// `#[derive(ControlOps)]` macro to generate default load / save implementations.
-pub fn impl_control_ops(ast: &syn::DeriveInput) -> TokenStream {
- let name = &ast.ident;
- let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl();
- let attrs = match parse_cros_alsa_attr(&ast.attrs) {
- Ok(attrs) => attrs,
- Err(e) => return e.to_compile_error().into(),
- };
- let path = match attrs.iter().find(|x| x.is_path()) {
- Some(CrosAlsaAttr::Path(path)) => path.clone(),
- None => syn::LitStr::new("cros_alsa", Span::call_site())
- .parse()
- .expect("failed to create a default path for derive macro: ControlOps"),
- };
- let gen = quote! {
- impl #impl_generics #path::ControlOps #impl_generics for #name #ty_generics #where_clause {
- fn load(&mut self) -> ::std::result::Result<<Self as #path::Control #impl_generics>::Item, #path::ControlError> {
- Ok(<Self as #path::Control>::Item::load(self.handle, &self.id)?)
- }
- fn save(&mut self, val: <Self as #path::Control #impl_generics>::Item) -> ::std::result::Result<bool, #path::ControlError> {
- Ok(<Self as #path::Control>::Item::save(self.handle, &self.id, val)?)
- }
- }
- };
- gen.into()
-}
diff --git a/cros_alsa/cros_alsa_derive/src/lib.rs b/cros_alsa/cros_alsa_derive/src/lib.rs
deleted file mode 100644
index 9970de78..00000000
--- a/cros_alsa/cros_alsa_derive/src/lib.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! `cros_alsa_derive` crate provides derive macros for cros_alsa.
-//!
-
-#![deny(missing_docs)]
-extern crate proc_macro;
-
-use proc_macro::TokenStream;
-
-mod common;
-mod control;
-use self::control::impl_control_ops;
-
-#[proc_macro_derive(ControlOps, attributes(cros_alsa))]
-/// Derive macro generating an impl of the trait ControlOps.
-/// To use this derive macro, users should hold `Ctl` and `ElemID` as `handle`
-/// and `id` in their control structure.
-pub fn control_ops_derive(input: TokenStream) -> TokenStream {
- match syn::parse(input) {
- Ok(ast) => impl_control_ops(&ast),
- Err(e) => e.to_compile_error().into(),
- }
-}
diff --git a/cros_alsa/src/card.rs b/cros_alsa/src/card.rs
deleted file mode 100644
index 42beef2c..00000000
--- a/cros_alsa/src/card.rs
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std::error;
-use std::fmt;
-
-use remain::sorted;
-
-use crate::control::{self, Control};
-use crate::control_primitive;
-use crate::control_primitive::{Ctl, ElemId, ElemIface};
-use crate::control_tlv::{self, ControlTLV};
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-/// Possible errors that can occur in cros-alsa::card.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Error occurs in Control.
- Control(control::Error),
- /// Error occurs in ControlTLV.
- ControlTLV(control_tlv::Error),
-}
-
-impl error::Error for Error {}
-
-impl From<control::Error> for Error {
- fn from(err: control::Error) -> Error {
- Error::Control(err)
- }
-}
-
-impl From<control_tlv::Error> for Error {
- fn from(err: control_tlv::Error) -> Error {
- Error::ControlTLV(err)
- }
-}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- Control(e) => write!(f, "{}", e),
- ControlTLV(e) => write!(f, "{}", e),
- }
- }
-}
-
-/// `Card` represents a sound card.
-#[derive(Debug)]
-pub struct Card {
- handle: Ctl,
- name: String,
-}
-
-impl Card {
- /// Creates a `Card`.
- ///
- /// # Arguments
- ///
- /// * `card_name` - The sound card name, ex: sofcmlmax98390d.
- ///
- /// # Errors
- ///
- /// * If card_name is an invalid CString.
- /// * If snd_ctl_open() fails.
- pub fn new(card_name: &str) -> Result<Self> {
- let handle = Ctl::new(&format!("hw:{}", card_name))?;
- Ok(Card {
- name: card_name.to_owned(),
- handle,
- })
- }
-
- /// Gets sound card name.
- pub fn name(&self) -> &str {
- &self.name
- }
-
- /// Creates a `Control` from control name.
- ///
- /// # Errors
- ///
- /// * If control name is an invalid CString.
- /// * If control does not exist.
- /// * If `Control` elem_type() mismatches the type of underlying mixer control.
- /// * If `Control` size() mismatches the number of value entries of underlying mixer control.
- pub fn control_by_name<'a, T: 'a>(&'a mut self, control_name: &str) -> Result<T>
- where
- T: Control<'a>,
- {
- let id = ElemId::new(ElemIface::Mixer, control_name)?;
- Ok(T::from(&mut self.handle, id)?)
- }
-
- /// Creates a `ControlTLV` from control name.
- ///
- /// # Errors
- ///
- /// * If control name is an invalid CString.
- /// * If control does not exist.
- pub fn control_tlv_by_name<'a>(&'a mut self, control_name: &str) -> Result<ControlTLV<'a>> {
- let id = ElemId::new(ElemIface::Mixer, control_name)?;
- Ok(ControlTLV::new(&mut self.handle, id)?)
- }
-}
diff --git a/cros_alsa/src/control.rs b/cros_alsa/src/control.rs
deleted file mode 100644
index 2bc90256..00000000
--- a/cros_alsa/src/control.rs
+++ /dev/null
@@ -1,297 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! `control` module is meant to provide easier to use and more type safe abstractions
-//! for various alsa mixer controls.
-//!
-//! Each mixer control should implement the `Control` trait to allow itself to be created by `Card`.
-//! Each mixer control could hold `Ctl` as handle and `ElemID` as id and use `#[derive(ControlOps)]` macro
-//! to generate default load / save implementations of the `ControlOps` trait which allows itself to read and
-//! write the underlying hardware.
-//!
-//! # Examples
-//! This is an example of how to define a `SwitchControl`.
-//!
-//! ```
-//! use std::error::Error;
-//!
-//! use cros_alsa::{Ctl, ElemId, Control, ControlError, ControlOps};
-//! use cros_alsa::elem::Elem;
-//!
-//! type Result<T> = std::result::Result<T, ControlError>;
-//!
-//! #[derive(ControlOps)]
-//! pub struct SwitchControl<'a> {
-//! // Must hold `Ctl` as handle and `ElemID` as id to use `#[derive(ControlOps)]`.
-//! handle: &'a mut Ctl,
-//! id: ElemId,
-//! }
-//!
-//! impl<'a> Control<'a> for SwitchControl <'a> {
-//! type Item = [bool; 1];
-//!
-//! fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
-//! Self {
-//! handle,
-//! id,
-//! }
-//! }
-//! }
-//!
-//! impl<'a> SwitchControl<'a> {
-//! /// Reads the state of a switch type mix control.
-//! pub fn state(&mut self) -> Result<bool> {
-//! // Uses ControlOps::load() to read the mixer control.
-//! let v = self.load()?;
-//! Ok(v[0])
-//! }
-//!
-//! /// Updates the control state to true.
-//! pub fn on(&mut self) -> Result<()> {
-//! // Uses ControlOps::save() to write the mixer control.
-//! self.save([true])?;
-//! Ok(())
-//! }
-//! }
-//!
-//! ```
-
-use std::error;
-use std::fmt;
-
-use cros_alsa_derive::ControlOps;
-use remain::sorted;
-
-use crate::control_primitive::{self, Ctl, ElemId, ElemInfo, ElemType};
-use crate::elem::{self, Elem};
-
-/// The Result type of cros-alsa::control.
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-/// Possible errors that can occur in cros-alsa::control.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Error occurs in Elem.
- Elem(elem::Error),
- /// Elem::size() does not match the element count of the mixer control.
- MismatchElemCount(String, usize, usize),
- /// Elem::elem_type() does not match the data type of the mixer control.
- MismatchElemType(String, ElemType, ElemType),
-}
-
-impl error::Error for Error {}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl From<elem::Error> for Error {
- fn from(err: elem::Error) -> Error {
- Error::Elem(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- Elem(e) => write!(f, "{}", e),
- MismatchElemCount(name, count, elem_count) => write!(
- f,
- "invalid `Control::size()` of {}: expect: {}, get: {}",
- name, count, elem_count
- ),
- MismatchElemType(name, t, elem_type) => write!(
- f,
- "invalid `Control::elem_type()` of {}: expect: {}, get: {}",
- name, t, elem_type
- ),
- }
- }
-}
-
-/// Each mixer control should implement the `Control` trait to allow itself to be created by `Card`.
-pub trait Control<'a>: Sized + 'a {
- /// The data type of the mixer control.
- /// Use `ElemType::load()` and `ElemType::save()` to read or write the mixer control.
- type Item: Elem;
-
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to create a `Control`.
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self;
- /// Called by `Card` to create a `Control`.
- fn from(handle: &'a mut Ctl, id: ElemId) -> Result<Self> {
- let info = ElemInfo::new(handle, &id)?;
- if info.elem_type()? != Self::elem_type() {
- return Err(Error::MismatchElemType(
- id.name()?.to_owned(),
- info.elem_type()?,
- Self::elem_type(),
- ));
- }
-
- if info.count() != Self::size() {
- return Err(Error::MismatchElemCount(
- id.name()?.to_owned(),
- info.count(),
- Self::size(),
- ));
- }
-
- Ok(Self::new(handle, id))
- }
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to validate the data type of a
- /// `Control`.
- fn elem_type() -> ElemType {
- Self::Item::elem_type()
- }
- /// Called by `Self::from(handle: &'a mut Ctl, id: ElemId)` to validate the number of value
- /// entries of a `Control`.
- fn size() -> usize {
- Self::Item::size()
- }
-}
-
-/// Each mixer control could implement the `ControlOps` trait to allow itself to read and
-/// write the underlying hardware`. Users could hold `Ctl` and `ElemID` as `handle` and `id`
-/// in their control structure and use `#[derive(ControlOps)]` macro to generate default
-/// load / save implementations.
-pub trait ControlOps<'a>: Control<'a> {
- /// Reads the values of the mixer control.
- fn load(&mut self) -> Result<<Self as Control<'a>>::Item>;
- /// Saves the values to the mixer control.
- fn save(&mut self, val: <Self as Control<'a>>::Item) -> Result<bool>;
-}
-
-/// `Control` that reads and writes a single integer value entry.
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct IntControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> IntControl<'a> {
- /// Gets an i32 value from the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn get(&mut self) -> Result<i32> {
- let val = self.load()?;
- Ok(val[0])
- }
-
- /// Updates an i32 value to the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn set(&mut self, val: i32) -> Result<()> {
- self.save([val])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for IntControl<'a> {
- type Item = [i32; 1];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}
-
-/// Stereo Volume Mixer Control
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct StereoVolumeControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> StereoVolumeControl<'a> {
- /// Reads the left and right volume.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn volume(&mut self) -> Result<(i32, i32)> {
- let val = self.load()?;
- Ok((val[0], val[1]))
- }
-
- /// Updates the left and right volume.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn set_volume(&mut self, left: i32, right: i32) -> Result<()> {
- self.save([left, right])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for StereoVolumeControl<'a> {
- type Item = [i32; 2];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}
-
-/// `Control` that reads and writes a single boolean value entry.
-/// Since this crate is the `cros_alsa` crate, we replace the `cros_alsa`
-/// path to `crate` in derive macros by `cros_alsa` attribute.
-#[derive(ControlOps)]
-#[cros_alsa(path = "crate")]
-pub struct SwitchControl<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> SwitchControl<'a> {
- /// Reads the state of a switch type mix control.
- ///
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn state(&mut self) -> Result<bool> {
- let v = self.load()?;
- Ok(v[0])
- }
-
- /// Updates the control state to true.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn on(&mut self) -> Result<()> {
- self.save([true])?;
- Ok(())
- }
-
- /// Updates the control state to false.
- ///
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn off(&mut self) -> Result<()> {
- self.save([false])?;
- Ok(())
- }
-}
-
-impl<'a> Control<'a> for SwitchControl<'a> {
- type Item = [bool; 1];
- fn new(handle: &'a mut Ctl, id: ElemId) -> Self {
- Self { handle, id }
- }
-}
diff --git a/cros_alsa/src/control_primitive.rs b/cros_alsa/src/control_primitive.rs
deleted file mode 100644
index 227aef27..00000000
--- a/cros_alsa/src/control_primitive.rs
+++ /dev/null
@@ -1,406 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-use std::convert::TryFrom;
-use std::error;
-use std::ffi::{CStr, CString, FromBytesWithNulError, NulError};
-use std::fmt;
-use std::marker::PhantomData;
-use std::ptr;
-use std::slice;
-use std::str;
-
-use alsa_sys::*;
-use libc::strlen;
-use remain::sorted;
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[derive(Debug, PartialEq)]
-/// Possible errors that can occur in FFI functions.
-pub enum FFIError {
- Rc(i32),
- NullPtr,
-}
-
-impl fmt::Display for FFIError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use FFIError::*;
- match self {
- Rc(rc) => write!(f, "{}", snd_strerror(*rc)?),
- NullPtr => write!(f, "the return value is a null pointer"),
- }
- }
-}
-
-#[sorted]
-#[derive(Debug, PartialEq)]
-/// Possible errors that can occur in cros-alsa::control_primitive.
-pub enum Error {
- /// Control with the given name does not exist.
- ControlNotFound(String),
- /// Failed to call snd_ctl_open().
- CtlOpenFailed(FFIError, String),
- /// snd_ctl_elem_id_get_name() returns null.
- ElemIdGetNameFailed,
- /// Failed to call snd_ctl_elem_id_malloc().
- ElemIdMallocFailed(FFIError),
- /// Failed to call snd_ctl_elem_info_malloc().
- ElemInfoMallocFailed(FFIError),
- /// Failed to call snd_ctl_elem_value_malloc().
- ElemValueMallocFailed(FFIError),
- /// The slice used to create a CStr does not have one and only one null
- /// byte positioned at the end.
- FromBytesWithNulError(FromBytesWithNulError),
- /// Failed to convert to a valid ElemType.
- InvalidElemType(u32),
- /// An error indicating that an interior nul byte was found.
- NulError(NulError),
- /// Failed to call snd_strerror().
- SndStrErrorFailed(i32),
- /// UTF-8 validation failed
- Utf8Error(str::Utf8Error),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- ControlNotFound(name) => write!(f, "control: {} does not exist", name),
- CtlOpenFailed(e, name) => write!(f, "{} snd_ctl_open failed: {}", name, e,),
- ElemIdGetNameFailed => write!(f, "snd_ctl_elem_id_get_name failed"),
- ElemIdMallocFailed(e) => write!(f, "snd_ctl_elem_id_malloc failed: {}", e),
- ElemInfoMallocFailed(e) => write!(f, "snd_ctl_elem_info_malloc failed: {}", e),
- ElemValueMallocFailed(e) => write!(f, "snd_ctl_elem_value_malloc failed: {}", e),
- FromBytesWithNulError(e) => write!(f, "invalid CString: {}", e),
- InvalidElemType(v) => write!(f, "invalid ElemType: {}", v),
- NulError(e) => write!(f, "invalid CString: {}", e),
- SndStrErrorFailed(e) => write!(f, "snd_strerror() failed: {}", e),
- Utf8Error(e) => write!(f, "{}", e),
- }
- }
-}
-
-impl From<Error> for fmt::Error {
- fn from(_err: Error) -> fmt::Error {
- fmt::Error
- }
-}
-
-impl From<str::Utf8Error> for Error {
- fn from(err: str::Utf8Error) -> Error {
- Error::Utf8Error(err)
- }
-}
-
-impl From<FromBytesWithNulError> for Error {
- fn from(err: FromBytesWithNulError) -> Error {
- Error::FromBytesWithNulError(err)
- }
-}
-
-impl From<NulError> for Error {
- fn from(err: NulError) -> Error {
- Error::NulError(err)
- }
-}
-
-/// [snd_ctl_elem_iface_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga14baa0febb91cc4c5d72dcc825acf518) wrapper.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub enum ElemIface {
- Card = SND_CTL_ELEM_IFACE_CARD as isize,
- Hwdep = SND_CTL_ELEM_IFACE_HWDEP as isize,
- Mixer = SND_CTL_ELEM_IFACE_MIXER as isize,
- PCM = SND_CTL_ELEM_IFACE_PCM as isize,
- Rawmidi = SND_CTL_ELEM_IFACE_RAWMIDI as isize,
- Timer = SND_CTL_ELEM_IFACE_TIMER as isize,
- Sequencer = SND_CTL_ELEM_IFACE_SEQUENCER as isize,
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-/// [snd_ctl_elem_type_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gac42e0ed6713b62711af5e80b4b3bcfec) wrapper.
-pub enum ElemType {
- None = SND_CTL_ELEM_TYPE_NONE as isize,
- Boolean = SND_CTL_ELEM_TYPE_BOOLEAN as isize,
- Integer = SND_CTL_ELEM_TYPE_INTEGER as isize,
- Enumerated = SND_CTL_ELEM_TYPE_ENUMERATED as isize,
- Bytes = SND_CTL_ELEM_TYPE_BYTES as isize,
- IEC958 = SND_CTL_ELEM_TYPE_IEC958 as isize,
- Integer64 = SND_CTL_ELEM_TYPE_INTEGER64 as isize,
-}
-
-impl fmt::Display for ElemType {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ElemType::None => write!(f, "SND_CTL_ELEM_TYPE_NONE"),
- ElemType::Boolean => write!(f, "SND_CTL_ELEM_TYPE_BOOLEAN"),
- ElemType::Integer => write!(f, "SND_CTL_ELEM_TYPE_INTEGER"),
- ElemType::Enumerated => write!(f, "SND_CTL_ELEM_TYPE_ENUMERATED"),
- ElemType::Bytes => write!(f, "SND_CTL_ELEM_TYPE_BYTES"),
- ElemType::IEC958 => write!(f, "SND_CTL_ELEM_TYPE_IEC958"),
- ElemType::Integer64 => write!(f, "SND_CTL_ELEM_TYPE_INTEGER64"),
- }
- }
-}
-
-impl TryFrom<u32> for ElemType {
- type Error = Error;
- fn try_from(elem_type: u32) -> Result<ElemType> {
- match elem_type {
- SND_CTL_ELEM_TYPE_NONE => Ok(ElemType::None),
- SND_CTL_ELEM_TYPE_BOOLEAN => Ok(ElemType::Boolean),
- SND_CTL_ELEM_TYPE_INTEGER => Ok(ElemType::Integer),
- SND_CTL_ELEM_TYPE_ENUMERATED => Ok(ElemType::Enumerated),
- SND_CTL_ELEM_TYPE_BYTES => Ok(ElemType::Bytes),
- SND_CTL_ELEM_TYPE_IEC958 => Ok(ElemType::IEC958),
- SND_CTL_ELEM_TYPE_INTEGER64 => Ok(ElemType::Integer64),
- _ => Err(Error::InvalidElemType(elem_type)),
- }
- }
-}
-
-/// [snd_ctl_elem_id_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gad6c3746f1925bfec6a4fd0e913430e55) wrapper.
-pub struct ElemId(
- ptr::NonNull<snd_ctl_elem_id_t>,
- PhantomData<snd_ctl_elem_id_t>,
-);
-
-impl Drop for ElemId {
- fn drop(&mut self) {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_id_t*.
- unsafe { snd_ctl_elem_id_free(self.0.as_ptr()) };
- }
-}
-
-impl ElemId {
- /// Creates an `ElemId` object by `ElemIface` and name.
- ///
- /// # Errors
- ///
- /// * If memory allocation fails.
- /// * If ctl_name is not a valid CString.
- pub fn new(iface: ElemIface, ctl_name: &str) -> Result<ElemId> {
- let mut id_ptr = ptr::null_mut();
- // Safe because we provide a valid id_ptr to be filled,
- // and we validate the return code before using id_ptr.
- let rc = unsafe { snd_ctl_elem_id_malloc(&mut id_ptr) };
- if rc < 0 {
- return Err(Error::ElemIdMallocFailed(FFIError::Rc(rc)));
- }
- let id = ptr::NonNull::new(id_ptr).ok_or(Error::ElemIdMallocFailed(FFIError::NullPtr))?;
-
- // Safe because id.as_ptr() is a valid snd_ctl_elem_id_t*.
- unsafe { snd_ctl_elem_id_set_interface(id.as_ptr(), iface as u32) };
- let name = CString::new(ctl_name)?;
- // Safe because id.as_ptr() is a valid snd_ctl_elem_id_t* and name is a safe CString.
- unsafe { snd_ctl_elem_id_set_name(id.as_ptr(), name.as_ptr()) };
- Ok(ElemId(id, PhantomData))
- }
-
- /// Borrows the const inner pointer.
- pub fn as_ptr(&self) -> *const snd_ctl_elem_id_t {
- self.0.as_ptr()
- }
-
- /// Safe [snd_ctl_elem_id_get_name()] (https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gaa6cfea3ac963bfdaeb8189e03e927a76) wrapper.
- ///
- /// # Errors
- ///
- /// * If snd_ctl_elem_id_get_name() fails.
- /// * If control element name is not a valid CString.
- /// * If control element name is not valid UTF-8 data.
- pub fn name(&self) -> Result<&str> {
- // Safe because self.as_ptr() is a valid snd_ctl_elem_id_t*.
- let name = unsafe { snd_ctl_elem_id_get_name(self.as_ptr()) };
- if name.is_null() {
- return Err(Error::ElemIdGetNameFailed);
- }
- // Safe because name is a valid *const i8, and its life time
- // is the same as the passed reference of self.
- let s = CStr::from_bytes_with_nul(unsafe {
- slice::from_raw_parts(name as *const u8, strlen(name) + 1)
- })?;
- Ok(s.to_str()?)
- }
-}
-
-/// [snd_ctl_elem_value_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga266b478eb64f1cdd75e337df4b4b995e) wrapper.
-pub struct ElemValue(
- ptr::NonNull<snd_ctl_elem_value_t>,
- PhantomData<snd_ctl_elem_value_t>,
-);
-
-impl Drop for ElemValue {
- // Safe because self.0.as_ptr() is valid.
- fn drop(&mut self) {
- unsafe { snd_ctl_elem_value_free(self.0.as_ptr()) };
- }
-}
-
-impl ElemValue {
- /// Creates an `ElemValue`.
- ///
- /// # Errors
- ///
- /// * If memory allocation fails.
- pub fn new(id: &ElemId) -> Result<ElemValue> {
- let mut v_ptr = ptr::null_mut();
- // Safe because we provide a valid v_ptr to be filled,
- // and we validate the return code before using v_ptr.
- let rc = unsafe { snd_ctl_elem_value_malloc(&mut v_ptr) };
- if rc < 0 {
- return Err(Error::ElemValueMallocFailed(FFIError::Rc(rc)));
- }
- let value =
- ptr::NonNull::new(v_ptr).ok_or(Error::ElemValueMallocFailed(FFIError::NullPtr))?;
- // Safe because value.as_ptr() is a valid snd_ctl_elem_value_t* and id.as_ptr() is also valid.
- unsafe { snd_ctl_elem_value_set_id(value.as_ptr(), id.as_ptr()) };
- Ok(ElemValue(value, PhantomData))
- }
-
- /// Borrows the mutable inner pointer.
- pub fn as_mut_ptr(&mut self) -> *mut snd_ctl_elem_value_t {
- self.0.as_ptr()
- }
-
- /// Borrows the const inner pointer.
- pub fn as_ptr(&self) -> *const snd_ctl_elem_value_t {
- self.0.as_ptr()
- }
-}
-
-/// [snd_ctl_elem_info_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga2cae0bb76df919368e4ff9a7021dd3ab) wrapper.
-pub struct ElemInfo(
- ptr::NonNull<snd_ctl_elem_info_t>,
- PhantomData<snd_ctl_elem_info_t>,
-);
-
-impl Drop for ElemInfo {
- fn drop(&mut self) {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_info_t*.
- unsafe { snd_ctl_elem_info_free(self.0.as_ptr()) };
- }
-}
-
-impl ElemInfo {
- /// Creates an `ElemInfo`.
- ///
- /// # Errors
- ///
- /// * If memory allocation fails.
- /// * If control does not exist.
- pub fn new(handle: &mut Ctl, id: &ElemId) -> Result<ElemInfo> {
- let mut info_ptr = ptr::null_mut();
-
- // Safe because we provide a valid info_ptr to be filled,
- // and we validate the return code before using info_ptr.
- let rc = unsafe { snd_ctl_elem_info_malloc(&mut info_ptr) };
- if rc < 0 {
- return Err(Error::ElemInfoMallocFailed(FFIError::Rc(rc)));
- }
- let info =
- ptr::NonNull::new(info_ptr).ok_or(Error::ElemInfoMallocFailed(FFIError::NullPtr))?;
-
- // Safe because info.as_ptr() is a valid snd_ctl_elem_info_t* and id.as_ptr() is also valid.
- unsafe { snd_ctl_elem_info_set_id(info.as_ptr(), id.as_ptr()) };
-
- // Safe because handle.as_mut_ptr() is a valid snd_ctl_t* and info.as_ptr() is a valid
- // snd_ctl_elem_info_t*.
- let rc = unsafe { snd_ctl_elem_info(handle.as_mut_ptr(), info.as_ptr()) };
- if rc < 0 {
- return Err(Error::ControlNotFound(id.name()?.to_owned()));
- }
- Ok(ElemInfo(info, PhantomData))
- }
-
- /// Safe [snd_ctl_elem_info_get_type](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga0fec5d22ee58d04f14b59f405adc595e) wrapper.
- pub fn elem_type(&self) -> Result<ElemType> {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_info_t*.
- unsafe { ElemType::try_from(snd_ctl_elem_info_get_type(self.0.as_ptr())) }
- }
-
- /// Safe [snd_ctl_elem_info_get_count](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gaa75a20d4190d324bcda5fd6659a4b377) wrapper.
- pub fn count(&self) -> usize {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_info_t*.
- unsafe { snd_ctl_elem_info_get_count(self.0.as_ptr()) as usize }
- }
-
- /// Safe [snd_ctl_elem_info_is_tlv_readable](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gaac6bb412e5a9fffb5509e98a10de45b5) wrapper.
- pub fn tlv_readable(&self) -> bool {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_info_t*.
- unsafe { snd_ctl_elem_info_is_tlv_readable(self.0.as_ptr()) as usize == 1 }
- }
-
- /// Safe [snd_ctl_elem_info_is_tlv_writable](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#gacfbaae80d710b6feac682f8ba10a0341) wrapper.
- pub fn tlv_writable(&self) -> bool {
- // Safe because self.0.as_ptr() is a valid snd_ctl_elem_info_t*.
- unsafe { snd_ctl_elem_info_is_tlv_writable(self.0.as_ptr()) as usize == 1 }
- }
-}
-
-/// [snd_ctl_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga06628f38def84a0fe3da74041db9d51f) wrapper.
-#[derive(Debug)]
-pub struct Ctl(ptr::NonNull<snd_ctl_t>, PhantomData<snd_ctl_t>);
-
-impl Drop for Ctl {
- fn drop(&mut self) {
- // Safe as we provide a valid snd_ctl_t*.
- unsafe { snd_ctl_close(self.0.as_ptr()) };
- }
-}
-
-impl Ctl {
- /// Creates a `Ctl`.
- /// Safe [snd_ctl_open](https://www.alsa-project.org/alsa-doc/alsa-lib/group___control.html#ga58537f5b74c9c1f51699f9908a0d7f56).
- /// Does not support async mode.
- ///
- /// # Errors
- ///
- /// * If `card` is an invalid CString.
- /// * If `snd_ctl_open()` fails.
- pub fn new(card: &str) -> Result<Ctl> {
- let name = CString::new(card)?;
- let mut ctl_ptr = ptr::null_mut();
- // Safe because we provide a valid ctl_ptr to be filled, name is a safe CString
- // and we validate the return code before using ctl_ptr.
- let rc = unsafe { snd_ctl_open(&mut ctl_ptr, name.as_ptr(), 0) };
- if rc < 0 {
- return Err(Error::CtlOpenFailed(
- FFIError::Rc(rc),
- name.to_str()?.to_owned(),
- ));
- }
- let ctl = ptr::NonNull::new(ctl_ptr).ok_or(Error::CtlOpenFailed(
- FFIError::NullPtr,
- name.to_str()?.to_owned(),
- ))?;
- Ok(Ctl(ctl, PhantomData))
- }
-
- /// Borrows the mutable inner pointer
- pub fn as_mut_ptr(&mut self) -> *mut snd_ctl_t {
- self.0.as_ptr()
- }
-}
-
-/// Safe [snd_strerror](https://www.alsa-project.org/alsa-doc/alsa-lib/group___error.html#ga182bbadf2349e11602bc531e8cf22f7e) wrapper.
-///
-/// # Errors
-///
-/// * If `snd_strerror` returns invalid UTF-8 data.
-pub fn snd_strerror(err_num: i32) -> Result<&'static str> {
- // Safe because we validate the return pointer of snd_strerror()
- // before using it.
- let s_ptr = unsafe { alsa_sys::snd_strerror(err_num) };
- if s_ptr.is_null() {
- return Err(Error::SndStrErrorFailed(err_num));
- }
- // Safe because s_ptr is a non-null *const u8 and its lifetime is static.
- let s = CStr::from_bytes_with_nul(unsafe {
- slice::from_raw_parts(s_ptr as *const u8, strlen(s_ptr) + 1)
- })?;
- Ok(s.to_str()?)
-}
diff --git a/cros_alsa/src/control_tlv.rs b/cros_alsa/src/control_tlv.rs
deleted file mode 100644
index e1f35510..00000000
--- a/cros_alsa/src/control_tlv.rs
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! `ControlTLV` supports read and write of the alsa TLV byte controls
-//! Users can obtain a ControlTLV by Card::control_tlv_by_name().
-//! # Examples
-//! This is an example of how to use a `TLV`.
-//!
-//! ```
-//! use std::assert_eq;
-//! use std::convert::TryFrom;
-//! use std::error::Error;
-//!
-//! use cros_alsa::{TLV, ControlTLVError};
-//! use cros_alsa::elem::Elem;
-//!
-//! type Result<T> = std::result::Result<T, ControlTLVError>;
-//!
-//! let mut tlv = TLV::new(0, vec![1,2,3,4]);
-//! assert_eq!(4, tlv.len());
-//! assert_eq!(0, tlv.tlv_type());
-//! assert_eq!(2, tlv[1]);
-//! tlv[1] = 8;
-//! assert_eq!(vec![1,8,3,4], tlv.value().to_vec());
-//! assert_eq!(vec![0,16,1,8,3,4], Into::<Vec<u32>>::into(tlv));
-//!
-//! ```
-
-use std::{
- convert::TryFrom,
- fmt,
- ops::{Index, IndexMut},
- slice::SliceIndex,
-};
-use std::{error, mem::size_of};
-
-use remain::sorted;
-
-use crate::control_primitive::{self, Ctl, ElemId, ElemInfo, ElemType};
-
-/// The Result type of cros-alsa::control.
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug, PartialEq)]
-/// Possible errors that can occur in cros-alsa::control.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Failed to convert buffer to TLV struct.
- InvalidTLV,
- /// ElemInfo::count() is not multiple of size_of::<u32>.
- InvalidTLVSize(String, usize),
- /// ElemInfo::elem_type() is not ElemType::Bytes.
- InvalidTLVType(String, ElemType),
- /// The control is not readable.
- TLVNotReadable,
- /// The control is not writeable.
- TLVNotWritable,
- /// Failed to call snd_ctl_elem_tlv_read.
- TLVReadFailed(i32),
- /// Failed to call snd_ctl_elem_tlv_write.
- TVLWriteFailed(i32),
-}
-
-impl error::Error for Error {}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- InvalidTLV => write!(f, "failed to convert to TLV"),
- InvalidTLVSize(name, elem_size) => write!(
- f,
- "ElemInfo::size() of {} should be multiple of size_of::<u32>, get: {}",
- name, elem_size
- ),
- InvalidTLVType(name, elem_type) => write!(
- f,
- "invalid ElemInfo::elem_type() of {}: expect: {}, get: {}",
- name,
- ElemType::Bytes,
- elem_type
- ),
- TLVNotReadable => write!(f, "the control is not readable."),
- TLVNotWritable => write!(f, "the control is not writable."),
- TLVReadFailed(rc) => write!(f, "snd_ctl_elem_tlv_read failed: {}", rc),
- TVLWriteFailed(rc) => write!(f, "snd_ctl_elem_tlv_write failed: {}", rc),
- }
- }
-}
-
-/// TLV struct represents the TLV data to be read from
-/// or write to an alsa TLV byte control.
-#[derive(Debug)]
-pub struct TLV {
- /// data[Self::TYPE_OFFSET] contains the tlv type.
- /// data[Self::LEN_OFFSET] contains the length of the value in bytes.
- /// data[Self::VALUE_OFFSET..] contains the data.
- data: Vec<u32>,
-}
-
-impl TLV {
- const TYPE_OFFSET: usize = 0;
- const LEN_OFFSET: usize = 1;
- const VALUE_OFFSET: usize = 2;
- const TLV_HEADER_SIZE_BYTES: usize = Self::VALUE_OFFSET * size_of::<u32>();
-
- /// Initializes a `TLV` by giving the tlv type and tlv value.
- pub fn new(tlv_type: u32, tlv_value: Vec<u32>) -> Self {
- let mut data = vec![0; 2];
- data[Self::TYPE_OFFSET] = tlv_type;
- data[Self::LEN_OFFSET] = (tlv_value.len() * size_of::<u32>()) as u32;
- data.extend(tlv_value.iter());
- Self { data }
- }
-
- /// Returns the type of the tlv.
- pub fn tlv_type(&self) -> u32 {
- self.data[Self::TYPE_OFFSET]
- }
-
- /// Returns the length of the tlv value in dword.
- pub fn len(&self) -> usize {
- self.data[Self::LEN_OFFSET] as usize / size_of::<u32>()
- }
-
- /// Returns whether the tlv value is empty.
- pub fn is_empty(&self) -> bool {
- self.data[Self::LEN_OFFSET] == 0
- }
-
- /// Returns the tlv value in slice.
- pub fn value(&self) -> &[u32] {
- &self.data[Self::VALUE_OFFSET..]
- }
-}
-
-impl<I: SliceIndex<[u32]>> Index<I> for TLV {
- type Output = I::Output;
- #[inline]
- fn index(&self, index: I) -> &Self::Output {
- &self.data[Self::VALUE_OFFSET..][index]
- }
-}
-
-impl<I: SliceIndex<[u32]>> IndexMut<I> for TLV {
- #[inline]
- fn index_mut(&mut self, index: I) -> &mut Self::Output {
- &mut self.data[Self::VALUE_OFFSET..][index]
- }
-}
-
-impl TryFrom<Vec<u32>> for TLV {
- type Error = Error;
-
- /// Constructs a TLV from a vector with the following alsa tlv header validation:
- /// 1 . tlv_buf[Self::LEN_OFFSET] should be multiple of size_of::<u32>
- /// 2 . tlv_buf[Self::LEN_OFFSET] is the length of tlv value in byte and
- /// should be less than the buffer length * size_of::<u32>.
- fn try_from(data: Vec<u32>) -> Result<Self> {
- if data.len() < 2 {
- return Err(Error::InvalidTLV);
- }
-
- if data[Self::LEN_OFFSET] % size_of::<u32>() as u32 != 0 {
- return Err(Error::InvalidTLV);
- }
-
- if data[Self::LEN_OFFSET] / size_of::<u32>() as u32
- > data[Self::VALUE_OFFSET..].len() as u32
- {
- return Err(Error::InvalidTLV);
- }
-
- Ok(Self { data })
- }
-}
-
-impl Into<Vec<u32>> for TLV {
- /// Returns the raw tlv data buffer (including the tlv header).
- fn into(self) -> Vec<u32> {
- self.data
- }
-}
-
-/// `ControlTLV` supports read and write of the alsa TLV byte controls.
-pub struct ControlTLV<'a> {
- handle: &'a mut Ctl,
- id: ElemId,
-}
-
-impl<'a> ControlTLV<'a> {
- /// Called by `Card` to create a `ControlTLV`.
- pub fn new(handle: &'a mut Ctl, id: ElemId) -> Result<Self> {
- let info = ElemInfo::new(handle, &id)?;
- if info.count() % size_of::<u32>() != 0 {
- return Err(Error::InvalidTLVSize(id.name()?.to_owned(), info.count()));
- }
- match info.elem_type()? {
- ElemType::Bytes => Ok(Self { handle, id }),
- _ => Err(Error::InvalidTLVType(
- id.name()?.to_owned(),
- info.elem_type()?,
- )),
- }
- }
-
- /// Reads data from the byte control by `snd_ctl_elem_tlv_read`
- ///
- /// #
- /// # Errors
- ///
- /// * If it fails to read from the control.
- pub fn load(&mut self) -> Result<TLV> {
- if !ElemInfo::new(self.handle, &self.id)?.tlv_readable() {
- return Err(Error::TLVNotReadable);
- }
-
- let tlv_size = ElemInfo::new(self.handle, &self.id)?.count() + TLV::TLV_HEADER_SIZE_BYTES;
-
- let mut tlv_buf = vec![0; tlv_size / size_of::<u32>()];
- // Safe because handle.as_mut_ptr() is a valid *mut snd_ctl_t, id_as_ptr is valid and
- // tlv_buf.as_mut_ptr() is also valid.
- let rc = unsafe {
- alsa_sys::snd_ctl_elem_tlv_read(
- self.handle.as_mut_ptr(),
- self.id.as_ptr(),
- tlv_buf.as_mut_ptr(),
- tlv_size as u32,
- )
- };
- if rc < 0 {
- return Err(Error::TLVReadFailed(rc));
- }
- Ok(TLV::try_from(tlv_buf)?)
- }
-
- /// Writes to the byte control by `snd_ctl_elem_tlv_write`
- ///
- /// # Results
- ///
- /// * `changed` - false on success.
- /// - true on success when value was changed.
- /// #
- /// # Errors
- ///
- /// * If it fails to write to the control.
- pub fn save(&mut self, tlv: TLV) -> Result<bool> {
- if !ElemInfo::new(self.handle, &self.id)?.tlv_writable() {
- return Err(Error::TLVNotReadable);
- }
- // Safe because handle.as_mut_ptr() is a valid *mut snd_ctl_t, id_as_ptr is valid and
- // tlv.as_mut_ptr() is also valid.
- let rc = unsafe {
- alsa_sys::snd_ctl_elem_tlv_write(
- self.handle.as_mut_ptr(),
- self.id.as_ptr(),
- Into::<Vec<u32>>::into(tlv).as_mut_ptr(),
- )
- };
- if rc < 0 {
- return Err(Error::TVLWriteFailed(rc));
- }
- Ok(rc > 0)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn test_tlv_try_from_raw_vec() {
- let tlv_buf = vec![0, 12, 2, 3, 4];
- assert!(TLV::try_from(tlv_buf).is_ok());
- }
-
- #[test]
- fn test_tlv_length_is_not_multiple_of_sizeof_int() {
- // Invalid tlv length in data[Self::LEN_OFFSET].
- let tlv_buf = vec![0, 1, 2, 3, 4];
- assert_eq!(TLV::try_from(tlv_buf).unwrap_err(), Error::InvalidTLV);
- }
-
- #[test]
- fn test_tlv_length_larger_than_buff_size() {
- // Invalid tlv length in data[Self::LEN_OFFSET].
- let tlv_buf = vec![0, 16, 2, 3, 4];
- assert_eq!(TLV::try_from(tlv_buf).unwrap_err(), Error::InvalidTLV);
- }
-
- #[test]
- fn test_tlv_length_less_than_two() {
- // tlv buffer length < 2
- let tlv_buf = vec![0];
- assert_eq!(TLV::try_from(tlv_buf).unwrap_err(), Error::InvalidTLV);
- }
-
- #[test]
- fn test_tlv_length_equal_two() {
- // tlv buffer size = 2.
- let tlv_buf = vec![0, 0];
- assert!(TLV::try_from(tlv_buf).is_ok());
- }
-}
diff --git a/cros_alsa/src/elem.rs b/cros_alsa/src/elem.rs
deleted file mode 100644
index 08fe8b62..00000000
--- a/cros_alsa/src/elem.rs
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! This module provides different implementations of `Elem` that use the alsa-lib control interface
-//! API to read and write alsa control elements.
-//!
-//! The `Elem::type()` returns the type of value that a control element can interact with,
-//! and it is one of integer, integer64, boolean, enumerators, bytes or IEC958 structure.
-//! The `Elem::size()` returns the number of values it reads from or writes to the hardware
-//! at a time.
-//! The `Elem::load(..)` and `Elem::save(..)` are used by `ControlOps` trait to read and write
-//! the underlying mixer control.
-//!
-//! Users should use the provided implementations of `Elem` to define the associated type in
-//! their owner encapsulation of `Control`.
-
-use std::default::Default;
-use std::error;
-use std::fmt;
-
-use libc::{c_long, c_uint};
-use remain::sorted;
-
-use crate::control_primitive::{self, snd_strerror, Ctl, ElemId, ElemType, ElemValue};
-
-/// The Result type of cros-alsa::elem.
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-/// Possible errors that can occur in cros-alsa::elem.
-pub enum Error {
- /// Failed to call AlsaControlAPI.
- AlsaControlAPI(control_primitive::Error),
- /// Failed to call `snd_ctl_elem_read()`.
- ElemReadFailed(i32),
- /// Failed to call `snd_ctl_elem_write()`.
- ElemWriteFailed(i32),
-}
-
-impl error::Error for Error {}
-
-impl From<control_primitive::Error> for Error {
- fn from(err: control_primitive::Error) -> Error {
- Error::AlsaControlAPI(err)
- }
-}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaControlAPI(e) => write!(f, "{}", e),
- ElemReadFailed(e) => write!(f, "snd_ctl_elem_read failed: {}", snd_strerror(*e)?),
- ElemWriteFailed(e) => write!(f, "snd_ctl_elem_write failed: {}", snd_strerror(*e)?),
- }
- }
-}
-
-// Uses a recursive macro to generate implementation for [bool; n] and [i32; n], n = 1 to 128.
-// The `$t:ident $($ts:ident)*` part matches and removes one token at a time. It's used for
-// counting recursive steps.
-macro_rules! impl_for_array {
- {$n:expr, $type:ty, $t:ident $($ts:ident)*} => {
- impl Elem for [$type; $n] {
- type T = Self;
- /// Reads [$type; $n] data from the mixer control.
- ///
- /// # Errors
- ///
- /// * If it fails to call `snd_ctl_elem_read()`.
- fn load(handle: &mut Ctl, id: &ElemId) -> Result<Self::T>
- {
- let mut elem = ElemValue::new(id)?;
- // Safe because self.handle.as_mut_ptr() is a valid *mut snd_ctl_t and
- // elem.as_mut_ptr() is also a valid *mut snd_ctl_elem_value_t.
- let rc = unsafe { alsa_sys::snd_ctl_elem_read(handle.as_mut_ptr(), elem.as_mut_ptr()) };
- if rc < 0 {
- return Err(Error::ElemReadFailed(rc));
- }
- let mut ret = [Default::default(); $n];
- for i in 0..$n {
- // Safe because elem.as_ptr() is a valid snd_ctl_elem_value_t* and i is guaranteed to be
- // within a valid range.
- ret[i] = unsafe { <$type>::elem_value_get(&elem, i) };
- }
- Ok(ret)
- }
-
- /// Updates [$type; $n] data to the mixer control.
- ///
- /// # Results
- ///
- /// * `changed` - false on success.
- /// - true on success when value was changed.
- ///
- /// # Errors
- ///
- /// * If it fails to call `snd_ctl_elem_write()`.
- fn save(handle: &mut Ctl, id: &ElemId, val: Self::T) -> Result<bool> {
- let mut elem = ElemValue::new(id)?;
- for i in 0..$n {
- // Safe because elem.as_mut_ptr() is a valid snd_ctl_elem_value_t* and i is guaranteed to be
- // within a valid range.
- unsafe { <$type>::elem_value_set(&mut elem, i, val[i]) };
- }
- // Safe because self.handle.as_mut_ptr() is a valid *mut snd_ctl_t and
- // elem.as_mut_ptr() is also a valid *mut snd_ctl_elem_value_t.
- let rc = unsafe { alsa_sys::snd_ctl_elem_write(handle.as_mut_ptr(), elem.as_mut_ptr()) };
- if rc < 0 {
- return Err(Error::ElemWriteFailed(rc));
- }
- Ok(rc > 0)
- }
-
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType {
- <$type>::elem_type()
- }
-
- /// Gets the number of value entries itself can read and write.
- fn size() -> usize {
- $n
- }
- }
- impl_for_array!{($n - 1), $type, $($ts)*}
- };
- {$n:expr, $type:ty,} => {};
-}
-
-// Implements `Elem` for [i32; n] where n = 1 to 128.
-impl_for_array! {128, i32,
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-}
-
-// Implements `Elem` for [bool; n] where n = 1 to 128.
-impl_for_array! {128, bool,
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T T
-}
-
-impl CtlElemValue for bool {
- type T = bool;
- /// Gets a bool from the ElemValue.
- unsafe fn elem_value_get(elem: &ElemValue, idx: usize) -> bool {
- alsa_sys::snd_ctl_elem_value_get_boolean(elem.as_ptr(), idx as c_uint) != 0
- }
- /// Sets a bool to the ElemValue.
- unsafe fn elem_value_set(elem: &mut ElemValue, idx: usize, val: bool) {
- alsa_sys::snd_ctl_elem_value_set_boolean(elem.as_mut_ptr(), idx as c_uint, val as c_long);
- }
- /// Returns ElemType::Boolean.
- fn elem_type() -> ElemType {
- ElemType::Boolean
- }
-}
-
-impl CtlElemValue for i32 {
- type T = i32;
- /// Gets an i32 from the ElemValue.
- unsafe fn elem_value_get(elem: &ElemValue, idx: usize) -> i32 {
- alsa_sys::snd_ctl_elem_value_get_integer(elem.as_ptr(), idx as c_uint) as i32
- }
- /// Sets an i32 to the ElemValue.
- unsafe fn elem_value_set(elem: &mut ElemValue, idx: usize, val: i32) {
- alsa_sys::snd_ctl_elem_value_set_integer(elem.as_mut_ptr(), idx as c_uint, val as c_long);
- }
- /// Returns ElemType::Integer.
- fn elem_type() -> ElemType {
- ElemType::Integer
- }
-}
-
-/// All primitive types of a control element should implement `CtlElemValue` trait.
-trait CtlElemValue {
- /// The primitive type of a control element.
- type T;
- /// Gets the value from the ElemValue.
- unsafe fn elem_value_get(value: &ElemValue, idx: usize) -> Self::T;
- /// Sets the value to the ElemValue.
- unsafe fn elem_value_set(value: &mut ElemValue, id: usize, val: Self::T);
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType;
-}
-
-/// Use `Elem` trait to access the underlying control element through the given `Ctl` and `ElemId`.
-pub trait Elem: Sized {
- /// The data type of a control element.
- type T;
- /// Reads the value from the mixer control.
- fn load(handle: &mut Ctl, id: &ElemId) -> Result<Self::T>;
- /// Saves the value to the mixer control.
- fn save(handle: &mut Ctl, id: &ElemId, val: Self::T) -> Result<bool>;
- /// Gets the data type itself can read and write.
- fn elem_type() -> ElemType;
- /// Gets the number of value entries itself can read and write.
- fn size() -> usize;
-}
diff --git a/cros_alsa/src/lib.rs b/cros_alsa/src/lib.rs
deleted file mode 100644
index 070d221a..00000000
--- a/cros_alsa/src/lib.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-//! `cros_alsa` crate currently supports interacting with alsa
-//! controls by using the control interface API of alsa-lib.
-//!
-//! # Examples
-//! This is an example of how to use the provided `Control` objects.
-//!
-//! ``` no_run
-//! use std::error::Error;
-//! use std::result::Result;
-//!
-//! use cros_alsa::{Card, SwitchControl, IntControl, StereoVolumeControl};
-//!
-//! fn main() -> Result<(), Box<dyn Error>> {
-//!
-//! let mut card = Card::new("sofmax98390d")?;
-//!
-//! // Uses a SwitchControl to turn on and off a mixer control that has a single boolean state.
-//! let mut calib_ctrl:SwitchControl = card.control_by_name("Left DSM Calibration")?;
-//! calib_ctrl.on()?;
-//! assert_eq!(calib_ctrl.state()?, true);
-//! calib_ctrl.off()?;
-//!
-//! // Uses an IntControl to read and write a mixer control that has a single integer value.
-//! let mut rdc_ctrl:IntControl = card.control_by_name("Left Rdc")?;
-//! let _rdc = rdc_ctrl.get()?;
-//! rdc_ctrl.set(13000)?;
-//!
-//! // Uses a StereoVolumeControl to manipulate stereo volume related functionality.
-//! let mut volume_ctrl:StereoVolumeControl = card.control_by_name("Master Playback Volume")?;
-//! volume_ctrl.set_volume(184, 184)?;
-//!
-//! Ok(())
-//! }
-//! ```
-
-// Allow the maximum recursive depth = 256 for macro expansion.
-#![recursion_limit = "256"]
-#![deny(missing_docs)]
-
-mod card;
-mod control;
-mod control_primitive;
-pub mod control_tlv;
-pub mod elem;
-
-pub use self::card::Card;
-pub use self::control::{Control, ControlOps, IntControl, StereoVolumeControl, SwitchControl};
-pub use self::control_primitive::{Ctl, ElemId};
-pub use self::control_tlv::{ControlTLV, TLV};
-
-pub use self::card::Error as CardError;
-pub use self::control::Error as ControlError;
-pub use self::control_tlv::Error as ControlTLVError;
-pub use self::elem::Error as ElemError;
-
-#[allow(unused_imports)]
-pub use cros_alsa_derive::*;
diff --git a/init/cras.conf b/init/cras.conf
index 20847494..e7df7991 100644
--- a/init/cras.conf
+++ b/init/cras.conf
@@ -9,9 +9,6 @@ description "Chrome OS audio server"
author "chromium-os-dev@chromium.org"
env CRAS_SOCKET_DIR=/run/cras
-env CRAS_VMS_SOCKET_DIR=/run/cras/vms
-env CRAS_PLUGIN_DIR=/run/cras/vms/plugin
-env CRAS_ARGS=
start on starting system-services
stop on stopping system-services
@@ -23,20 +20,6 @@ limit rtprio 12 12
pre-start script
mkdir -p -m 1770 "${CRAS_SOCKET_DIR}"
chown -R cras:cras "${CRAS_SOCKET_DIR}"
- mkdir -p -m 1770 "${CRAS_VMS_SOCKET_DIR}"
- chown -R cras:cras "${CRAS_VMS_SOCKET_DIR}"
- for socket_dir in playback unified; do
- mkdir -p -m 1770 "${CRAS_PLUGIN_DIR}/${socket_dir}"
- chown -R cras:cras "${CRAS_PLUGIN_DIR}/${socket_dir}"
- done
- mkdir -m 0755 -p /var/lib/cras
- chown -R cras:cras /var/lib/cras
end script
exec /bin/sh /usr/share/cros/init/cras.sh
-
-# sound_card_init uses CRAS stop timestamp as a criterion to skip boot time
-# calibration for DSM.
-post-stop script
- echo "$(date +---%\nsecs:\ %s%\nnanos:\ %N)" > /var/lib/cras/stop
-end script
diff --git a/init/cras.sh b/init/cras.sh
index 91114c00..a1a21db2 100644
--- a/init/cras.sh
+++ b/init/cras.sh
@@ -6,11 +6,6 @@
device_config_dir="$(cros_config /audio/main cras-config-dir)"
internal_ucm_suffix="$(cros_config /audio/main ucm-suffix)"
-# Deprecate HSP since it's just too old.
-# TODO(hychao): Clean up all CRAS codes that are related to HSP once we're
-# sure no headset breaks because of that.
-DISABLE_PROFILE="--disable_profile=hsp"
-
# Handle legacy config.
if [ -z "${device_config_dir}" ]; then
# Disable HSP/HFP on Google WiFi (Gale) with UART-HCI Bluetooth
@@ -48,6 +43,7 @@ exec minijail0 -u cras -g cras -G --uts -v -l \
-k 'tmpfs,/run,tmpfs,MS_NODEV|MS_NOEXEC|MS_NOSUID,mode=755,size=10M' \
-b /run/cras,/run/cras,1 \
-b /run/dbus,/run/dbus,1 \
+ -b /run/systemd/journal \
-b /run/udev,/run/udev \
-b /dev,/dev \
-b /dev/shm,/dev/shm,1 \
@@ -61,4 +57,4 @@ exec minijail0 -u cras -g cras -G --uts -v -l \
-- \
/usr/bin/cras \
${DSP_CONFIG} ${DEVICE_CONFIG_DIR} ${DISABLE_PROFILE} \
- ${INTERNAL_UCM_SUFFIX} ${CRAS_ARGS}
+ ${INTERNAL_UCM_SUFFIX}
diff --git a/scripts/asoc_dapm_graph b/scripts/asoc_dapm_graph
index fd43736d..f02c60c5 100755
--- a/scripts/asoc_dapm_graph
+++ b/scripts/asoc_dapm_graph
@@ -42,7 +42,7 @@ def handle_widgets(path):
for l in lines[1:]:
l = l.rstrip()
# The string format is (in/out) "switch" "widget".
- edge = list(filter(None, re.split(r' (in|out) "(.+)" "(.+)"', l)))
+ edge = filter(None, re.split(r' (in|out) "(.+)" "(.+)"', l))
if len(edge) != 3:
continue
diff --git a/scripts/audio_diagnostics b/scripts/audio_diagnostics
index b754c07c..c3fe4f8d 100755
--- a/scripts/audio_diagnostics
+++ b/scripts/audio_diagnostics
@@ -7,37 +7,21 @@
# Collect information about the audio system from top to bottom.
dump_cards() {
- # shellcheck disable=SC2068
for card in ${@}
do
- echo "=== amixer -c ${card} scontents ==="
- amixer -c "${card}" scontents
- echo "=== amixer -c ${card} contents ==="
- amixer -c "${card}" contents
+ echo '=== amixer -c' $card scontents '==='
+ amixer -c $card scontents
+ echo '=== amixer -c' $card contents '==='
+ amixer -c $card contents
done
}
-# Helper function: in_the_list $1 $2
-# Returns 0 if str $1 is included in delimited str $2; otherwise 1
-in_the_list() {
- for item in $2
- do
- if [ "$1" = "${item}" ]; then
- return 0
- fi
- done
- return 1
-}
-
echo '=== cras_test_client --dump_server_info ==='
cras_test_client --dump_server_info
echo '=== cras_test_client --dump_audio_thread ==='
cras_test_client --dump_audio_thread
-echo '=== cras_test_client --dump_main ==='
-cras_test_client --dump_main
-
echo '=== cras_test_client --dump_bt ==='
cras_test_client --dump_bt
@@ -49,81 +33,28 @@ aplay -l
echo '=== arecord -l ==='
arecord -l
-output_cards=$(
- aplay -l | grep -E ^card | sed 's/card \([0-9]\+\).*/\1/' | sort -u)
-dump_cards "${output_cards}"
+output_cards=$(aplay -l | egrep ^card | sed 's/card \([0-9]\+\).*/\1/' | sort -u)
+dump_cards $output_cards
-input_cards=$(
- arecord -l | grep -E ^card | sed 's/card \([0-9]\+\).*/\1/' | sort -u)
-dump_cards "${input_cards}"
+input_cards=$(arecord -l | egrep ^card | sed 's/card \([0-9]\+\).*/\1/' | sort -u)
+dump_cards $input_cards
# HDA codec for codecs on x86.
codecs=$(find /proc/asound -mindepth 2 -maxdepth 2 -path '*card*/codec#*')
-for codec in ${codecs}
+for codec in $codecs
do
- echo "=== codec: ${codec} ==="
- cat "${codec}"
+ echo '=== codec:' $codec '==='
+ cat $codec
done
# I2C dump for codecs on arm.
# Find lines like "max98088.7-0010" and extract "7 0x0010" from it.
if [ -e /sys/kernel/debug/asoc/codecs ]; then
sed_expr='s/^\([^.-]\+\)\.\([0-9]\+\)-\([0-9]\+\)$/\2 0x\3/p'
- sed -n "${sed_expr}" /sys/kernel/debug/asoc/codecs |
- while read -r i2c_addr
+ sed -n "$sed_expr" /sys/kernel/debug/asoc/codecs |
+ while read i2c_addr
do
- echo "=== i2cdump -f -y ${i2c_addr} ==="
- i2cdump -f -y "${i2c_addr}"
+ echo '===' i2cdump -f -y $i2c_addr '==='
+ i2cdump -f -y $i2c_addr
done
fi
-
-# Dump registers from regmaps
-
-# List of audio components
-# For kernel>=4.14, it is in /sys/kernel/debug/asoc/components
-# For kernel<4.14, it is in /sys/kernel/debug/asoc/codecs
-if [ -f /sys/kernel/debug/asoc/components ]; then
- audio_comps=$(cat /sys/kernel/debug/asoc/components)
-else
- audio_comps=$(cat /sys/kernel/debug/asoc/codecs)
-fi
-
-# Blocklist regmap name of dumping registers (tracked by b/154177454)
-# Use the blank space as delimiter, e.g. 'name_a name_b name_c'
-name_blocklist='snd_hda_codec_hdmi'
-
-for file_path in /sys/kernel/debug/regmap/*
-do
- [ -e "${file_path}" ] || break # handle the case of no files
- component=$(basename "${file_path}")
-
- # Skip dumping registers if component is not listed in audio_comps
- if ! in_the_list "${component}" "${audio_comps}"; then
- continue
- fi
-
- if [ ! -f "${file_path}/name" ]; then
- echo "Failed at dump registers: ${file_path}"
- continue
- fi
-
- name=$(cat "${file_path}/name")
- echo "=== dump registers component: ${component} name: ${name} ==="
-
- # Skip dumping registers if regmap's name is in name_blocklist
- if in_the_list "${name}" "${name_blocklist}"; then
- echo 'skipped dumping due to b/154177454'
- continue
- fi
-
- # Store back the original value
- # Note: $(cat cache_bypass) returns 'Y' if flag is on; otherwise 'N'
- cache_bypass=$(cat "${file_path}/cache_bypass")
- if [ "${cache_bypass}" = "N" ]; then
- echo 1 > "${file_path}/cache_bypass"
- fi
- cat "${file_path}/registers"
- if [ "${cache_bypass}" = "N" ]; then
- echo 0 > "${file_path}/cache_bypass"
- fi
-done
diff --git a/scripts/audio_tuning/frontend/audio.js b/scripts/audio_tuning/frontend/audio.js
index 98870cdd..2476f1a9 100644
--- a/scripts/audio_tuning/frontend/audio.js
+++ b/scripts/audio_tuning/frontend/audio.js
@@ -1105,7 +1105,7 @@ function check_button(div, handler) {
this.update = update;
}
-function empty() {
+function dummy() {
}
/* Changes the opacity of a div. */
@@ -1185,7 +1185,7 @@ function drc_card(parent, index, lower_freq, freq_label) {
var f_slider;
if (lower_freq == 0) { /* Special case for the lowest band */
f_slider = new slider_input_log(table, freq_label, lower_freq, 0, 1,
- 'Hz', 0, empty);
+ 'Hz', 0, dummy);
f_slider.hide(true);
} else {
f_slider = new slider_input_log(table, freq_label, lower_freq, 1,
@@ -1570,7 +1570,7 @@ function DrcDrawer(canvas) {
var kneeThresholdDb;
var kneeThreshold;
var ykneeThresholdDb;
- var mainLinearGain;
+ var masterLinearGain;
var maxOutputDb = 6;
var minOutputDb = -36;
@@ -1662,10 +1662,10 @@ function DrcDrawer(canvas) {
kneeThreshold = dBToLinear(kneeThresholdDb);
ykneeThresholdDb = linearToDb(kneeCurve(kneeThreshold, curve_k));
- /* Calculate mainLinearGain */
+ /* Calculate masterLinearGain */
var fullRangeGain = saturate(1, curve_k);
var fullRangeMakeupGain = Math.pow(1 / fullRangeGain, 0.6);
- mainLinearGain = dBToLinear(boost) * fullRangeMakeupGain;
+ masterLinearGain = dBToLinear(boost) * fullRangeMakeupGain;
/* Clear canvas */
var width = canvas.width;
@@ -1725,7 +1725,7 @@ function DrcDrawer(canvas) {
var inputDb = xpixelToDb(x);
var inputLinear = dBToLinear(inputDb);
var outputLinear = saturate(inputLinear, curve_k);
- outputLinear *= mainLinearGain;
+ outputLinear *= masterLinearGain;
var outputDb = linearToDb(outputLinear);
var y = dBToYPixel(outputDb);
diff --git a/scripts/volume_tuning/volume.js b/scripts/volume_tuning/volume.js
index 88f39984..c5f05266 100644
--- a/scripts/volume_tuning/volume.js
+++ b/scripts/volume_tuning/volume.js
@@ -116,7 +116,7 @@ function redraw() {
var max = parseFloat(minmax_boxes[1].value);
var step = parseFloat(minmax_boxes[2].value);
- // Soundness checks
+ // Sanity checks
if (isNaN(min) || isNaN(max) || isNaN(step)) return;
if (min >= max || step <= 0 || (max - min) / step > 10000) return;
diff --git a/seccomp/cras-seccomp-amd64.policy b/seccomp/cras-seccomp-amd64.policy
index afa6ace6..06dc2243 100644
--- a/seccomp/cras-seccomp-amd64.policy
+++ b/seccomp/cras-seccomp-amd64.policy
@@ -11,7 +11,6 @@ poll: 1
ppoll: 1
fstat: 1
write: 1
-writev: 1
open: 1
openat: 1
close: 1
@@ -20,7 +19,6 @@ getrandom: 1
access: 1
fcntl: 1
getdents: 1
-getdents64: 1
sendmsg: 1
stat: 1
statfs: 1
@@ -36,13 +34,10 @@ futex: 1
lseek: 1
rt_sigaction: 1
socket: arg0 == AF_UNIX || arg0 == AF_BLUETOOTH || arg0 == AF_NETLINK
-socketpair: 1
unlink: 1
nanosleep: 1
-clock_nanosleep: 1
pipe: 1
ftruncate: 1
-fallocate: 1
mprotect: 1
connect: 1
getsockname: 1
@@ -64,7 +59,6 @@ setrlimit: 1
listen: 1
clone: 1
set_robust_list: 1
-setpriority: 1
getresuid: 1
getresgid: 1
sched_setscheduler: 1
@@ -92,4 +86,3 @@ prlimit64: 1
tgkill: 1
mremap: 1
dup: 1
-gettimeofday: 1
diff --git a/seccomp/cras-seccomp-arm.policy b/seccomp/cras-seccomp-arm.policy
index cbaa622b..f917036f 100644
--- a/seccomp/cras-seccomp-arm.policy
+++ b/seccomp/cras-seccomp-arm.policy
@@ -3,13 +3,10 @@
# found in the LICENSE file.
clock_gettime: 1
-clock_gettime64: 1
poll: 1
read: 1
ppoll: 1
-ppoll_time64: 1
write: 1
-writev: 1
recv: 1
send: 1
recvmsg: 1
@@ -41,13 +38,10 @@ unlink: 1
lsetxattr: 1
rt_sigprocmask: 1
ftruncate: 1
-fallocate: 1
futex: 1
-futex_time64: 1
execve: 1
set_robust_list: 1
socket: arg0 == AF_UNIX || arg0 == AF_BLUETOOTH || arg0 == AF_NETLINK
-socketpair: 1
clone: 1
setsockopt: 1
geteuid32: 1
@@ -67,8 +61,6 @@ exit_group: 1
getsockname: 1
getdents: 1
nanosleep: 1
-clock_nanosleep: 1
-clock_nanosleep_time64: 1
epoll_ctl: 1
sched_setscheduler: 1
restart_syscall: 1
@@ -77,10 +69,8 @@ getresuid32: 1
exit: 1
prctl: arg0 == PR_SET_NAME
clock_getres: 1
-clock_getres_time64: 1
epoll_create1: 1
fchmod: 1
-setpriority: 1
setrlimit: 1
listen: 1
gettid: 1
@@ -91,6 +81,7 @@ getresgid32: 1
pipe2: 1
sched_get_priority_max: 1
sysinfo: 1
+flock: 1
# Allow ioctl command of type 'A' and 'U' for SNDRV_PCM_IOCTL_* and
# SNDRV_CTL_IOCTL_*, and EVIOCGSW(8), EVIOCGNAME(256), EVIOCGBIT(0x05, 8),
@@ -101,4 +92,3 @@ prlimit64: 1
tgkill: 1
mremap: 1
dup: 1
-_newselect: 1
diff --git a/seccomp/cras-seccomp-arm64.policy b/seccomp/cras-seccomp-arm64.policy
index 4b523552..64f32440 100644
--- a/seccomp/cras-seccomp-arm64.policy
+++ b/seccomp/cras-seccomp-arm64.policy
@@ -10,7 +10,6 @@ ioctl: arg1 in 0xffff41ff && arg1 & 0x00004100 || arg1 in 0xffff55ff && arg1 & 0
ppoll: 1
read: 1
write: 1
-writev: 1
newfstatat: 1
fstat: 1
openat: 1
@@ -31,7 +30,6 @@ sendto: 1
brk: 1
munmap: 1
socket: arg0 == AF_UNIX || arg0 == AF_BLUETOOTH || arg0 == AF_NETLINK
-socketpair: 1
statfs: 1
getsockopt: 1
accept: 1
@@ -39,7 +37,6 @@ pipe2: 1
prctl: arg0 == PR_SET_NAME
futex: 1
ftruncate: 1
-fallocate: 1
connect: 1
bind: 1
clock_getres: 1
@@ -53,6 +50,7 @@ exit_group: 1
fchmod: 1
fchmodat: 1
flock: 1
+flock: 1
getegid: 1
geteuid: 1
getgid: 1
@@ -68,7 +66,6 @@ listen: 1
lsetxattr: 1
madvise: 1
nanosleep: 1
-clock_nanosleep: 1
restart_syscall: 1
rt_sigprocmask: 1
rt_sigreturn: 1
@@ -77,7 +74,6 @@ sched_get_priority_min: 1
sched_setscheduler: 1
setrlimit: 1
set_robust_list: 1
-setpriority: 1
setsockopt: 1
set_tid_address: 1
sysinfo: 1
diff --git a/sof_sys/.gitignore b/sof_sys/.gitignore
deleted file mode 100644
index fa8d85ac..00000000
--- a/sof_sys/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Cargo.lock
-target
diff --git a/sof_sys/.rustfmt.toml b/sof_sys/.rustfmt.toml
deleted file mode 100644
index a2db3012..00000000
--- a/sof_sys/.rustfmt.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-use_field_init_shorthand = true
-use_try_shorthand = true
diff --git a/sof_sys/Cargo.toml b/sof_sys/Cargo.toml
deleted file mode 100644
index 21934ee1..00000000
--- a/sof_sys/Cargo.toml
+++ /dev/null
@@ -1,4 +0,0 @@
-[package]
-name = "sof_sys"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
diff --git a/sof_sys/generator/.gitignore b/sof_sys/generator/.gitignore
deleted file mode 100644
index 03314f77..00000000
--- a/sof_sys/generator/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-Cargo.lock
diff --git a/sof_sys/generator/Cargo.toml b/sof_sys/generator/Cargo.toml
deleted file mode 100644
index 672d41da..00000000
--- a/sof_sys/generator/Cargo.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[package]
-name = "generator"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-[dependencies]
-bindgen = "0.43.0"
diff --git a/sof_sys/generator/README.md b/sof_sys/generator/README.md
deleted file mode 100644
index 3e2ca771..00000000
--- a/sof_sys/generator/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Use `cargo run` to generate rust bindings at sof_sys/src/bindings.rs
diff --git a/sof_sys/generator/src/main.rs b/sof_sys/generator/src/main.rs
deleted file mode 100644
index 60f0102d..00000000
--- a/sof_sys/generator/src/main.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-extern crate bindgen;
-
-use std::fs::File;
-use std::io::Write;
-use std::path::PathBuf;
-
-fn main() {
- let bindings = bindgen::Builder::default()
- .header("wrapper.h")
- .derive_debug(false)
- .clang_arg("-I../../../sound-open-firmware-private/src/include")
- .whitelist_type("sof_abi_hdr")
- .whitelist_type("sof_ipc_ctrl_cmd")
- .generate()
- .expect("Unable to generate bindings");
-
- let header = b"// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/*
- * generated from files in sound-open-firmware-private/src/include:
- * kernel/header.h
- * ipc/control.h
- */
-
-";
-
- // Write the bindings to the $OUT_DIR/bindings.rs file.
- let out_path = PathBuf::from("../src").join("bindings.rs");
-
- let mut output_file =
- File::create(&out_path).expect(&format!("Couldn't create {:?}", out_path));
- output_file
- .write_all(header)
- .expect("Couldn't write header");
- output_file
- .write_all(bindings.to_string().as_bytes())
- .expect("Couldn't write bindings");
-}
diff --git a/sof_sys/generator/wrapper.h b/sof_sys/generator/wrapper.h
deleted file mode 100644
index 5bac0f57..00000000
--- a/sof_sys/generator/wrapper.h
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2021 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#include <kernel/header.h>
-#include <ipc/control.h>
diff --git a/sof_sys/src/bindings.rs b/sof_sys/src/bindings.rs
deleted file mode 100644
index 7bed0dcf..00000000
--- a/sof_sys/src/bindings.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-/*
- * generated from files in sound-open-firmware-private/src/include:
- * kernel/header.h
- * ipc/control.h
- */
-
-/* automatically generated by rust-bindgen */
-
-#[repr(C)]
-#[derive(Default)]
-pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>);
-impl<T> __IncompleteArrayField<T> {
- #[inline]
- pub fn new() -> Self {
- __IncompleteArrayField(::std::marker::PhantomData)
- }
- #[inline]
- pub unsafe fn as_ptr(&self) -> *const T {
- ::std::mem::transmute(self)
- }
- #[inline]
- pub unsafe fn as_mut_ptr(&mut self) -> *mut T {
- ::std::mem::transmute(self)
- }
- #[inline]
- pub unsafe fn as_slice(&self, len: usize) -> &[T] {
- ::std::slice::from_raw_parts(self.as_ptr(), len)
- }
- #[inline]
- pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] {
- ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len)
- }
-}
-impl<T> ::std::fmt::Debug for __IncompleteArrayField<T> {
- fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
- fmt.write_str("__IncompleteArrayField")
- }
-}
-impl<T> ::std::clone::Clone for __IncompleteArrayField<T> {
- #[inline]
- fn clone(&self) -> Self {
- Self::new()
- }
-}
-impl<T> ::std::marker::Copy for __IncompleteArrayField<T> {}
-pub type __uint32_t = ::std::os::raw::c_uint;
-/// \brief Header for all non IPC ABI data.
-///
-/// Identifies data type, size and ABI.
-/// Data header used for all component data structures and binary blobs sent to
-/// firmware as runtime data. This data is typically sent by userspace
-/// applications and tunnelled through any OS kernel (via binary kcontrol on
-/// Linux) to the firmware.
-#[repr(C, packed)]
-pub struct sof_abi_hdr {
- ///< 'S', 'O', 'F', '\0'
- pub magic: u32,
- ///< component specific type
- pub type_: u32,
- ///< size in bytes of data excl. this struct
- pub size: u32,
- ///< SOF ABI version
- pub abi: u32,
- ///< reserved for future use
- pub reserved: [u32; 4usize],
- ///< Component data - opaque to core
- pub data: __IncompleteArrayField<u32>,
-}
-#[test]
-fn bindgen_test_layout_sof_abi_hdr() {
- assert_eq!(
- ::std::mem::size_of::<sof_abi_hdr>(),
- 32usize,
- concat!("Size of: ", stringify!(sof_abi_hdr))
- );
- assert_eq!(
- ::std::mem::align_of::<sof_abi_hdr>(),
- 1usize,
- concat!("Alignment of ", stringify!(sof_abi_hdr))
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).magic as *const _ as usize },
- 0usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(magic)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).type_ as *const _ as usize },
- 4usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(type_)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).size as *const _ as usize },
- 8usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(size)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).abi as *const _ as usize },
- 12usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(abi)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).reserved as *const _ as usize },
- 16usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(reserved)
- )
- );
- assert_eq!(
- unsafe { &(*(::std::ptr::null::<sof_abi_hdr>())).data as *const _ as usize },
- 32usize,
- concat!(
- "Offset of field: ",
- stringify!(sof_abi_hdr),
- "::",
- stringify!(data)
- )
- );
-}
-///< maps to ALSA volume style controls
-pub const sof_ipc_ctrl_cmd_SOF_CTRL_CMD_VOLUME: sof_ipc_ctrl_cmd = 0;
-///< maps to ALSA enum style controls
-pub const sof_ipc_ctrl_cmd_SOF_CTRL_CMD_ENUM: sof_ipc_ctrl_cmd = 1;
-///< maps to ALSA switch style controls
-pub const sof_ipc_ctrl_cmd_SOF_CTRL_CMD_SWITCH: sof_ipc_ctrl_cmd = 2;
-///< maps to ALSA binary style controls
-pub const sof_ipc_ctrl_cmd_SOF_CTRL_CMD_BINARY: sof_ipc_ctrl_cmd = 3;
-/// Control command type.
-pub type sof_ipc_ctrl_cmd = u32;
diff --git a/sof_sys/src/lib.rs b/sof_sys/src/lib.rs
deleted file mode 100644
index 57119cfa..00000000
--- a/sof_sys/src/lib.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-#![allow(clippy::unreadable_literal)]
-#![allow(clippy::cognitive_complexity)]
-#![allow(non_upper_case_globals)]
-#![allow(non_camel_case_types)]
-#![allow(non_snake_case)]
-
-pub mod bindings;
-#[allow(unused_imports)]
-pub use bindings::sof_abi_hdr;
diff --git a/sound_card_init/.gitignore b/sound_card_init/.gitignore
deleted file mode 100644
index b6e87008..00000000
--- a/sound_card_init/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-# Generated by Cargo
-# will have compiled files and executables
-**/target/
-
-# These are backup files generated by rustfmt
-**/*.rs.bk
diff --git a/sound_card_init/99-sound_card_init.rules b/sound_card_init/99-sound_card_init.rules
deleted file mode 100644
index 82a3aec8..00000000
--- a/sound_card_init/99-sound_card_init.rules
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-SUBSYSTEM!="sound", GOTO="sci_end"
-ACTION!="change", GOTO="sci_end"
-KERNEL!="card*", GOTO="sci_end"
-
-GOTO="sci_action"
-
-LABEL="sci_action"
-RUN+="/sbin/initctl start sound_card_init SOUND_CARD_ID=$attr{id}"
-LABEL="sci_end"
diff --git a/sound_card_init/Cargo.lock b/sound_card_init/Cargo.lock
deleted file mode 100644
index c89ad1ec..00000000
--- a/sound_card_init/Cargo.lock
+++ /dev/null
@@ -1,286 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "alsa-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644d308f5822c2b39fba5a6d850f74c208bf73c61d1d2dfad62505d6960e4977"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "amp"
-version = "0.1.0"
-dependencies = [
- "cros_alsa",
- "dsm",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sof_sys",
- "sys_util",
-]
-
-[[package]]
-name = "android_log-sys"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
-
-[[package]]
-name = "assertions"
-version = "0.1.0"
-
-[[package]]
-name = "audio_streams"
-version = "0.1.0"
-dependencies = [
- "sync",
- "sys_util",
-]
-
-[[package]]
-name = "cras-sys"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "data_model",
-]
-
-[[package]]
-name = "cros_alsa"
-version = "0.1.0"
-dependencies = [
- "alsa-sys",
- "cros_alsa_derive",
- "libc",
- "remain",
-]
-
-[[package]]
-name = "cros_alsa_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "data_model"
-version = "0.1.0"
-dependencies = [
- "assertions",
- "libc",
-]
-
-[[package]]
-name = "dsm"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cros_alsa",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sys_util",
-]
-
-[[package]]
-name = "dtoa"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
-
-[[package]]
-name = "getopts"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5"
-dependencies = [
- "unicode-width",
-]
-
-[[package]]
-name = "libc"
-version = "0.2.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
-
-[[package]]
-name = "libcras"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cras-sys",
- "data_model",
- "libc",
- "sys_util",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
-
-[[package]]
-name = "poll_token_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "remain"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.119"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9bdd36f49e35b61d49efd8aa7fc068fd295961fd2286d0b2ee9a4c7a14e99cc3"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.119"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "552954ce79a059ddd5fd68c271592374bd15cab2274970380c000118aeffe1cd"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_yaml"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f"
-dependencies = [
- "dtoa",
- "linked-hash-map",
- "serde",
- "yaml-rust",
-]
-
-[[package]]
-name = "sof_sys"
-version = "0.1.0"
-
-[[package]]
-name = "sound_card_init"
-version = "0.1.0"
-dependencies = [
- "amp",
- "audio_streams",
- "cros_alsa",
- "dsm",
- "getopts",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sof_sys",
- "sys_util",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.58"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "sync"
-version = "0.1.0"
-
-[[package]]
-name = "sys_util"
-version = "0.1.0"
-dependencies = [
- "android_log-sys",
- "data_model",
- "libc",
- "poll_token_derive",
- "sync",
- "syscall_defines",
- "tempfile",
-]
-
-[[package]]
-name = "syscall_defines"
-version = "0.1.0"
-
-[[package]]
-name = "tempfile"
-version = "3.0.7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "unicode-width"
-version = "0.1.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
diff --git a/sound_card_init/Cargo.toml b/sound_card_init/Cargo.toml
deleted file mode 100644
index 9d5a107e..00000000
--- a/sound_card_init/Cargo.toml
+++ /dev/null
@@ -1,33 +0,0 @@
-[package]
-name = "sound_card_init"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "Sound Card Initializer"
-
-[workspace]
-members = [
- "amp",
- "dsm"
-]
-
-[dependencies]
-amp = { path = "amp" }
-audio_streams = "*"
-cros_alsa = "*"
-dsm = { path = "dsm" }
-getopts = "0.2"
-libcras = "*"
-remain = "0.2.1"
-serde = { version = "1.0", features = ["derive"] }
-serde_yaml = "0.8.11"
-sof_sys = "*"
-sys_util = "*"
-
-[patch.crates-io]
-audio_streams = { path = "../audio_streams" } # ignored by ebuild
-cros_alsa = { path = "../cros_alsa" } # ignored by ebuild
-cros_alsa_derive = { path = "../cros_alsa/cros_alsa_derive" } # ignored by ebuild
-libcras = { path = "../cras/client/libcras" } # ignored by ebuild
-sof_sys = { path = "../sof_sys" } # ignored by ebuild
-sys_util = { path = "../../../platform/crosvm/sys_util" } # ignored by ebuild
diff --git a/sound_card_init/amp/Cargo.lock b/sound_card_init/amp/Cargo.lock
deleted file mode 100644
index 679e60cd..00000000
--- a/sound_card_init/amp/Cargo.lock
+++ /dev/null
@@ -1,254 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "alsa-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644d308f5822c2b39fba5a6d850f74c208bf73c61d1d2dfad62505d6960e4977"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "amp"
-version = "0.1.0"
-dependencies = [
- "cros_alsa",
- "dsm",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sof_sys",
- "sys_util",
-]
-
-[[package]]
-name = "android_log-sys"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
-
-[[package]]
-name = "assertions"
-version = "0.1.0"
-
-[[package]]
-name = "audio_streams"
-version = "0.1.0"
-dependencies = [
- "sync",
- "sys_util",
-]
-
-[[package]]
-name = "cras-sys"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "data_model",
-]
-
-[[package]]
-name = "cros_alsa"
-version = "0.1.0"
-dependencies = [
- "alsa-sys",
- "cros_alsa_derive",
- "libc",
- "remain",
-]
-
-[[package]]
-name = "cros_alsa_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "data_model"
-version = "0.1.0"
-dependencies = [
- "assertions",
- "libc",
-]
-
-[[package]]
-name = "dsm"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cros_alsa",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sys_util",
-]
-
-[[package]]
-name = "dtoa"
-version = "0.4.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
-
-[[package]]
-name = "libc"
-version = "0.2.84"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff"
-
-[[package]]
-name = "libcras"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cras-sys",
- "data_model",
- "libc",
- "sys_util",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
-
-[[package]]
-name = "pkg-config"
-version = "0.3.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
-
-[[package]]
-name = "poll_token_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "remain"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ba1e78fa68412cb93ef642fd4d20b9a941be49ee9333875ebaf13112673ea7"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.123"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_yaml"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "971be8f6e4d4a47163b405a3df70d14359186f9ab0f3a3ec37df144ca1ce089f"
-dependencies = [
- "dtoa",
- "linked-hash-map",
- "serde",
- "yaml-rust",
-]
-
-[[package]]
-name = "sof_sys"
-version = "0.1.0"
-
-[[package]]
-name = "syn"
-version = "1.0.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "sync"
-version = "0.1.0"
-
-[[package]]
-name = "sys_util"
-version = "0.1.0"
-dependencies = [
- "android_log-sys",
- "data_model",
- "libc",
- "poll_token_derive",
- "sync",
- "syscall_defines",
- "tempfile",
-]
-
-[[package]]
-name = "syscall_defines"
-version = "0.1.0"
-
-[[package]]
-name = "tempfile"
-version = "3.0.7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
-dependencies = [
- "linked-hash-map",
-]
diff --git a/sound_card_init/amp/Cargo.toml b/sound_card_init/amp/Cargo.toml
deleted file mode 100644
index 62e63db7..00000000
--- a/sound_card_init/amp/Cargo.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-[package]
-name = "amp"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "The boot time calibration logic for smart amp"
-
-[dependencies]
-cros_alsa = "*"
-libcras = "*"
-dsm = { path = "../dsm" }
-remain = "0.2.1"
-serde = { version = "1.0", features = ["derive"]}
-serde_yaml = "0.8.11"
-sof_sys = "*"
-sys_util = "*"
diff --git a/sound_card_init/amp/src/lib.rs b/sound_card_init/amp/src/lib.rs
deleted file mode 100644
index 7114233d..00000000
--- a/sound_card_init/amp/src/lib.rs
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2021 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `amp` crate provides `Amp` trait for amplifier initializations and `AmpBuilder`
-//! to create `Amp` objects.
-#![deny(missing_docs)]
-
-mod max98373d;
-mod max98390d;
-use std::path::PathBuf;
-
-use dsm::Error;
-
-use max98373d::Max98373;
-use max98390d::Max98390;
-
-type Result<T> = std::result::Result<T, Error>;
-const CONF_DIR: &str = "/etc/sound_card_init";
-
-/// It creates `Amp` object based on the sound card name.
-pub struct AmpBuilder<'a> {
- sound_card_id: &'a str,
- config_path: PathBuf,
-}
-
-impl<'a> AmpBuilder<'a> {
- /// Creates an `AmpBuilder`.
- /// # Arguments
- ///
- /// * `card_name` - card name.
- /// * `conf_file` - config file name.
- pub fn new(sound_card_id: &'a str, conf_file: &'a str) -> Self {
- let config_path = PathBuf::from(CONF_DIR).join(conf_file);
- AmpBuilder {
- sound_card_id,
- config_path,
- }
- }
-
- /// Creates an `Amp` based on the sound card name.
- pub fn build(&self) -> Result<Box<dyn Amp>> {
- match self.sound_card_id {
- "sofcmlmax98390d" => {
- Ok(Box::new(Max98390::new(self.sound_card_id, &self.config_path)?) as Box<dyn Amp>)
- }
- "sofrt5682" => {
- Ok(Box::new(Max98373::new(self.sound_card_id, &self.config_path)?) as Box<dyn Amp>)
- }
- _ => Err(Error::UnsupportedSoundCard(self.sound_card_id.to_owned())),
- }
- }
-}
-
-/// It defines the required functions of amplifier objects.
-pub trait Amp {
- /// The amplifier boot time calibration flow.
- fn boot_time_calibration(&mut self) -> Result<()>;
-}
diff --git a/sound_card_init/amp/src/max98373d/dsm_param.rs b/sound_card_init/amp/src/max98373d/dsm_param.rs
deleted file mode 100644
index d9257522..00000000
--- a/sound_card_init/amp/src/max98373d/dsm_param.rs
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::mem;
-
-use cros_alsa::{Card, TLV};
-use sof_sys::sof_abi_hdr;
-
-use dsm::{self, Error, Result};
-
-/// Amp volume mode enumeration used by set_volume().
-#[derive(Copy, Clone, PartialEq)]
-pub enum VolumeMode {
- /// Low mode protects the speaker by limiting its output volume if the
- /// calibration has not been completed successfully.
- Low = 0x1009B9CF,
- /// High mode removes the speaker output volume limitation after
- /// having successfully completed the calibration.
- High = 0x20000000,
-}
-
-#[derive(Copy, Clone)]
-/// Calibration mode enumeration.
-pub enum CalibMode {
- ON = 0x4,
- OFF = 0x1,
-}
-
-#[derive(Copy, Clone)]
-/// Smart pilot signal mode mode enumeration.
-pub enum SPTMode {
- ON = 0x1,
- OFF = 0x0,
-}
-
-#[derive(Copy, Clone)]
-/// DSM Parem field enumeration.
-enum DsmAPI {
- ParamCount = 0x0,
- CalibMode = 0x1,
- MakeupGain = 0x5,
- DsmRdc = 0x6,
- DsmAmbientTemp = 0x8,
- AdaptiveRdc = 0x12,
- SPTMode = 0x68,
-}
-
-#[derive(Debug)]
-/// It implements functions to access the `DSMParam` fields.
-pub struct DSMParam {
- param_count: usize,
- num_channels: usize,
- tlv: TLV,
-}
-
-impl DSMParam {
- const DWORD_PER_PARAM: usize = 2;
- const VALUE_OFFSET: usize = 1;
- const SOF_HEADER_SIZE: usize = mem::size_of::<sof_abi_hdr>() / mem::size_of::<i32>();
-
- /// Creates an `DSMParam`.
- /// # Arguments
- ///
- /// * `card` - `&Card`.
- /// * `num_channels` - number of channels.
- /// * `ctl_name` - the mixer control name to access the DSM param.
- ///
- /// # Results
- ///
- /// * `DSMParam` - It is initialized by the content of the given byte control .
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card: &mut Card, num_channels: usize, ctl_name: &str) -> Result<Self> {
- let tlv = card.control_tlv_by_name(ctl_name)?.load()?;
- Self::try_from_tlv(tlv, num_channels)
- }
-
- /// Sets DSMParam to the given calibration mode.
- pub fn set_calibration_mode(&mut self, mode: CalibMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::CalibMode, mode as i32);
- }
- }
-
- /// Sets DSMParam to the given smart pilot signal mode.
- pub fn set_spt_mode(&mut self, mode: SPTMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::SPTMode, mode as i32);
- }
- }
-
- /// Sets DSMParam to the given VolumeMode.
- pub fn set_volume_mode(&mut self, mode: VolumeMode) {
- for channel in 0..self.num_channels {
- self.set(channel, DsmAPI::MakeupGain, mode as i32);
- }
- }
-
- /// Reads the calibrated rdc from DSMParam.
- pub fn get_adaptive_rdc(&self) -> Vec<i32> {
- self.get(DsmAPI::AdaptiveRdc)
- }
-
- /// Sets DSMParam to the given the calibrated rdc.
- pub fn set_rdc(&mut self, ch: usize, rdc: i32) {
- self.set(ch, DsmAPI::DsmRdc, rdc);
- }
-
- /// Sets DSMParam to the given calibrated temp.
- pub fn set_ambient_temp(&mut self, ch: usize, temp: i32) {
- self.set(ch, DsmAPI::DsmAmbientTemp, temp);
- }
-
- /// Sets the `id` field to the given `val`.
- fn set(&mut self, channel: usize, id: DsmAPI, val: i32) {
- let pos = Self::value_pos(self.param_count, channel, id);
- self.tlv[pos] = val as u32;
- }
-
- /// Gets the val from the `id` field from all the channels.
- fn get(&self, id: DsmAPI) -> Vec<i32> {
- (0..self.num_channels)
- .map(|channel| {
- let pos = Self::value_pos(self.param_count, channel, id);
- self.tlv[pos] as i32
- })
- .collect()
- }
-
- fn try_from_tlv(tlv: TLV, num_channels: usize) -> Result<Self> {
- let param_count_pos = Self::value_pos(0, 0, DsmAPI::ParamCount);
-
- if tlv.len() < param_count_pos {
- return Err(Error::InvalidDSMParam);
- }
-
- let param_count = tlv[param_count_pos] as usize;
-
- if tlv.len() != Self::SOF_HEADER_SIZE + param_count * num_channels * Self::DWORD_PER_PARAM {
- return Err(Error::InvalidDSMParam);
- }
-
- Ok(Self {
- param_count,
- num_channels,
- tlv,
- })
- }
-
- #[inline]
- fn value_pos(param_count: usize, channel: usize, id: DsmAPI) -> usize {
- Self::SOF_HEADER_SIZE
- + (channel * param_count + id as usize) * Self::DWORD_PER_PARAM
- + Self::VALUE_OFFSET
- }
-}
-
-impl Into<TLV> for DSMParam {
- fn into(self) -> TLV {
- self.tlv
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- const PARAM_COUNT: usize = 138;
- const CHANNEL_COUNT: usize = 2;
-
- #[test]
- fn test_dsmparam_try_from_tlv_ok() {
- let mut data = vec![
- 0u32;
- DSMParam::SOF_HEADER_SIZE
- + CHANNEL_COUNT * PARAM_COUNT * DSMParam::DWORD_PER_PARAM
- ];
- data[DSMParam::value_pos(PARAM_COUNT, 0, DsmAPI::ParamCount)] = PARAM_COUNT as u32;
- data[DSMParam::value_pos(PARAM_COUNT, 1, DsmAPI::ParamCount)] = PARAM_COUNT as u32;
-
- let tlv = TLV::new(0, data);
- assert!(DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).is_ok());
- }
-
- #[test]
- fn test_dsmparam_try_from_invalid_len() {
- let data = vec![0u32; DSMParam::SOF_HEADER_SIZE];
-
- let tlv = TLV::new(0, data);
- assert_eq!(
- DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).unwrap_err(),
- Error::InvalidDSMParam
- );
- }
-
- #[test]
- fn test_dsmparam_try_from_param_count() {
- let data = vec![
- 0u32;
- DSMParam::SOF_HEADER_SIZE
- + CHANNEL_COUNT * PARAM_COUNT * DSMParam::DWORD_PER_PARAM
- ];
-
- let tlv = TLV::new(0, data);
- assert_eq!(
- DSMParam::try_from_tlv(tlv, CHANNEL_COUNT).unwrap_err(),
- Error::InvalidDSMParam
- );
- }
-}
diff --git a/sound_card_init/amp/src/max98373d/mod.rs b/sound_card_init/amp/src/max98373d/mod.rs
deleted file mode 100644
index 1ee29ceb..00000000
--- a/sound_card_init/amp/src/max98373d/mod.rs
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `max98373d` module implements the required initialization workflows for sound
-//! cards that use max98373d smart amp.
-//! It currently supports boot time calibration for max98373d.
-#![deny(missing_docs)]
-mod dsm_param;
-mod settings;
-
-use std::path::Path;
-use std::time::Duration;
-use std::{fs, thread};
-
-use cros_alsa::{Card, IntControl};
-use dsm::{CalibData, Error, Result, SpeakerStatus, ZeroPlayer, DSM};
-use sys_util::info;
-
-use crate::Amp;
-use dsm_param::*;
-use settings::{AmpCalibSettings, DeviceSettings};
-
-/// It implements the amplifier boot time calibration flow.
-pub struct Max98373 {
- card: Card,
- setting: AmpCalibSettings,
-}
-
-impl Amp for Max98373 {
- /// Performs max98373d boot time calibration.
- ///
- /// # Errors
- ///
- /// If any amplifiers fail to complete the calibration.
- fn boot_time_calibration(&mut self) -> Result<()> {
- if !Path::new(&self.setting.dsm_param).exists() {
- return Err(Error::MissingDSMParam);
- }
-
- let num_channels = self.setting.num_channels();
- let dsm = DSM::new(
- &self.card.name(),
- num_channels,
- Self::rdc_to_ohm,
- Self::TEMP_UPPER_LIMIT_CELSIUS,
- Self::TEMP_LOWER_LIMIT_CELSIUS,
- );
- self.set_volume(VolumeMode::Low)?;
-
- let calib = if !self.setting.boot_time_calibration_enabled {
- info!("skip boot time calibration and use vpd values");
- // Needs Rdc updates to be done after internal speaker is ready otherwise
- // it would be overwritten by the DSM blob update.
- dsm.wait_for_speakers_ready()?;
- dsm.get_all_vpd_calibration_value()?
- } else {
- match dsm.check_speaker_over_heated_workflow()? {
- SpeakerStatus::Hot(previous_calib) => previous_calib,
- SpeakerStatus::Cold => {
- let all_temp = self.get_ambient_temp()?;
- let all_rdc = self.do_rdc_calibration()?;
- all_rdc
- .iter()
- .zip(all_temp)
- .enumerate()
- .map(|(ch, (&rdc, temp))| {
- dsm.decide_calibration_value_workflow(ch, CalibData { rdc, temp })
- })
- .collect::<Result<Vec<_>>>()?
- }
- }
- };
- self.apply_calibration_value(&calib)?;
- self.set_volume(VolumeMode::High)?;
- Ok(())
- }
-}
-
-impl Max98373 {
- const TEMP_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(10);
- const RDC_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(500);
- const RDC_CALIB_INTERVAL: Duration = Duration::from_millis(200);
- const CALIB_REPEAT_TIMES: usize = 5;
-
- const TEMP_UPPER_LIMIT_CELSIUS: f32 = 40.0;
- const TEMP_LOWER_LIMIT_CELSIUS: f32 = 0.0;
-
- /// Creates an `Max98373`.
- /// # Arguments
- ///
- /// * `card_name` - card_name.
- /// * `config_path` - config file path.
- ///
- /// # Results
- ///
- /// * `Max98373` - It implements the Max98373 functions of boot time calibration.
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card_name: &str, config_path: &Path) -> Result<Self> {
- let conf = fs::read_to_string(config_path)
- .map_err(|e| Error::FileIOFailed(config_path.to_path_buf(), e))?;
- let settings = DeviceSettings::from_yaml_str(&conf)?;
- Ok(Self {
- card: Card::new(card_name)?,
- setting: settings.amp_calibrations,
- })
- }
-
- /// Triggers the amplifier calibration and reads the calibrated rdc.
- /// To get accurate calibration results, the main thread calibrates the amplifier while
- /// the `zero_player` starts another thread to play zeros to the speakers.
- fn do_rdc_calibration(&mut self) -> Result<Vec<i32>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::RDC_CALIB_WARM_UP_TIME)?;
- // Playback of zeros is started for Self::RDC_CALIB_WARM_UP_TIME, and the main thread
- // can start the calibration.
- self.set_spt_mode(SPTMode::OFF)?;
- self.set_calibration_mode(CalibMode::ON)?;
- // Playback of zeros is started, and the main thread can start the calibration.
- let mut avg_rdc = vec![0; self.setting.num_channels()];
- for _ in 0..Self::CALIB_REPEAT_TIMES {
- let rdc = self.get_adaptive_rdc()?;
- for i in 0..self.setting.num_channels() {
- avg_rdc[i] += rdc[i];
- }
- thread::sleep(Self::RDC_CALIB_INTERVAL);
- }
- self.set_spt_mode(SPTMode::ON)?;
- self.set_calibration_mode(CalibMode::OFF)?;
- zero_player.stop()?;
-
- avg_rdc = avg_rdc
- .iter()
- .map(|val| val / Self::CALIB_REPEAT_TIMES as i32)
- .collect();
- Ok(avg_rdc)
- }
-
- /// Sets the card volume control to the given VolumeMode.
- fn set_volume(&mut self, mode: VolumeMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
-
- dsm_param.set_volume_mode(mode);
-
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Applies the calibration value to the amp.
- fn apply_calibration_value(&mut self, calib: &[CalibData]) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- for ch in 0..self.setting.num_channels() {
- dsm_param.set_rdc(ch, calib[ch].rdc);
- dsm_param.set_ambient_temp(ch, Self::celsius_to_dsm_unit(calib[ch].temp));
- }
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Rdc (ohm) = [ID:0x12] * 3.66 / 2^27
- #[inline]
- fn rdc_to_ohm(x: i32) -> f32 {
- (3.66 * x as f32) / (1 << 27) as f32
- }
-
- /// Returns the ambient temperature in celsius degree.
- fn get_ambient_temp(&mut self) -> Result<Vec<f32>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::TEMP_CALIB_WARM_UP_TIME)?;
- let mut temps = Vec::new();
- for x in 0..self.setting.num_channels() as usize {
- let temp = self
- .card
- .control_by_name::<IntControl>(&self.setting.temp_ctrl[x])?
- .get()?;
- let celsius = Self::measured_temp_to_celsius(temp);
- temps.push(celsius);
- }
- zero_player.stop()?;
-
- Ok(temps)
- }
-
- /// Converts the measured ambient temperature to celsius unit.
- #[inline]
- fn measured_temp_to_celsius(temp: i32) -> f32 {
- // Measured Temperature (°C) = ([Mixer Val] * 1.28) - 29
- (temp as f32 * 1.28) - 29.0
- }
-
- /// Converts the ambient temperature from celsius to the DsmSetAPI::DsmAmbientTemp unit.
- #[inline]
- fn celsius_to_dsm_unit(celsius: f32) -> i32 {
- // Temperature (℃) = [ID:0x12] / 2^19
- (celsius * (1 << 19) as f32) as i32
- }
-
- /// Sets the amp to the given smart pilot signal mode.
- fn set_spt_mode(&mut self, mode: SPTMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- dsm_param.set_spt_mode(mode);
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Sets the amp to the given the calibration mode.
- fn set_calibration_mode(&mut self, mode: CalibMode) -> Result<()> {
- let mut dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- dsm_param.set_calibration_mode(mode);
- self.card
- .control_tlv_by_name(&self.setting.dsm_param_write_ctrl)?
- .save(dsm_param.into())
- .map_err(Error::DSMParamUpdateFailed)?;
- Ok(())
- }
-
- /// Reads the calibrated rdc.
- /// Must be called when the calibration mode in on.
- fn get_adaptive_rdc(&mut self) -> Result<Vec<i32>> {
- let dsm_param = DSMParam::new(
- &mut self.card,
- self.setting.num_channels(),
- &self.setting.dsm_param_read_ctrl,
- )?;
- Ok(dsm_param.get_adaptive_rdc())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn celsius_to_dsm_unit() {
- assert_eq!(Max98373::celsius_to_dsm_unit(37.0), 0x01280000);
- assert_eq!(Max98373::celsius_to_dsm_unit(50.0), 0x01900000);
- }
-
- #[test]
- fn rdc_to_ohm() {
- assert_eq!(Max98373::rdc_to_ohm(0x05cea0c7), 2.656767);
- }
-
- #[test]
- fn measured_temp_to_celsius() {
- assert_eq!(Max98373::measured_temp_to_celsius(56), 42.68);
- }
-}
diff --git a/sound_card_init/amp/src/max98373d/settings.rs b/sound_card_init/amp/src/max98373d/settings.rs
deleted file mode 100644
index 1d6e64e5..00000000
--- a/sound_card_init/amp/src/max98373d/settings.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::string::String;
-
-use dsm::{self, Error, Result};
-use serde::Deserialize;
-/// `DeviceSettings` includes the settings of max98373. It currently includes:
-/// * the settings of amplifier calibration.
-/// * the path of dsm_param.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct DeviceSettings {
- pub amp_calibrations: AmpCalibSettings,
-}
-
-/// `AmpCalibSettings` includes the settings needed for amplifier calibration.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibSettings {
- pub dsm_param_read_ctrl: String,
- pub dsm_param_write_ctrl: String,
- pub temp_ctrl: Vec<String>,
- // Path of the dsm_param.bin file.
- pub dsm_param: String,
- pub boot_time_calibration_enabled: bool,
-}
-
-impl AmpCalibSettings {
- /// Returns the number of channels.
- pub fn num_channels(&self) -> usize {
- self.temp_ctrl.len()
- }
-}
-
-impl DeviceSettings {
- /// Creates a `DeviceSettings` from a yaml str.
- pub fn from_yaml_str(conf: &str) -> Result<DeviceSettings> {
- let settings: DeviceSettings = serde_yaml::from_str(conf)
- .map_err(|e| Error::DeserializationFailed("DeviceSettings".to_owned(), e))?;
- Ok(settings)
- }
-}
diff --git a/sound_card_init/amp/src/max98390d/mod.rs b/sound_card_init/amp/src/max98390d/mod.rs
deleted file mode 100644
index 601165ec..00000000
--- a/sound_card_init/amp/src/max98390d/mod.rs
+++ /dev/null
@@ -1,213 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `max98390d` module implements the required initialization workflows for sound
-//! cards that use max98390d smart amp.
-//! It currently supports boot time calibration for max98390d.
-#![deny(missing_docs)]
-mod settings;
-
-use std::time::Duration;
-use std::{fs, path::Path};
-
-use cros_alsa::{Card, IntControl, SwitchControl};
-use dsm::{CalibData, Error, Result, SpeakerStatus, TempConverter, ZeroPlayer, DSM};
-
-use crate::Amp;
-use settings::{AmpCalibSettings, DeviceSettings};
-
-/// Amp volume mode emulation used by set_volume().
-#[derive(PartialEq, Clone, Copy)]
-enum VolumeMode {
- /// Low mode protects the speaker by limiting its output volume if the
- /// calibration has not been completed successfully.
- Low = 138,
- /// High mode removes the speaker output volume limitation after
- /// having successfully completed the calibration.
- High = 148,
-}
-
-/// It implements the Max98390 functions of boot time calibration.
-#[derive(Debug)]
-pub struct Max98390 {
- card: Card,
- setting: AmpCalibSettings,
-}
-
-impl Amp for Max98390 {
- /// Performs max98390d boot time calibration.
- ///
- /// # Errors
- ///
- /// If the amplifier fails to complete the calibration.
- fn boot_time_calibration(&mut self) -> Result<()> {
- if !Path::new(&self.setting.dsm_param).exists() {
- return Err(Error::MissingDSMParam);
- }
-
- let mut dsm = DSM::new(
- &self.card.name(),
- self.setting.num_channels(),
- Self::rdc_to_ohm,
- Self::TEMP_UPPER_LIMIT_CELSIUS,
- Self::TEMP_LOWER_LIMIT_CELSIUS,
- );
- dsm.set_temp_converter(TempConverter::new(
- Self::dsm_unit_to_celsius,
- Self::celsius_to_dsm_unit,
- ));
-
- self.set_volume(VolumeMode::Low)?;
- let calib = match dsm.check_speaker_over_heated_workflow()? {
- SpeakerStatus::Hot(previous_calib) => previous_calib,
- SpeakerStatus::Cold => self
- .do_calibration()?
- .iter()
- .enumerate()
- .map(|(ch, calib_data)| dsm.decide_calibration_value_workflow(ch, *calib_data))
- .collect::<Result<Vec<_>>>()?,
- };
- self.apply_calibration_value(calib)?;
- self.set_volume(VolumeMode::High)?;
- Ok(())
- }
-}
-
-impl Max98390 {
- const TEMP_UPPER_LIMIT_CELSIUS: f32 = 40.0;
- const TEMP_LOWER_LIMIT_CELSIUS: f32 = 0.0;
- const RDC_CALIB_WARM_UP_TIME: Duration = Duration::from_millis(300);
-
- /// Creates an `Max98390`.
- /// # Arguments
- ///
- /// * `card_name` - card name.
- /// * `config_path` - config file path.
- ///
- /// # Results
- ///
- /// * `Max98390` - It implements the Max98390 functions of boot time calibration.
- ///
- /// # Errors
- ///
- /// * If `Card` creation from sound card name fails.
- pub fn new(card_name: &str, config_path: &Path) -> Result<Self> {
- let conf = fs::read_to_string(config_path)
- .map_err(|e| Error::FileIOFailed(config_path.to_path_buf(), e))?;
- let settings = DeviceSettings::from_yaml_str(&conf)?;
- Ok(Self {
- card: Card::new(card_name)?,
- setting: settings.amp_calibrations,
- })
- }
-
- /// Sets the card volume control to given VolumeMode.
- fn set_volume(&mut self, mode: VolumeMode) -> Result<()> {
- for control in &self.setting.controls {
- self.card
- .control_by_name::<IntControl>(&control.volume_ctrl)?
- .set(mode as i32)?;
- }
- Ok(())
- }
-
- /// Applies the calibration value to the amp.
- fn apply_calibration_value(&mut self, calib: Vec<CalibData>) -> Result<()> {
- for (ch, &CalibData { rdc, temp }) in calib.iter().enumerate() {
- self.card
- .control_by_name::<IntControl>(&self.setting.controls[ch].rdc_ctrl)?
- .set(rdc)?;
- self.card
- .control_by_name::<IntControl>(&self.setting.controls[ch].temp_ctrl)?
- .set(Self::celsius_to_dsm_unit(temp))?;
- }
- Ok(())
- }
-
- /// Triggers the amplifier calibration and reads the calibrated rdc and ambient_temp value
- /// from the mixer control.
- /// To get accurate calibration results, the main thread calibrates the amplifier while
- /// the `zero_player` starts another thread to play zeros to the speakers.
- fn do_calibration(&mut self) -> Result<Vec<CalibData>> {
- let mut zero_player: ZeroPlayer = Default::default();
- zero_player.start(Self::RDC_CALIB_WARM_UP_TIME)?;
- // Playback of zeros is started for Self::RDC_CALIB_WARM_UP_TIME, and the main thread
- // can start the calibration.
- let setting = &self.setting;
- let card = &mut self.card;
- let calib = setting
- .controls
- .iter()
- .map(|control| {
- card.control_by_name::<SwitchControl>(&control.calib_ctrl)?
- .on()?;
- let rdc = card
- .control_by_name::<IntControl>(&control.rdc_ctrl)?
- .get()?;
- let temp = card
- .control_by_name::<IntControl>(&control.temp_ctrl)?
- .get()?;
- card.control_by_name::<SwitchControl>(&control.calib_ctrl)?
- .off()?;
- Ok(CalibData {
- rdc,
- temp: Self::dsm_unit_to_celsius(temp),
- })
- })
- .collect::<Result<Vec<CalibData>>>()?;
- zero_player.stop()?;
- Ok(calib)
- }
-
- /// Converts the ambient temperature from celsius to the DSM unit.
- #[inline]
- fn celsius_to_dsm_unit(celsius: f32) -> i32 {
- (celsius * ((1 << 12) as f32) / 100.0) as i32
- }
-
- /// Converts the ambient temperature from DSM unit to celsius.
- #[inline]
- fn dsm_unit_to_celsius(temp: i32) -> f32 {
- temp as f32 * 100.0 / (1 << 12) as f32
- }
-
- /// Converts the calibrated value to real DC resistance in ohm unit.
- #[inline]
- fn rdc_to_ohm(x: i32) -> f32 {
- 3.66 * (1 << 20) as f32 / x as f32
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn celsius_to_dsm_unit() {
- assert_eq!(
- Max98390::celsius_to_dsm_unit(Max98390::TEMP_UPPER_LIMIT_CELSIUS),
- 1638
- );
- assert_eq!(
- Max98390::celsius_to_dsm_unit(Max98390::TEMP_LOWER_LIMIT_CELSIUS),
- 0
- );
- }
-
- #[test]
- fn dsm_unit_to_celsius() {
- assert_eq!(
- Max98390::dsm_unit_to_celsius(1638).round(),
- Max98390::TEMP_UPPER_LIMIT_CELSIUS
- );
- assert_eq!(
- Max98390::dsm_unit_to_celsius(0),
- Max98390::TEMP_LOWER_LIMIT_CELSIUS
- );
- }
-
- #[test]
- fn rdc_to_ohm() {
- assert_eq!(Max98390::rdc_to_ohm(1123160), 3.416956);
- assert_eq!(Max98390::rdc_to_ohm(1157049), 3.3168762);
- }
-}
diff --git a/sound_card_init/amp/src/max98390d/settings.rs b/sound_card_init/amp/src/max98390d/settings.rs
deleted file mode 100644
index 316f25be..00000000
--- a/sound_card_init/amp/src/max98390d/settings.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::string::String;
-
-use dsm::{self, Error, Result};
-use serde::Deserialize;
-
-/// `DeviceSettings` includes the settings of max98390. It currently includes:
-/// * the settings of amplifier calibration.
-/// * the path of dsm_param.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct DeviceSettings {
- pub amp_calibrations: AmpCalibSettings,
-}
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibCtrl {
- // Mixer control to get/set rdc value.
- pub rdc_ctrl: String,
- // Mixer control to get/set ambient temperature value.
- pub temp_ctrl: String,
- // Mixer control to trigger calibration.
- pub calib_ctrl: String,
- // Mixer control to adjust volume.
- pub volume_ctrl: String,
-}
-
-/// `AmpCalibSettings` includes the settings needed for amplifier calibration.
-#[derive(Debug, Default, PartialEq, Deserialize, Clone)]
-pub struct AmpCalibSettings {
- // Mixer control to get/set rdc value.
- pub controls: Vec<AmpCalibCtrl>,
- // Path of the dsm_param.bin file.
- pub dsm_param: String,
-}
-
-impl AmpCalibSettings {
- /// Returns the number of channels.
- pub fn num_channels(&self) -> usize {
- self.controls.len()
- }
-}
-
-impl DeviceSettings {
- /// Creates a `DeviceSettings` from a yaml str.
- pub fn from_yaml_str(conf: &str) -> Result<DeviceSettings> {
- let settings: DeviceSettings = serde_yaml::from_str(conf)
- .map_err(|e| Error::DeserializationFailed("DeviceSettings".to_owned(), e))?;
- Ok(settings)
- }
-}
diff --git a/sound_card_init/dsm/Cargo.lock b/sound_card_init/dsm/Cargo.lock
deleted file mode 100644
index 411c7527..00000000
--- a/sound_card_init/dsm/Cargo.lock
+++ /dev/null
@@ -1,229 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-[[package]]
-name = "alsa-sys"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "644d308f5822c2b39fba5a6d850f74c208bf73c61d1d2dfad62505d6960e4977"
-dependencies = [
- "libc",
- "pkg-config",
-]
-
-[[package]]
-name = "assertions"
-version = "0.1.0"
-
-[[package]]
-name = "audio_streams"
-version = "0.1.0"
-dependencies = [
- "sync",
- "sys_util",
-]
-
-[[package]]
-name = "cras-sys"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "data_model",
-]
-
-[[package]]
-name = "cros_alsa"
-version = "0.1.0"
-dependencies = [
- "alsa-sys",
- "libc",
- "remain",
- "sys_util",
-]
-
-[[package]]
-name = "data_model"
-version = "0.1.0"
-dependencies = [
- "assertions",
-]
-
-[[package]]
-name = "dtoa"
-version = "0.4.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
-
-[[package]]
-name = "libc"
-version = "0.2.69"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
-
-[[package]]
-name = "libcras"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cras-sys",
- "data_model",
- "libc",
- "sys_util",
-]
-
-[[package]]
-name = "linked-hash-map"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
-
-[[package]]
-name = "max98390d"
-version = "0.1.0"
-dependencies = [
- "audio_streams",
- "cros_alsa",
- "libcras",
- "remain",
- "serde",
- "serde_yaml",
- "sound_card_util",
- "sys_util",
-]
-
-[[package]]
-name = "pkg-config"
-version = "0.3.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
-
-[[package]]
-name = "poll_token_derive"
-version = "0.1.0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
-dependencies = [
- "proc-macro2",
-]
-
-[[package]]
-name = "remain"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99c861227fc40c8da6fdaa3d58144ac84c0537080a43eb1d7d45c28f88dcb888"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde"
-version = "1.0.106"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.106"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "serde_yaml"
-version = "0.8.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35"
-dependencies = [
- "dtoa",
- "linked-hash-map",
- "serde",
- "yaml-rust",
-]
-
-[[package]]
-name = "sound_card_util"
-version = "0.1.0"
-dependencies = [
- "cros_alsa",
- "remain",
- "sys_util",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "sync"
-version = "0.1.0"
-
-[[package]]
-name = "sys_util"
-version = "0.1.0"
-dependencies = [
- "data_model",
- "libc",
- "poll_token_derive",
- "sync",
- "syscall_defines",
- "tempfile",
-]
-
-[[package]]
-name = "syscall_defines"
-version = "0.1.0"
-
-[[package]]
-name = "tempfile"
-version = "3.0.7"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-
-[[package]]
-name = "yaml-rust"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
-dependencies = [
- "linked-hash-map",
-]
diff --git a/sound_card_init/dsm/Cargo.toml b/sound_card_init/dsm/Cargo.toml
deleted file mode 100644
index 280896d2..00000000
--- a/sound_card_init/dsm/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "dsm"
-version = "0.1.0"
-authors = ["The Chromium OS Authors"]
-edition = "2018"
-description = "The boot time calibration logic for smart amp"
-
-[dependencies]
-cros_alsa = "*"
-audio_streams = "*"
-libcras = "*"
-remain = "0.2.1"
-serde = { version = "1.0", features = ["derive"]}
-serde_yaml = "0.8.11"
-sys_util = "*" \ No newline at end of file
diff --git a/sound_card_init/dsm/src/datastore.rs b/sound_card_init/dsm/src/datastore.rs
deleted file mode 100644
index f0180cc2..00000000
--- a/sound_card_init/dsm/src/datastore.rs
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::fs::{remove_file, File};
-use std::io::{prelude::*, BufReader, BufWriter};
-use std::path::PathBuf;
-
-use serde::{Deserialize, Serialize};
-use sys_util::info;
-
-use crate::error::{Error, Result};
-
-/// `Datastore`, which stores and reads calibration values in yaml format.
-#[derive(Debug, Deserialize, Serialize, Copy, Clone)]
-pub enum Datastore {
- /// Indicates using values in VPD.
- UseVPD,
- DSM {
- rdc: i32,
- temp: i32,
- },
-}
-
-impl Datastore {
- /// The dir of datastore.
- pub const DATASTORE_DIR: &'static str = "/var/lib/sound_card_init";
-
- /// Creates a `Datastore` and initializes its fields from the datastore file.
- pub fn from_file(snd_card: &str, channel: usize) -> Result<Datastore> {
- let path = Self::path(snd_card, channel);
- let reader =
- BufReader::new(File::open(&path).map_err(|e| Error::FileIOFailed(path.to_owned(), e))?);
- let datastore: Datastore =
- serde_yaml::from_reader(reader).map_err(|e| Error::SerdeError(path.to_owned(), e))?;
- Ok(datastore)
- }
-
- /// Saves a `Datastore` to file.
- pub fn save(&self, snd_card: &str, channel: usize) -> Result<()> {
- let path = Self::path(snd_card, channel);
-
- let mut writer = BufWriter::new(
- File::create(&path).map_err(|e| Error::FileIOFailed(path.to_owned(), e))?,
- );
- writer
- .write(
- serde_yaml::to_string(self)
- .map_err(|e| Error::SerdeError(path.to_owned(), e))?
- .as_bytes(),
- )
- .map_err(|e| Error::FileIOFailed(path.to_owned(), e))?;
- writer
- .flush()
- .map_err(|e| Error::FileIOFailed(path.to_owned(), e))?;
- info!("update Datastore {}: {:?}", path.to_string_lossy(), self);
- Ok(())
- }
-
- /// Deletes the datastore file.
- pub fn delete(snd_card: &str, channel: usize) -> Result<()> {
- let path = Self::path(snd_card, channel);
- remove_file(&path).map_err(|e| Error::FileIOFailed(path.to_owned(), e))?;
- info!("datastore: {:#?} is deleted.", path);
- Ok(())
- }
-
- fn path(snd_card: &str, channel: usize) -> PathBuf {
- PathBuf::from(Self::DATASTORE_DIR)
- .join(snd_card)
- .join(format!("calib_{}", channel))
- }
-}
diff --git a/sound_card_init/dsm/src/error.rs b/sound_card_init/dsm/src/error.rs
deleted file mode 100644
index 4b6e8dc2..00000000
--- a/sound_card_init/dsm/src/error.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::any::Any;
-use std::error;
-use std::fmt;
-use std::io;
-use std::num::ParseIntError;
-use std::path::PathBuf;
-use std::sync::PoisonError;
-use std::time;
-
-use remain::sorted;
-
-use crate::CalibData;
-
-pub type Result<T> = std::result::Result<T, Error>;
-
-#[sorted]
-#[derive(Debug)]
-pub enum Error {
- AlsaCardError(cros_alsa::CardError),
- AlsaControlError(cros_alsa::ControlError),
- AlsaControlTLVError(cros_alsa::ControlTLVError),
- CalibrationTimeout,
- CrasClientFailed(libcras::Error),
- DeserializationFailed(String, serde_yaml::Error),
- DSMParamUpdateFailed(cros_alsa::ControlTLVError),
- FileIOFailed(PathBuf, io::Error),
- InternalSpeakerNotFound,
- InvalidDatastore,
- InvalidDSMParam,
- InvalidShutDownTime,
- InvalidTemperature(f32),
- LargeCalibrationDiff(CalibData),
- MissingDSMParam,
- MutexPoisonError,
- NewPlayStreamFailed(libcras::BoxError),
- NextPlaybackBufferFailed(libcras::BoxError),
- PlaybackFailed(io::Error),
- SerdeError(PathBuf, serde_yaml::Error),
- StartPlaybackTimeout,
- SystemTimeError(time::SystemTimeError),
- UnsupportedSoundCard(String),
- VPDParseFailed(String, ParseIntError),
- WorkerPanics(Box<dyn Any + Send + 'static>),
- ZeroPlayerIsNotRunning,
- ZeroPlayerIsRunning,
-}
-
-impl PartialEq for Error {
- // Implement eq for more Error when needed.
- fn eq(&self, other: &Error) -> bool {
- match (self, other) {
- (Error::InvalidDSMParam, Error::InvalidDSMParam) => true,
- _ => false,
- }
- }
-}
-
-impl From<cros_alsa::CardError> for Error {
- fn from(err: cros_alsa::CardError) -> Error {
- Error::AlsaCardError(err)
- }
-}
-
-impl From<cros_alsa::ControlError> for Error {
- fn from(err: cros_alsa::ControlError) -> Error {
- Error::AlsaControlError(err)
- }
-}
-
-impl From<cros_alsa::ControlTLVError> for Error {
- fn from(err: cros_alsa::ControlTLVError) -> Error {
- Error::AlsaControlTLVError(err)
- }
-}
-
-impl<T> From<PoisonError<T>> for Error {
- fn from(_: PoisonError<T>) -> Error {
- Error::MutexPoisonError
- }
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- AlsaCardError(e) => write!(f, "AlsaCardError: {}", e),
- AlsaControlError(e) => write!(f, "AlsaControlError: {}", e),
- AlsaControlTLVError(e) => write!(f, "AlsaControlTLVError: {}", e),
- CalibrationTimeout => write!(f, "calibration is not finished in time"),
- DSMParamUpdateFailed(e) => write!(f, "failed to update DsmParam, err: {}", e),
- CrasClientFailed(e) => write!(f, "failed to create cras client: {}", e),
- DeserializationFailed(file_path, e) => {
- write!(f, "failed to parse {}: {}", file_path, e)
- }
- FileIOFailed(file_path, e) => write!(f, "{:#?}: {}", file_path, e),
- InvalidShutDownTime => write!(f, "invalid shutdown time"),
- InternalSpeakerNotFound => write!(f, "internal speaker is not found in cras"),
- InvalidTemperature(temp) => write!(
- f,
- "invalid calibration temperature: {}, and there is no datastore",
- temp
- ),
- InvalidDatastore => write!(f, "invalid datastore format"),
- InvalidDSMParam => write!(f, "invalid dsm param from kcontrol"),
- LargeCalibrationDiff(calib) => {
- write!(f, "calibration difference is too large, calib: {:?}", calib)
- }
- MissingDSMParam => write!(f, "missing dsm_param.bin"),
- MutexPoisonError => write!(f, "mutex is poisoned"),
- NewPlayStreamFailed(e) => write!(f, "{}", e),
- NextPlaybackBufferFailed(e) => write!(f, "{}", e),
- PlaybackFailed(e) => write!(f, "{}", e),
- SerdeError(file_path, e) => write!(f, "{:?}: {}", file_path, e),
- StartPlaybackTimeout => write!(f, "playback is not started in time"),
- SystemTimeError(e) => write!(f, "{}", e),
- UnsupportedSoundCard(name) => write!(f, "unsupported sound card: {}", name),
- VPDParseFailed(file_path, e) => write!(f, "failed to parse vpd {}: {}", file_path, e),
- WorkerPanics(e) => write!(f, "run_play_zero_worker panics: {:#?}", e),
- ZeroPlayerIsNotRunning => write!(f, "zero player is not running"),
- ZeroPlayerIsRunning => write!(f, "zero player is running"),
- }
- }
-}
diff --git a/sound_card_init/dsm/src/lib.rs b/sound_card_init/dsm/src/lib.rs
deleted file mode 100644
index 0b3ec64c..00000000
--- a/sound_card_init/dsm/src/lib.rs
+++ /dev/null
@@ -1,335 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `dsm` crate implements the required initialization workflows for smart amps.
-
-mod datastore;
-mod error;
-pub mod utils;
-mod vpd;
-mod zero_player;
-
-use std::{
- thread,
- time::{Duration, SystemTime, UNIX_EPOCH},
-};
-
-use libcras::{CrasClient, CrasNodeType};
-use sys_util::{error, info};
-
-use crate::datastore::Datastore;
-pub use crate::error::{Error, Result};
-use crate::utils::{run_time, shutdown_time};
-use crate::vpd::VPD;
-pub use crate::zero_player::ZeroPlayer;
-
-#[derive(Debug, Clone, Copy)]
-/// `CalibData` represents the calibration data.
-pub struct CalibData {
- /// The DC resistance of the speaker is DSM unit.
- pub rdc: i32,
- /// The ambient temperature in celsius unit at which the rdc is measured.
- pub temp: f32,
-}
-
-/// `TempConverter` converts the temperature value between celsius and unit in VPD::dsm_calib_temp.
-pub struct TempConverter {
- vpd_to_celsius: fn(i32) -> f32,
- celsius_to_vpd: fn(f32) -> i32,
-}
-
-impl Default for TempConverter {
- fn default() -> Self {
- let vpd_to_celsius = |x: i32| x as f32;
- let celsius_to_vpd = |x: f32| x.round() as i32;
- Self {
- vpd_to_celsius,
- celsius_to_vpd,
- }
- }
-}
-
-impl TempConverter {
- /// Creates a `TempConverter`
- ///
- /// # Arguments
- ///
- /// * `vpd_to_celsius` - function to convert VPD::dsm_calib_temp to celsius unit`
- /// * `celsius_to_vpd` - function to convert celsius unit to VPD::dsm_calib_temp`
- /// # Results
- ///
- /// * `TempConverter` - it converts the temperature value between celsius and unit in VPD::dsm_calib_temp.
- pub fn new(vpd_to_celsius: fn(i32) -> f32, celsius_to_vpd: fn(f32) -> i32) -> Self {
- Self {
- vpd_to_celsius,
- celsius_to_vpd,
- }
- }
-}
-
-/// `SpeakerStatus` are the possible return results of
-/// DSM::check_speaker_over_heated_workflow.
-pub enum SpeakerStatus {
- ///`SpeakerStatus::Cold` means the speakers are not overheated and the Amp can
- /// trigger the boot time calibration.
- Cold,
- /// `SpeakerStatus::Hot(Vec<CalibData>)` means the speakers may be too hot for calibration.
- /// The boot time calibration should be skipped and the Amp should use the previous
- /// calibration values returned by the enum.
- Hot(Vec<CalibData>),
-}
-
-/// `DSM`, which implements the required initialization workflows for smart amps.
-pub struct DSM {
- snd_card: String,
- num_channels: usize,
- temp_converter: TempConverter,
- rdc_to_ohm: fn(i32) -> f32,
- temp_upper_limit: f32,
- temp_lower_limit: f32,
-}
-
-impl DSM {
- const SPEAKER_COOL_DOWN_TIME: Duration = Duration::from_secs(180);
- const CALI_ERROR_UPPER_LIMIT: f32 = 0.3;
- const CALI_ERROR_LOWER_LIMIT: f32 = 0.03;
-
- /// Creates a `DSM`
- ///
- /// # Arguments
- ///
- /// * `snd_card` - `sound card name`.
- /// * `num_channels` - `number of channels`.
- /// * `rdc_to_ohm` - `fn(rdc: i32) -> f32 to convert the CalibData::rdc to ohm unit`.
- /// * `temp_upper_limit` - the high limit of the valid ambient temperature in dsm unit.
- /// * `temp_lower_limit` - the low limit of the valid ambient temperature in dsm unit.
- ///
- /// # Results
- ///
- /// * `DSM` - It implements the required initialization workflows for smart amps.
- pub fn new(
- snd_card: &str,
- num_channels: usize,
- rdc_to_ohm: fn(i32) -> f32,
- temp_upper_limit: f32,
- temp_lower_limit: f32,
- ) -> Self {
- Self {
- snd_card: snd_card.to_owned(),
- num_channels,
- rdc_to_ohm,
- temp_converter: TempConverter::default(),
- temp_upper_limit,
- temp_lower_limit,
- }
- }
-
- /// Sets self.temp_converter to the given temp_converter.
- ///
- /// # Arguments
- ///
- /// * `temp_converter` - the convert function to use.
- pub fn set_temp_converter(&mut self, temp_converter: TempConverter) {
- self.temp_converter = temp_converter;
- }
-
- /// Checks whether the speakers are overheated or not according to the previous shutdown time.
- /// The boot time calibration should be skipped when the speakers may be too hot
- /// and the Amp should use the previous calibration value returned by the
- /// SpeakerStatus::Hot(Vec<CalibData>).
- ///
- /// # Results
- ///
- /// * `SpeakerStatus::Cold` - which means the speakers are not overheated and the Amp can
- /// trigger the boot time calibration.
- /// * `SpeakerStatus::Hot(Vec<CalibData>)` - when the speakers may be too hot. The boot
- /// time calibration should be skipped and the Amp should use the previous calibration values
- /// returned by the enum.
- ///
- /// # Errors
- ///
- /// * The speakers are overheated and there are no previous calibration values stored.
- /// * Cannot determine whether the speakers are overheated as previous shutdown time record is
- /// invalid.
- pub fn check_speaker_over_heated_workflow(&self) -> Result<SpeakerStatus> {
- if self.is_first_boot() {
- return Ok(SpeakerStatus::Cold);
- }
- match self.is_speaker_over_heated() {
- Ok(overheated) => {
- if overheated {
- let calib: Vec<CalibData> = (0..self.num_channels)
- .map(|ch| -> Result<CalibData> { self.get_previous_calibration_value(ch) })
- .collect::<Result<Vec<CalibData>>>()?;
- info!("the speakers are hot, the boot time calibration should be skipped");
- return Ok(SpeakerStatus::Hot(calib));
- }
- Ok(SpeakerStatus::Cold)
- }
- Err(err) => {
- // We cannot assume the speakers are not replaced or not overheated
- // when the shutdown time file is invalid; therefore we can not use the datastore
- // value anymore and we can not trigger boot time calibration.
- for ch in 0..self.num_channels {
- if let Err(e) = Datastore::delete(&self.snd_card, ch) {
- error!("error delete datastore: {}", e);
- }
- }
- Err(err)
- }
- }
- }
-
- /// Decides a good calibration value and updates the stored value according to the following
- /// logic:
- /// * Returns the previous value if the ambient temperature is not within a valid range.
- /// * Returns Error::LargeCalibrationDiff if rdc difference is larger than
- /// `CALI_ERROR_UPPER_LIMIT`.
- /// * Returns the previous value if the rdc difference is smaller than `CALI_ERROR_LOWER_LIMIT`.
- /// * Returns the boot time calibration value and updates the datastore value if the rdc.
- /// difference is between `CALI_ERROR_UPPER_LIMIT` and `CALI_ERROR_LOWER_LIMIT`.
- ///
- /// # Arguments
- ///
- /// * `card` - `&Card`.
- /// * `channel` - `channel number`.
- /// * `calib_data` - `boot time calibrated data`.
- ///
- /// # Results
- ///
- /// * `CalibData` - the calibration data to be applied according to the deciding logic.
- ///
- /// # Errors
- ///
- /// * VPD does not exist.
- /// * rdc difference is larger than `CALI_ERROR_UPPER_LIMIT`.
- /// * Failed to update Datastore.
- pub fn decide_calibration_value_workflow(
- &self,
- channel: usize,
- calib_data: CalibData,
- ) -> Result<CalibData> {
- if calib_data.temp < self.temp_lower_limit || calib_data.temp > self.temp_upper_limit {
- info!("invalid temperature: {}.", calib_data.temp);
- return self
- .get_previous_calibration_value(channel)
- .map_err(|_| Error::InvalidTemperature(calib_data.temp));
- }
- let (datastore_exist, previous_calib) = match self.get_previous_calibration_value(channel) {
- Ok(previous_calib) => (true, previous_calib),
- Err(e) => {
- info!("{}, use vpd as previous calibration value", e);
- (false, self.get_vpd_calibration_value(channel)?)
- }
- };
-
- let diff = {
- let calib_rdc_ohm = (self.rdc_to_ohm)(calib_data.rdc);
- let previous_rdc_ohm = (self.rdc_to_ohm)(previous_calib.rdc);
- (calib_rdc_ohm - previous_rdc_ohm) / previous_rdc_ohm
- };
- if diff > Self::CALI_ERROR_UPPER_LIMIT {
- Err(Error::LargeCalibrationDiff(calib_data))
- } else if diff < Self::CALI_ERROR_LOWER_LIMIT {
- if !datastore_exist {
- Datastore::UseVPD.save(&self.snd_card, channel)?;
- }
- Ok(previous_calib)
- } else {
- Datastore::DSM {
- rdc: calib_data.rdc,
- temp: (self.temp_converter.celsius_to_vpd)(calib_data.temp),
- }
- .save(&self.snd_card, channel)?;
- Ok(calib_data)
- }
- }
-
- /// Gets the calibration values from vpd.
- ///
- /// # Results
- ///
- /// * `Vec<CalibData>` - the calibration values in vpd.
- ///
- /// # Errors
- ///
- /// * Failed to read vpd.
- pub fn get_all_vpd_calibration_value(&self) -> Result<Vec<CalibData>> {
- (0..self.num_channels)
- .map(|ch| self.get_vpd_calibration_value(ch))
- .collect::<Result<Vec<_>>>()
- }
-
- /// Blocks until the internal speakers are ready.
- ///
- /// # Errors
- ///
- /// * Failed to wait the internal speakers to be ready.
- pub fn wait_for_speakers_ready(&self) -> Result<()> {
- let find_speaker = || -> Result<()> {
- let cras_client = CrasClient::new().map_err(Error::CrasClientFailed)?;
- let _node = cras_client
- .output_nodes()
- .find(|node| node.node_type == CrasNodeType::CRAS_NODE_TYPE_INTERNAL_SPEAKER)
- .ok_or(Error::InternalSpeakerNotFound)?;
- Ok(())
- };
- // TODO(b/155007305): Implement cras_client.wait_node_change and use it here.
- const RETRY: usize = 3;
- const RETRY_INTERVAL: Duration = Duration::from_millis(500);
- for _ in 0..RETRY {
- match find_speaker() {
- Ok(_) => return Ok(()),
- Err(e) => error!("retry on finding speaker: {}", e),
- };
- thread::sleep(RETRY_INTERVAL);
- }
- Err(Error::InternalSpeakerNotFound)
- }
-
- fn is_first_boot(&self) -> bool {
- !run_time::exists(&self.snd_card)
- }
-
- // If (Current time - the latest CRAS shutdown time) < cool_down_time, we assume that
- // the speakers may be overheated.
- fn is_speaker_over_heated(&self) -> Result<bool> {
- let last_run = run_time::from_file(&self.snd_card)?;
- let last_shutdown = shutdown_time::from_file()?;
- if last_shutdown < last_run {
- return Err(Error::InvalidShutDownTime);
- }
-
- let now = SystemTime::now()
- .duration_since(UNIX_EPOCH)
- .map_err(Error::SystemTimeError)?;
-
- let elapsed = now
- .checked_sub(last_shutdown)
- .ok_or(Error::InvalidShutDownTime)?;
-
- if elapsed < Self::SPEAKER_COOL_DOWN_TIME {
- return Ok(true);
- }
- Ok(false)
- }
-
- fn get_previous_calibration_value(&self, ch: usize) -> Result<CalibData> {
- let sci_calib = Datastore::from_file(&self.snd_card, ch)?;
- match sci_calib {
- Datastore::UseVPD => self.get_vpd_calibration_value(ch),
- Datastore::DSM { rdc, temp } => Ok(CalibData {
- rdc,
- temp: (self.temp_converter.vpd_to_celsius)(temp),
- }),
- }
- }
-
- fn get_vpd_calibration_value(&self, channel: usize) -> Result<CalibData> {
- let vpd = VPD::new(channel)?;
- Ok(CalibData {
- rdc: vpd.dsm_calib_r0,
- temp: (self.temp_converter.vpd_to_celsius)(vpd.dsm_calib_temp),
- })
- }
-}
diff --git a/sound_card_init/dsm/src/utils.rs b/sound_card_init/dsm/src/utils.rs
deleted file mode 100644
index 64f6c972..00000000
--- a/sound_card_init/dsm/src/utils.rs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! It contains common utils shared within sound_card_init.
-#![deny(missing_docs)]
-
-use std::fs::File;
-use std::io::{prelude::*, BufReader, BufWriter};
-use std::path::PathBuf;
-use std::time::Duration;
-
-use crate::datastore::Datastore;
-use crate::error::{Error, Result};
-
-fn duration_from_file(path: &PathBuf) -> Result<Duration> {
- let reader =
- BufReader::new(File::open(&path).map_err(|e| Error::FileIOFailed(path.clone(), e))?);
- serde_yaml::from_reader(reader).map_err(|e| Error::SerdeError(path.clone(), e))
-}
-
-/// The utils to parse CRAS shutdown time file.
-pub mod shutdown_time {
- use super::*;
- // The path of CRAS shutdown time file.
- const SHUTDOWN_TIME_FILE: &str = "/var/lib/cras/stop";
-
- /// Reads the unix time from CRAS shutdown time file.
- pub fn from_file() -> Result<Duration> {
- duration_from_file(&PathBuf::from(SHUTDOWN_TIME_FILE))
- }
-}
-
-/// The utils to create and parse sound_card_init run time file.
-pub mod run_time {
- use std::time::SystemTime;
-
- use super::*;
- // The filename of sound_card_init run time file.
- const RUN_TIME_FILE: &str = "run";
-
- /// Returns the sound_card_init run time file existence.
- pub fn exists(snd_card: &str) -> bool {
- run_time_file(snd_card).exists()
- }
-
- /// Reads the unix time from sound_card_init run time file.
- pub fn from_file(snd_card: &str) -> Result<Duration> {
- duration_from_file(&run_time_file(snd_card))
- }
-
- /// Saves the current unix time to sound_card_init run time file.
- pub fn now_to_file(snd_card: &str) -> Result<()> {
- match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
- Ok(t) => to_file(snd_card, t),
- Err(e) => Err(Error::SystemTimeError(e)),
- }
- }
-
- /// Saves the unix time to sound_card_init run time file.
- pub fn to_file(snd_card: &str, duration: Duration) -> Result<()> {
- let path = run_time_file(snd_card);
- let mut writer =
- BufWriter::new(File::create(&path).map_err(|e| Error::FileIOFailed(path.clone(), e))?);
- writer
- .write_all(
- serde_yaml::to_string(&duration)
- .map_err(|e| Error::SerdeError(path.clone(), e))?
- .as_bytes(),
- )
- .map_err(|e| Error::FileIOFailed(path.clone(), e))?;
- writer
- .flush()
- .map_err(|e| Error::FileIOFailed(path.clone(), e))?;
- Ok(())
- }
-
- fn run_time_file(snd_card: &str) -> PathBuf {
- PathBuf::from(Datastore::DATASTORE_DIR)
- .join(snd_card)
- .join(RUN_TIME_FILE)
- }
-}
diff --git a/sound_card_init/dsm/src/vpd.rs b/sound_card_init/dsm/src/vpd.rs
deleted file mode 100644
index b00864cc..00000000
--- a/sound_card_init/dsm/src/vpd.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::fs::File;
-use std::io::prelude::*;
-use std::io::BufReader;
-use std::path::PathBuf;
-
-use crate::error::{Error, Result};
-
-const VPD_DIR: &str = "/sys/firmware/vpd/ro/vpdfile";
-
-/// `VPD`, which represents the amplifier factory calibration values.
-#[derive(Default, Debug)]
-pub struct VPD {
- pub dsm_calib_r0: i32,
- pub dsm_calib_temp: i32,
-}
-
-impl VPD {
- /// Creates a `VPD` and initializes its fields from VPD_DIR/dsm_calib_r0_{channel}.
- /// # Arguments
- ///
- /// * `channel` - channel number.
- pub fn new(channel: usize) -> Result<VPD> {
- let mut vpd: VPD = Default::default();
- vpd.dsm_calib_r0 = read_vpd_files(&format!("dsm_calib_r0_{}", channel))?;
- vpd.dsm_calib_temp = read_vpd_files(&format!("dsm_calib_temp_{}", channel))?;
- Ok(vpd)
- }
-}
-
-fn read_vpd_files(file: &str) -> Result<i32> {
- let path = PathBuf::from(VPD_DIR).with_file_name(file);
- let io_err = |e| Error::FileIOFailed(path.to_owned(), e);
- let mut reader = BufReader::new(File::open(&path).map_err(io_err)?);
- let mut line = String::new();
- reader.read_line(&mut line).map_err(io_err)?;
- line.parse::<i32>()
- .map_err(|e| Error::VPDParseFailed(path.to_string_lossy().to_string(), e))
-}
diff --git a/sound_card_init/dsm/src/zero_player.rs b/sound_card_init/dsm/src/zero_player.rs
deleted file mode 100644
index 441f7ffa..00000000
--- a/sound_card_init/dsm/src/zero_player.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-use std::io::Write;
-use std::sync::atomic::{AtomicBool, Ordering};
-use std::sync::{Arc, Condvar, Mutex};
-use std::thread;
-use std::thread::JoinHandle;
-use std::time::Duration;
-
-use audio_streams::SampleFormat;
-use libcras::{CrasClient, CrasNodeType};
-use sys_util::error;
-
-use crate::error::{Error, Result};
-
-/// `ZeroPlayer` provides the functionality to play zeros sample in the background thread.
-#[derive(Default)]
-pub struct ZeroPlayer {
- thread_info: Option<PlayZeroWorkerInfo>,
-}
-
-impl Drop for ZeroPlayer {
- fn drop(&mut self) {
- if self.thread_info.is_some() {
- if let Err(e) = self.stop() {
- error!("{}", e);
- }
- }
- }
-}
-
-impl ZeroPlayer {
- /// It takes about 400 ms to get CRAS_NODE_TYPE_INTERNAL_SPEAKER during the boot time.
- const TIMEOUT: Duration = Duration::from_millis(1000);
-
- /// Returns whether the ZeroPlayer is running.
- pub fn running(&self) -> bool {
- self.thread_info.is_some()
- }
-
- /// Starts to play zeros for at most `max_playback_time`.
- /// This function blocks and returns until playback has started for `min_playback_time`.
- /// This function must be called when self.running() returns false.
- ///
- /// # Arguments
- ///
- /// * `min_playback_time` - It blocks and returns until playback has started for
- /// `min_playback_time`.
- ///
- /// # Errors
- ///
- /// * If it's called when the `ZeroPlayer` is already running.
- /// * Failed to find internal speakers.
- /// * Failed to start the background thread.
- pub fn start(&mut self, min_playback_time: Duration) -> Result<()> {
- if self.running() {
- return Err(Error::ZeroPlayerIsRunning);
- }
- self.thread_info = Some(PlayZeroWorkerInfo::new(min_playback_time));
- if let Some(thread_info) = &mut self.thread_info {
- // Block until playback of zeros has started for min_playback_time or timeout.
- let (lock, cvar) = &*(thread_info.ready);
- let result = cvar.wait_timeout_while(
- lock.lock()?,
- min_playback_time + ZeroPlayer::TIMEOUT,
- |&mut is_ready| !is_ready,
- )?;
- if result.1.timed_out() {
- return Err(Error::StartPlaybackTimeout);
- }
- }
- Ok(())
- }
-
- /// Stops playing zeros in the background thread.
- /// This function must be called when self.running() returns true.
- ///
- /// # Errors
- ///
- /// * If it's called again when the `ZeroPlayer` is not running.
- /// * Failed to play zeros to internal speakers via CRAS client.
- /// * Failed to join the background thread.
- pub fn stop(&mut self) -> Result<()> {
- match self.thread_info.take() {
- Some(mut thread_info) => Ok(thread_info.destroy()?),
- None => Err(Error::ZeroPlayerIsNotRunning),
- }
- }
-}
-
-// Audio thread book-keeping data
-struct PlayZeroWorkerInfo {
- thread: Option<JoinHandle<Result<()>>>,
- // Uses `thread_run` to notify the background thread to stop.
- thread_run: Arc<AtomicBool>,
- // The background thread uses `ready` to notify the main thread that playback
- // of zeros has started for min_playback_time.
- ready: Arc<(Mutex<bool>, Condvar)>,
-}
-
-impl Drop for PlayZeroWorkerInfo {
- fn drop(&mut self) {
- if let Err(e) = self.destroy() {
- error!("{}", e);
- }
- }
-}
-
-impl PlayZeroWorkerInfo {
- // Spawns the PlayZeroWorker.
- fn new(min_playback_time: Duration) -> Self {
- let thread_run = Arc::new(AtomicBool::new(false));
- let ready = Arc::new((Mutex::new(false), Condvar::new()));
- let mut worker = PlayZeroWorker::new(min_playback_time, thread_run.clone(), ready.clone());
- Self {
- thread: Some(thread::spawn(move || -> Result<()> {
- worker.run()?;
- Ok(())
- })),
- thread_run,
- ready,
- }
- }
-
- // Joins the PlayZeroWorker.
- fn destroy(&mut self) -> Result<()> {
- self.thread_run.store(false, Ordering::Relaxed);
- if let Some(handle) = self.thread.take() {
- let res = handle.join().map_err(Error::WorkerPanics)?;
- return match res {
- Err(e) => Err(e),
- Ok(_) => Ok(()),
- };
- }
- Ok(())
- }
-}
-
-struct PlayZeroWorker {
- min_playback_time: Duration,
- // Uses `thread_run` to notify the background thread to stop.
- thread_run: Arc<AtomicBool>,
- // The background thread uses `ready` to notify the main thread that playback
- // of zeros has started for min_playback_time.
- ready: Arc<(Mutex<bool>, Condvar)>,
-}
-
-impl PlayZeroWorker {
- const FRAMES_PER_BUFFER: usize = 256;
- const FRAME_RATE: u32 = 48000;
- const NUM_CHANNELS: usize = 2;
- const FORMAT: SampleFormat = SampleFormat::S16LE;
-
- fn new(
- min_playback_time: Duration,
- thread_run: Arc<AtomicBool>,
- ready: Arc<(Mutex<bool>, Condvar)>,
- ) -> Self {
- Self {
- min_playback_time,
- thread_run,
- ready,
- }
- }
-
- fn run(&mut self) -> Result<()> {
- let mut cras_client = CrasClient::new().map_err(Error::CrasClientFailed)?;
- // TODO(b/155007305): Implement cras_client.wait_node_change and use it here.
- let node = cras_client
- .output_nodes()
- .find(|node| node.node_type == CrasNodeType::CRAS_NODE_TYPE_INTERNAL_SPEAKER)
- .ok_or(Error::InternalSpeakerNotFound)?;
- let local_buffer =
- vec![0u8; Self::FRAMES_PER_BUFFER * Self::NUM_CHANNELS * Self::FORMAT.sample_bytes()];
- let min_playback_iterations = (Self::FRAME_RATE
- * self.min_playback_time.as_millis() as u32)
- / Self::FRAMES_PER_BUFFER as u32
- / 1000;
- let (_control, mut stream) = cras_client
- .new_pinned_playback_stream(
- node.iodev_index,
- Self::NUM_CHANNELS,
- Self::FORMAT,
- Self::FRAME_RATE,
- Self::FRAMES_PER_BUFFER,
- )
- .map_err(|e| Error::NewPlayStreamFailed(e))?;
-
- let mut iter = 0;
- self.thread_run.store(true, Ordering::Relaxed);
- while self.thread_run.load(Ordering::Relaxed) {
- let mut buffer = stream
- .next_playback_buffer()
- .map_err(|e| Error::NextPlaybackBufferFailed(e))?;
- let _write_frames = buffer.write(&local_buffer).map_err(Error::PlaybackFailed)?;
-
- // Notifies the main thread that playback of zeros has started for min_playback_time.
- if iter == min_playback_iterations {
- let (lock, cvar) = &*self.ready;
- let mut is_ready = lock.lock()?;
- *is_ready = true;
- cvar.notify_one();
- }
- iter += 1;
- }
- Ok(())
- }
-}
diff --git a/sound_card_init/seccomp/sound_card_init-seccomp-amd64.policy b/sound_card_init/seccomp/sound_card_init-seccomp-amd64.policy
deleted file mode 100644
index d06f225e..00000000
--- a/sound_card_init/seccomp/sound_card_init-seccomp-amd64.policy
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-access: 1
-arch_prctl: 1
-bind: 1
-brk: 1
-clone: 1
-close: 1
-connect: 1
-dup2: 1
-dup: 1
-epoll_create1: 1
-epoll_ctl: 1
-epoll_wait: 1
-execve: 1
-exit: 1
-exit_group: 1
-fcntl: 1
-fstat: 1
-futex: 1
-getcwd: 1
-getdents: 1
-getdents64: 1
-getegid: 1
-geteuid: 1
-getgid: 1
-getgroups: 1
-getpgid: 1
-getpgrp: 1
-getpid: 1
-getppid: 1
-getpriority: 1
-getrandom: 1
-getresgid: 1
-getresuid: 1
-getsid: 1
-getsockname: 1
-getuid: 1
-ioctl: arg1 == 0x5401 || arg1 == 0xc4c85512 || arg1 == 0x540f || arg1 == 0x80045500 || arg1 == 0xc4c85513 || arg1 == 0x81785501 || arg1 == 0x5413 || arg1 == 0xc1105511 || arg1 == 0x81785501 || arg1 == 0x80045500 || arg1 == 0xc008551a || arg1 == 0xc4c85512 || arg1 == 0xc008551b || arg1 == 0xc1105511
-lseek: 1
-madvise: 1
-mmap: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
-mprotect: arg2 in ~PROT_EXEC || arg2 in ~PROT_WRITE
-munmap: 1
-nanosleep: 1
-clock_nanosleep: 1
-openat: 1
-pipe2: 1
-ppoll: 1
-prctl: arg0 == 0x3 || arg0 == 0x4
-prlimit64: 1
-read: 1
-recvfrom: 1
-recvmsg: 1
-restart_syscall: 1
-rt_sigaction: 1
-rt_sigprocmask: 1
-rt_sigreturn: 1
-sched_getaffinity: 1
-sched_yield: 1
-sendmsg: 1
-sendto: 1
-set_robust_list: 1
-set_tid_address: 1
-setgid: 1
-setgroups: 1
-setpriority: 1
-setresgid: 1
-setresuid: 1
-setuid: 1
-sigaltstack: 1
-socket: arg0 == 0x10 || arg0 == 0x1
-socketpair: 1
-stat: 1
-statx: 1
-umask: 1
-uname: 1
-unlink: 1
-wait4: 1
-write: 1
diff --git a/sound_card_init/sound_card_init.conf b/sound_card_init/sound_card_init.conf
deleted file mode 100644
index 40bc88f8..00000000
--- a/sound_card_init/sound_card_init.conf
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2020 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Installed by sound_card_init package.
-# sound_card_init upstart job.
-# sound_card_init is started by /lib/udev/rules.d/99-sound_card_init.rules
-
-description "Chrome OS sound card initializer"
-author "chromium-os-dev@chromium.org"
-
-# sound_card_init is a short-running process, but we don't start it as
-# a task job, because sound_card_init needs the sound card to be ready in
-# CRAS therefore we do not want to block the udev rule processing.
-
-# Make the task killable, because if it has a leak it's better to
-# restart it than to OOM-panic.
-oom score 0
-
-# SOUND_CARD_ID is provided by /lib/udev/rules.d/99-sound_card_init.rules.
-import SOUND_CARD_ID
-
-pre-start script
- if ! echo "${SOUND_CARD_ID}" | grep -Eq "^[a-zA-Z0-9]+$"; then
- logger -t "${UPSTART_JOB}" \
- "Invalid SOUND_CARD_ID supplied"
- exit 1
- else
- mkdir -m 0755 -p /var/lib/sound_card_init/"${SOUND_CARD_ID}"
- chown -R sound_card_init:sound_card_init /var/lib/sound_card_init
- fi
-end script
-
-
-script
- CONFIG="$(cros_config /audio/main sound-card-init-conf)"
- if [ -f /etc/sound_card_init/"${CONFIG}" ]; then
- # Here (in order) are a list of the args added:
- # --uts: Create and enter new UTS namespace (hostname/NIS domain name).
- # -e: doesn't need network access.
- # -l: process doesn't use SysV shared memory or IPC.
- # -N: doesn't need to modify control groups settings.
- # -v: run inside a new VFS namespace.
- # -p -r: process doesn't need to access other processes in the system.
- # -n: process doesn't need new privileges.
- # -P: set /mnt/empty as the root fs.
- # -b: bind /
- # -k: Get a writeable and empty /run tmpfs path.
- # -b: need /run/cras to connect cras.
- # -b: need /dev to send ioctls to the system's block devices.
- # -k: empty /sys tmpfs path.
- # -b: need /sys/firmware/vpd/ro/ access to read the default calibration
- # value in vpd.
- # -k: get a writeable and empty /var tmpfs path.
- # -b: need /var/lib/sound_card_init/$SOUND_CARD_ID writable access for
- # datastore update.
- # -b: need /var/lib/cras readable
- exec minijail0 \
- --uts \
- -e \
- -l \
- -N \
- -v \
- -p -r \
- -n \
- -P /mnt/empty \
- -b / \
- -k 'tmpfs,/run,tmpfs,MS_NODEV|MS_NOEXEC|MS_NOSUID,mode=755,size=10M' \
- -b /run/cras \
- -b /dev \
- -k 'tmpfs,/sys,tmpfs,MS_NODEV|MS_NOEXEC|MS_NOSUID,mode=755,size=10M' \
- -b /sys/firmware/vpd/ro/ \
- -k 'tmpfs,/var,tmpfs,MS_NODEV|MS_NOEXEC|MS_NOSUID,mode=755,size=10M' \
- -b /var/lib/sound_card_init/"${SOUND_CARD_ID}"/,,1 \
- -b /var/lib/cras/ \
- -u sound_card_init -g sound_card_init -G \
- -S /usr/share/policy/sound_card_init-seccomp.policy \
- /usr/bin/sound_card_init "--id=${SOUND_CARD_ID}" "--conf=${CONFIG}"
- fi
-end script \ No newline at end of file
diff --git a/sound_card_init/src/main.rs b/sound_card_init/src/main.rs
deleted file mode 100644
index 806b7d53..00000000
--- a/sound_card_init/src/main.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2020 The Chromium OS Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//! `sound_card_init` is an user space binary to perform sound card initialization during boot time.
-//!
-//!
-//! # Arguments
-//!
-//! * `sound_card_id` - The sound card name, ex: sofcmlmax98390d.
-//!
-//! Given the `sound_card_id`, this binary parses the CONF_DIR/<sound_card_id>.yaml to perform per sound card initialization.
-//! The upstart job of `sound_card_init` is started by the udev event specified in /lib/udev/rules.d/99-sound_card_init.rules.
-#![deny(missing_docs)]
-use std::env;
-use std::error;
-use std::fmt;
-use std::process;
-use std::string::String;
-
-use getopts::Options;
-use remain::sorted;
-use sys_util::{error, info, syslog};
-
-use amp::AmpBuilder;
-use dsm::utils::run_time;
-
-type Result<T> = std::result::Result<T, Error>;
-
-#[derive(Default)]
-struct Args {
- pub sound_card_id: String,
- pub conf: String,
-}
-
-#[sorted]
-#[derive(Debug)]
-enum Error {
- MissingOption(String),
- ParseArgsFailed(getopts::Fail),
-}
-
-impl error::Error for Error {}
-
-impl fmt::Display for Error {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use Error::*;
- match self {
- MissingOption(option) => write!(f, "missing required option: {}", option),
- ParseArgsFailed(e) => write!(f, "parse_args failed: {}", e),
- }
- }
-}
-
-fn print_usage(opts: &Options) {
- let brief = "Usage: sound_card_init [options]".to_owned();
- print!("{}", opts.usage(&brief));
-}
-
-fn parse_args() -> Result<Args> {
- let mut opts = Options::new();
- opts.optopt("", "id", "sound card id", "ID");
- opts.optopt(
- "",
- "conf",
- "the config file name. It should be $(cros_config /audio/main sound-card-init-conf)",
- "CONFIG_NAME",
- );
- opts.optflag("h", "help", "print help menu");
- let matches = opts
- .parse(&env::args().collect::<Vec<_>>()[1..])
- .map_err(|e| {
- print_usage(&opts);
- Error::ParseArgsFailed(e)
- })?;
-
- if matches.opt_present("h") {
- print_usage(&opts);
- process::exit(0);
- }
-
- let sound_card_id = matches
- .opt_str("id")
- .ok_or_else(|| Error::MissingOption("id".to_owned()))
- .map_err(|e| {
- print_usage(&opts);
- e
- })?;
-
- let conf = matches
- .opt_str("conf")
- .ok_or_else(|| Error::MissingOption("conf".to_owned()))
- .map_err(|e| {
- print_usage(&opts);
- e
- })?;
-
- Ok(Args {
- sound_card_id,
- conf,
- })
-}
-
-/// Parses the CONF_DIR/${args.conf}.yaml and starts the boot time calibration.
-fn sound_card_init(args: &Args) -> std::result::Result<(), Box<dyn error::Error>> {
- info!("sound_card_id: {}, conf:{}", args.sound_card_id, args.conf);
- AmpBuilder::new(&args.sound_card_id, &args.conf)
- .build()?
- .boot_time_calibration()?;
-
- Ok(())
-}
-
-fn main() {
- syslog::init().expect("failed to initialize syslog");
- let args = match parse_args() {
- Ok(args) => args,
- Err(e) => {
- error!("failed to parse arguments: {}", e);
- return;
- }
- };
-
- match sound_card_init(&args) {
- Ok(_) => info!("sound_card_init finished successfully."),
- Err(e) => error!("sound_card_init: {}", e),
- }
-
- if let Err(e) = run_time::now_to_file(&args.sound_card_id) {
- error!("failed to create sound_card_init run time file: {}", e);
- }
-}
diff --git a/ucm-config/for_all_boards/Pixel USB-C earbuds/Pixel USB-C earbuds.conf b/ucm-config/bolt/HDA Intel PCH/HDA Intel PCH.conf
index 4166632c..1cd5b42a 100644
--- a/ucm-config/for_all_boards/Pixel USB-C earbuds/Pixel USB-C earbuds.conf
+++ b/ucm-config/bolt/HDA Intel PCH/HDA Intel PCH.conf
@@ -1,4 +1,4 @@
-Comment "Pixel USB-C earbuds"
+Comment "Bolt internal card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/bolt/HDA Intel PCH/HiFi.conf b/ucm-config/bolt/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..2ab99c55
--- /dev/null
+++ b/ucm-config/bolt/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,67 @@
+SectionVerb {
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='HP/Speaker Playback Switch' off"
+ cset "name='HP/Speaker Auto Detect Playback Switch' off"
+ cset "name='PlayEnhancement Playback Switch' on"
+ cset "name='Surround Playback Switch' on"
+ cset "name='Crystalizer Playback Switch' off"
+ cset "name='Dialog Plus Playback Switch' off"
+ cset "name='Smart Volume Playback Switch' on"
+ cset "name='X-Bass Playback Switch' on"
+ cset "name='Equalizer Playback Switch' off"
+ cset "name='Echo Cancellation Capture Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 99"
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='Analog-Mic2 Capture Volume' 90"
+ cset "name='Analog-Mic2 Capture Switch' on"
+ cset "name='Mic1-Boost (30dB) Capture Switch' on"
+ cset "name='AMic1/DMic Capture Switch' off"
+ cset "name='AMic1/DMic Auto Detect Capture Switch' off"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Front Headphone Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='PlayEnhancement Playback Switch' off"
+ cset "name='HP/Speaker Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='PlayEnhancement Playback Switch' on"
+ cset "name='HP/Speaker Playback Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='AMic1/DMic Capture Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='AMic1/DMic Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/chell b/ucm-config/chell
new file mode 120000
index 00000000..1ec1f47c
--- /dev/null
+++ b/ucm-config/chell
@@ -0,0 +1 @@
+glados/ \ No newline at end of file
diff --git a/ucm-config/cid/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/cid/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..63485af9
--- /dev/null
+++ b/ucm-config/cid/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Cid internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/cid/HDA Intel PCH/HiFi.conf b/ucm-config/cid/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..6174c0b9
--- /dev/null
+++ b/ucm-config/cid/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,55 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 1"
+ cset "name='Capture Source' 0"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ DspName ""
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Playback Switch' off"
+ cset "name='Headphone Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
diff --git a/ucm-config/for_all_boards/Dell AC511 USB SoundBar/Dell AC511 USB SoundBar.conf b/ucm-config/daisy/DAISY-I2S-98090/DAISY-I2S-98090.conf
index 54913786..3ca0ff05 100644
--- a/ucm-config/for_all_boards/Dell AC511 USB SoundBar/Dell AC511 USB SoundBar.conf
+++ b/ucm-config/daisy/DAISY-I2S-98090/DAISY-I2S-98090.conf
@@ -1,4 +1,4 @@
-Comment "Dell AC511 USB SoundBar"
+Comment "Daisy internal card (Maxim 98090)"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/daisy/DAISY-I2S-98090/HiFi.conf b/ucm-config/daisy/DAISY-I2S-98090/HiFi.conf
new file mode 100644
index 00000000..54e92b3c
--- /dev/null
+++ b/ucm-config/daisy/DAISY-I2S-98090/HiFi.conf
@@ -0,0 +1,107 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:DAISYI2S98090"
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='MIC2 Mux' IN34"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Right ADC Mixer MIC2 Switch' off"
+ cset "name='Left ADC Mixer MIC2 Switch' off"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "DAISY-I2S-98090 HDMI Jack"
+ DspName ""
+ EDIDFile "/sys/devices/platform/exynos-drm/drm/card1/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:DAISYI2S98090"
+ cset "name='Left Speaker Mixer Left DAC Switch' off"
+ cset "name='Right Speaker Mixer Right DAC Switch' off"
+ ]
+ DisableSequence [
+ cdev "hw:DAISYI2S98090"
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "DAISY-I2S-98090 Headphone Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S98090"
+ cset "name='Left Speaker Mixer Left DAC Switch' off"
+ cset "name='Right Speaker Mixer Right DAC Switch' off"
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:DAISYI2S98090"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "DAISY-I2S-98090 Mic Jack"
+ CaptureControl "MIC2"
+ DefaultNodeGain "-500"
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S98090"
+
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='DMIC Mux' ADC"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:DAISYI2S98090"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Right ADC Mixer MIC2 Switch' off"
+ cset "name='Left ADC Mixer MIC2 Switch' off"
+ cset "name='MIC2 Volume' 0"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/for_all_boards/PCP-USB/PCP-USB.conf b/ucm-config/daisy/DAISY-I2S/DAISY-I2S.conf
index b4689272..0f4b5fcc 100644
--- a/ucm-config/for_all_boards/PCP-USB/PCP-USB.conf
+++ b/ucm-config/daisy/DAISY-I2S/DAISY-I2S.conf
@@ -1,4 +1,4 @@
-Comment "PCP USB Stethoscope"
+Comment "Daisy internal card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/daisy/DAISY-I2S/HiFi.conf b/ucm-config/daisy/DAISY-I2S/HiFi.conf
new file mode 100644
index 00000000..90318169
--- /dev/null
+++ b/ucm-config/daisy/DAISY-I2S/HiFi.conf
@@ -0,0 +1,142 @@
+SectionVerb {
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Headphone Volume' 13"
+ cset "name='Speaker Volume' 16"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ cset "name='Receiver Switch' on"
+ cset "name='Lineout Switch' on"
+ cset "name='MIC1 Volume' 20"
+ cset "name='MIC2 Volume' 20"
+ cset "name='MIC1 Boost Volume' 0"
+ cset "name='MIC2 Boost Volume' 1"
+ cset "name='Linein Volume' 5"
+ cset "name='ADCL Volume' 15"
+ cset "name='ADCR Volume' 15"
+ cset "name='ADCL Boost Volume' 0"
+ cset "name='ADCR Boost Volume' 0"
+ cset "name='EQ1 Mode' Default"
+ cset "name='EQ1 Switch' on"
+ cset "name='EQ2 Switch' off"
+ cset "name='Biquad1 Switch' off"
+ cset "name='Biquad2 Switch' off"
+ cset "name='DMIC1 Left Capture Switch' on"
+ cset "name='DMIC1 Right Capture Switch' on"
+ cset "name='MIC1 External Mic Switch' off"
+ cset "name='MIC2 External Mic Switch' on"
+ cset "name='DAI2 Filter Mode' Voice"
+ cset "name='DAI1 DAC Filter' Off"
+ cset "name='DAI1 Filter Mode' Music"
+ cset "name='DAI2 DAC Filter' Off"
+ cset "name='DAI3 DAC Filter' Off"
+ cset "name='Linein Mode' Stereo"
+ cset "name='Lineout Mode' Stereo"
+ cset "name='Right ADC Mixer MIC1 Switch' off"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Right ADC Mixer IN1 Switch' off"
+ cset "name='Right ADC Mixer IN2 Switch' off"
+ cset "name='Left ADC Mixer MIC1 Switch' off"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer IN1 Switch' off"
+ cset "name='Left ADC Mixer IN2 Switch' off"
+ cset "name='Right Lineout Mixer Left DAC1 Switch' off"
+ cset "name='Right Lineout Mixer Right DAC1 Switch' off"
+ cset "name='Right Lineout Mixer MIC1 Switch' off"
+ cset "name='Right Lineout Mixer MIC2 Switch' off"
+ cset "name='Right Lineout Mixer IN1 Switch' off"
+ cset "name='Right Lineout Mixer IN2 Switch' off"
+ cset "name='Left Lineout Mixer Left DAC1 Switch' off"
+ cset "name='Left Lineout Mixer Right DAC1 Switch' off"
+ cset "name='Left Lineout Mixer MIC1 Switch' off"
+ cset "name='Left Lineout Mixer MIC2 Switch' off"
+ cset "name='Left Lineout Mixer IN1 Switch' off"
+ cset "name='Left Lineout Mixer IN2 Switch' off"
+ cset "name='Receiver Mixer Left DAC1 Switch' off"
+ cset "name='Receiver Mixer Right DAC1 Switch' off"
+ cset "name='Receiver Mixer MIC1 Switch' off"
+ cset "name='Receiver Mixer MIC2 Switch' off"
+ cset "name='Receiver Mixer IN1 Switch' off"
+ cset "name='Receiver Mixer IN2 Switch' off"
+ cset "name='Right Speaker Mixer Left DAC1 Switch' off"
+ cset "name='Right Speaker Mixer Right DAC1 Switch' on"
+ cset "name='Right Speaker Mixer Mono DAC2 Switch' off"
+ cset "name='Right Speaker Mixer Mono DAC3 Switch' off"
+ cset "name='Left Speaker Mixer Left DAC1 Switch' on"
+ cset "name='Left Speaker Mixer Right DAC1 Switch' off"
+ cset "name='Left Speaker Mixer Mono DAC2 Switch' off"
+ cset "name='Left Speaker Mixer Mono DAC3 Switch' off"
+ cset "name='Right Headphone Mixer Left DAC1 Switch' off"
+ cset "name='Right Headphone Mixer Right DAC1 Switch' on"
+ cset "name='Right Headphone Mixer MIC1 Switch' off"
+ cset "name='Right Headphone Mixer MIC2 Switch' off"
+ cset "name='Right Headphone Mixer IN1 Switch' off"
+ cset "name='Right Headphone Mixer IN2 Switch' off"
+ cset "name='Left Headphone Mixer Left DAC1 Switch' on"
+ cset "name='Left Headphone Mixer Right DAC1 Switch' off"
+ cset "name='Left Headphone Mixer MIC1 Switch' off"
+ cset "name='Left Headphone Mixer MIC2 Switch' off"
+ cset "name='Left Headphone Mixer IN1 Switch' off"
+ cset "name='Left Headphone Mixer IN2 Switch' off"
+ cset "name='Linein Mux' INA"
+ cset "name='External MIC' MIC2"
+ cset "name='HDMI Playback Switch' off"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "DAISY-I2S HDMI Jack"
+ EDIDFile "/sys/devices/platform/exynos-drm/drm/card1/card1-HDMI-A-1/edid"
+ }
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "DAISY-I2S Headphone Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+ cset "name='EQ1 Switch' off"
+ cset "name='Speaker Switch' off"
+ cset "name='Left Headphone Mixer Left DAC1 Switch' on"
+ cset "name='Right Headphone Mixer Right DAC1 Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:DAISYI2S"
+ cset "name='EQ1 Mode' Default"
+ cset "name='EQ1 Switch' on"
+ cset "name='Left Speaker Mixer Left DAC1 Switch' on"
+ cset "name='Right Speaker Mixer Right DAC1 Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "DAISY-I2S Mic Jack"
+ CaptureControl "MIC2"
+ DefaultNodeGain "-500"
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='DMIC1 Left Capture Switch' off"
+ cset "name='DMIC1 Right Capture Switch' off"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Left ADC Mixer MIC2 Switch' off"
+ cset "name='Right ADC Mixer MIC2 Switch' off"
+ cset "name='DMIC1 Left Capture Switch' on"
+ cset "name='DMIC1 Right Capture Switch' on"
+ ]
+}
diff --git a/ucm-config/daisy_skate/DAISY-I2S/DAISY-I2S.conf b/ucm-config/daisy_skate/DAISY-I2S/DAISY-I2S.conf
new file mode 100644
index 00000000..bca7d631
--- /dev/null
+++ b/ucm-config/daisy_skate/DAISY-I2S/DAISY-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Skate internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/daisy_skate/DAISY-I2S/HiFi.conf b/ucm-config/daisy_skate/DAISY-I2S/HiFi.conf
new file mode 100644
index 00000000..d2a913b8
--- /dev/null
+++ b/ucm-config/daisy_skate/DAISY-I2S/HiFi.conf
@@ -0,0 +1,70 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+ cset "name='Left SPK Mixer Left DAC1 Switch' on"
+ cset "name='Right SPK Mixer Right DAC1 Switch' on"
+ cset "name='Left HP Mixer Left DAC1 Switch' on"
+ cset "name='Right HP Mixer Right DAC1 Switch' on"
+ cset "name='External MIC' MIC2"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='DAI1 Filter Mode' Music"
+ cset "name='DIGMICL Switch' on"
+ cset "name='DIGMICR Switch' on"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "DAISY-I2S HDMI Jack"
+ DspName ""
+ EDIDFile "/sys/devices/platform/exynos-drm/drm/card1/card1-HDMI-A-1/edid"
+ }
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "DAISY-I2S Headphone Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+ cset "name='EQ1 Switch' off"
+ ]
+ DisableSequence [
+ cdev "hw:DAISYI2S"
+ cset "name='EQ1 Mode' Default"
+ cset "name='EQ1 Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "DAISY-I2S Mic Jack"
+ CaptureControl "MIC2"
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='DIGMICL Switch' off"
+ cset "name='DIGMICR Switch' off"
+ ]
+
+ DisableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Left ADC Mixer MIC2 Switch' off"
+ cset "name='Right ADC Mixer MIC2 Switch' off"
+ cset "name='DIGMICL Switch' on"
+ cset "name='DIGMICR Switch' on"
+ ]
+}
diff --git a/ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HUAWEI USB-C HEADSET.conf b/ucm-config/daisy_spring/DAISY-I2S/DAISY-I2S.conf
index c1db5193..05389ee0 100644
--- a/ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HUAWEI USB-C HEADSET.conf
+++ b/ucm-config/daisy_spring/DAISY-I2S/DAISY-I2S.conf
@@ -1,4 +1,4 @@
-Comment "HUAWEI USB-C HEADSET"
+Comment "Spring internal card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/daisy_spring/DAISY-I2S/HiFi.conf b/ucm-config/daisy_spring/DAISY-I2S/HiFi.conf
new file mode 100644
index 00000000..af49a05f
--- /dev/null
+++ b/ucm-config/daisy_spring/DAISY-I2S/HiFi.conf
@@ -0,0 +1,90 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Headphone Volume' 0"
+ cset "name='Speaker Volume' 0"
+ cset "name='Receiver Volume' 0"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ cset "name='Receiver Switch' on"
+ cset "name='MIC1 Volume' 31"
+ cset "name='MIC2 Volume' 32"
+ cset "name='MIC1 Boost Volume' 0"
+ cset "name='MIC2 Boost Volume' 0"
+ cset "name='INA Volume' 7"
+ cset "name='INB Volume' 7"
+ cset "name='ADCL Volume' 0"
+ cset "name='ADCR Volume' 0"
+ cset "name='ADCL Boost Volume' 0"
+ cset "name='ADCR Boost Volume' 0"
+ cset "name='DIGMICR Switch' on"
+ cset "name='DIGMICL Switch' on"
+ cset "name='EQ1 Switch' off"
+ cset "name='EQ2 Switch' off"
+ cset "name='EX Limiter Mode' off"
+ cset "name='EX Limiter Threshold' '0.6'"
+ cset "name='DAI1 Filter Mode' Music"
+ cset "name='DAI1 DAC Filter' off"
+ cset "name='DAI1 ADC Filter' 1"
+ cset "name='DAI2 DC Block Switch' off"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Right SPK Mixer Right DAC1 Switch' on"
+ cset "name='Left SPK Mixer Left DAC1 Switch' on"
+ cset "name='Right HP Mixer Right DAC1 Switch' on"
+ cset "name='Left HP Mixer Left DAC1 Switch' on"
+ cset "name='External MIC' MIC2"
+ cset "name='HDMI Playback Switch' off"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "DAISY-I2S HDMI Jack"
+ DspName ""
+ EDIDFile "/sys/devices/platform/exynos-drm/drm/card1/card1-HDMI-A-1/edid"
+ }
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "DAISY-I2S Headphone Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "DAISY-I2S Mic Jack"
+ CaptureControl "MIC2"
+ }
+
+ EnableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='DIGMICL Switch' off"
+ cset "name='DIGMICR Switch' off"
+ ]
+
+ DisableSequence [
+ cdev "hw:DAISYI2S"
+
+ cset "name='Left ADC Mixer MIC2 Switch' off"
+ cset "name='Right ADC Mixer MIC2 Switch' off"
+ cset "name='DIGMICL Switch' on"
+ cset "name='DIGMICR Switch' on"
+ ]
+}
diff --git a/ucm-config/falco/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/falco/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..45c29837
--- /dev/null
+++ b/ucm-config/falco/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Falco internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/falco/HDA Intel PCH/HiFi.conf b/ucm-config/falco/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..03f431e5
--- /dev/null
+++ b/ucm-config/falco/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,55 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 0"
+ cset "name='Capture Source' 0"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ DspName ""
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Playback Switch' off"
+ cset "name='Headphone Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
diff --git a/ucm-config/for_all_boards/C505 HD Webcam/HiFi.conf b/ucm-config/for_all_boards/C505 HD Webcam/HiFi.conf
deleted file mode 100644
index c7e13426..00000000
--- a/ucm-config/for_all_boards/C505 HD Webcam/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:Webcam"
- cset "name='Mic Capture Volume' 0"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Webcam" {
- Value {
- CapturePCM "hw:Webcam,0"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
diff --git a/ucm-config/for_all_boards/Chat 150 C/HiFi.conf b/ucm-config/for_all_boards/Chat 150 C/HiFi.conf
index 368796d7..5a73702c 100644
--- a/ucm-config/for_all_boards/Chat 150 C/HiFi.conf
+++ b/ucm-config/for_all_boards/Chat 150 C/HiFi.conf
@@ -10,7 +10,7 @@ SectionVerb {
]
}
-SectionDevice."Chat 150 C".0 {
+SectionDevice."Dummy".0 {
EnableSequence [
]
diff --git a/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/DELL PROFESSIONAL SOUND BAR AE5.conf b/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/DELL PROFESSIONAL SOUND BAR AE5.conf
deleted file mode 100644
index e34c8135..00000000
--- a/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/DELL PROFESSIONAL SOUND BAR AE5.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-Comment "DELL PROFESSIONAL SOUND BAR AE5"
-
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/HiFi.conf b/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/HiFi.conf
deleted file mode 100644
index 67bd2d52..00000000
--- a/ucm-config/for_all_boards/DELL PROFESSIONAL SOUND BAR AE5/HiFi.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Dell AE515 USB SoundBar Output".0 {
- Comment "SoundBar Output"
-
- Value {
- PlaybackPCM "hw:AE5,0"
- }
-}
-
-SectionDevice."Dell AE515 USB SoundBar Input".0 {
- Comment "SoundBar Input"
-
- Value {
- CapturePCM "hw:AE5,0"
- }
-}
diff --git a/ucm-config/for_all_boards/Dell AC511 USB SoundBar/HiFi.conf b/ucm-config/for_all_boards/Dell AC511 USB SoundBar/HiFi.conf
deleted file mode 100644
index e920e3c2..00000000
--- a/ucm-config/for_all_boards/Dell AC511 USB SoundBar/HiFi.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:SoundBar"
-
- cset "name='PCM Playback Volume' 51"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Dell AC511 USB SoundBar Output".0 {
- Comment "SoundBar Output"
-
- Value {
- PlaybackPCM "hw:SoundBar,0"
- }
-}
-
-SectionDevice."Dell AC511 USB SoundBar Input".0 {
- Comment "SoundBar Input"
-
- Value {
- CapturePCM "hw:SoundBar,0"
- }
-}
diff --git a/ucm-config/for_all_boards/Dell-WD15-Dock/Dell-WD15-Dock.conf b/ucm-config/for_all_boards/Dell-WD15-Dock/Dell-WD15-Dock.conf
deleted file mode 100644
index 290758a3..00000000
--- a/ucm-config/for_all_boards/Dell-WD15-Dock/Dell-WD15-Dock.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-Comment "USB-audio on Dell docking station"
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/for_all_boards/Dell-WD15-Dock/HiFi.conf b/ucm-config/for_all_boards/Dell-WD15-Dock/HiFi.conf
deleted file mode 100644
index c522540f..00000000
--- a/ucm-config/for_all_boards/Dell-WD15-Dock/HiFi.conf
+++ /dev/null
@@ -1,40 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
- EnableSequence [
- cdev "hw:Dock"
- ]
- DisableSequence [
- ]
-}
-
-SectionDevice."Dock Headphone".0 {
- Comment "Headphone"
-
- Value {
- PlaybackPCM "hw:Dock,0"
- }
-}
-
-SectionDevice."Dock Line Out".0 {
- Value {
- PlaybackPCM "hw:Dock,1"
- }
- EnableSequence [
- cdev "hw:Dock"
- cset "name='Line Playback Switch' on"
- ]
- DisableSequence [
- cdev "hw:Dock"
- cset "name='Line Playback Switch' off"
- ]
-}
-
-SectionDevice."Dock Microphone".0 {
- Comment "Microphone"
-
- Value {
- CapturePCM "hw:Dock,0"
- }
-}
diff --git a/ucm-config/for_all_boards/HD Pro Webcam C920/HD Pro Webcam C920.conf b/ucm-config/for_all_boards/HD Pro Webcam C920/HD Pro Webcam C920.conf
new file mode 100644
index 00000000..e7394ba8
--- /dev/null
+++ b/ucm-config/for_all_boards/HD Pro Webcam C920/HD Pro Webcam C920.conf
@@ -0,0 +1,6 @@
+Comment "HD Pro Webcam C920"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/for_all_boards/HD Pro Webcam C920/HiFi.conf b/ucm-config/for_all_boards/HD Pro Webcam C920/HiFi.conf
new file mode 100644
index 00000000..e7d37232
--- /dev/null
+++ b/ucm-config/for_all_boards/HD Pro Webcam C920/HiFi.conf
@@ -0,0 +1,28 @@
+SectionVerb {
+ Value {
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:C920"
+
+ cset "name='Mic Capture Volume' 5"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic" {
+ Value {
+ CapturePCM "hw:HD Pro Webcam C920,0"
+ MaxSoftwareGain "2000"
+ JackType "always"
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
diff --git a/ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HiFi.conf b/ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HiFi.conf
deleted file mode 100644
index d48942bf..00000000
--- a/ucm-config/for_all_boards/HUAWEI USB-C HEADSET/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:HEADSET"
- cset "name='PCM Playback Volume' 45"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."HUAWEI USB-C HEADSET Output".0 {
- Value {
- PlaybackPCM "hw:HEADSET,0"
- }
-}
-
-SectionDevice."HUAWEI USB-C HEADSET Input".0 {
- Value {
- CapturePCM "hw:HEADSET,0"
- }
-}
diff --git a/ucm-config/for_all_boards/ICUSBAUDIO7D/HiFi.conf b/ucm-config/for_all_boards/ICUSBAUDIO7D/HiFi.conf
deleted file mode 100644
index c44de8dd..00000000
--- a/ucm-config/for_all_boards/ICUSBAUDIO7D/HiFi.conf
+++ /dev/null
@@ -1,132 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:ICUSBAUDIO7D"
-
- cset "name='Line Capture Switch', off"
- cset "name='Mic Capture Switch', off"
- cset "name='IEC958 In Capture Switch', off"
- cset "name='PCM Capture Switch', off"
- cset "name='Speaker Playback Switch', off"
- cset "name='Mic Playback Switch', off"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Speaker-Headset".0 {
- Comment "Speaker out"
-
- Value {
- PlaybackPCM "hw:ICUSBAUDIO7D,0"
- PlaybackMixerElem "Speaker"
- }
-
- EnableSequence [
- cset "name='Speaker Playback Switch', on"
- ]
-
- DisableSequence [
- cset "name='Speaker Playback Switch', off"
- ]
-}
-
-SectionDevice."Line In".0 {
- Comment "Line In"
-
- Value {
- CapturePCM "hw:ICUSBAUDIO7D,0"
- CaptureMixerElem "Line"
- }
-
- ConflictingDevice [
- "Mic"
- "SPDIF In"
- "PCM"
- ]
-
- EnableSequence [
- cset "name='Line Capture Switch', on"
- cset "name='PCM Capture Source', Line"
- ]
-
- DisableSequence [
- cset "name='Line Capture Switch', off"
- ]
-}
-
-SectionDevice."Mic".0 {
- Comment "Mic Input"
-
- Value {
- CapturePCM "hw:ICUSBAUDIO7D,0"
- CaptureMixerElem "Mic"
- }
-
- ConflictingDevice [
- "Line In"
- "SPDIF In"
- "PCM"
- ]
-
- EnableSequence [
- cset "name='Mic Capture Switch', on"
- cset "name='PCM Capture Source', Mic"
- ]
-
- DisableSequence [
- cset "name='Mic Capture Switch', off"
- ]
-}
-
-SectionDevice."SPDIF In".0 {
- Comment "S/PDIF In"
-
- Value {
- CapturePCM "hw:ICUSBAUDIO7D,0"
- CaptureMixerElem "IEC958 In"
- }
-
- ConflictingDevice [
- "Line In"
- "Mic"
- "PCM"
- ]
-
- EnableSequence [
- cset "name='IEC958 In Capture Switch', on"
- cset "name='PCM Capture Source', IEC958 In"
- ]
-
- DisableSequence [
- cset "name='IEC958 In Capture Switch', off"
- ]
-}
-
-SectionDevice."PCM".0 {
- Comment "PCM Capture"
-
- Value {
- CapturePCM "hw:ICUSBAUDIO7D,0"
- CaptureMixerElem "PCM"
- }
-
- ConflictingDevice [
- "Line In"
- "Mic"
- "SPDIF In"
- ]
-
- EnableSequence [
- cset "name='PCM Capture Switch', on"
- cset "name='PCM Capture Source', Mixer"
- ]
-
- DisableSequence [
- cset "name='PCM Capture Switch', off"
- ]
-}
diff --git a/ucm-config/for_all_boards/Jabra SPEAK 810/HiFi.conf b/ucm-config/for_all_boards/Jabra SPEAK 810/HiFi.conf
index 313bffef..5a73702c 100644
--- a/ucm-config/for_all_boards/Jabra SPEAK 810/HiFi.conf
+++ b/ucm-config/for_all_boards/Jabra SPEAK 810/HiFi.conf
@@ -10,7 +10,7 @@ SectionVerb {
]
}
-SectionDevice."Jabra Speak 810".0 {
+SectionDevice."Dummy".0 {
EnableSequence [
]
diff --git a/ucm-config/for_all_boards/Logitech BRIO/HiFi.conf b/ucm-config/for_all_boards/Logitech BRIO/HiFi.conf
deleted file mode 100644
index eb20ee2d..00000000
--- a/ucm-config/for_all_boards/Logitech BRIO/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:BRIO"
- cset "name='Mic Capture Volume' 24"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."BRIO" {
- Value {
- CapturePCM "hw:BRIO,0"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
diff --git a/ucm-config/for_all_boards/Logitech Webcam C930e/HiFi.conf b/ucm-config/for_all_boards/Logitech Webcam C930e/HiFi.conf
deleted file mode 100644
index 95f2fcf8..00000000
--- a/ucm-config/for_all_boards/Logitech Webcam C930e/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:C930e"
- cset "name='Mic Capture Volume' 30"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."C930e" {
- Value {
- CapturePCM "hw:C930e,0"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
diff --git a/ucm-config/for_all_boards/Logitech Webcam C930e/Logitech Webcam C930e.conf b/ucm-config/for_all_boards/Logitech Webcam C930e/Logitech Webcam C930e.conf
deleted file mode 100644
index f6760e2d..00000000
--- a/ucm-config/for_all_boards/Logitech Webcam C930e/Logitech Webcam C930e.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-Comment "Logitech Webcam C930e"
-
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/for_all_boards/Loopback/HiFi.conf b/ucm-config/for_all_boards/Loopback/HiFi.conf
deleted file mode 100644
index 254c9956..00000000
--- a/ucm-config/for_all_boards/Loopback/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Loopback Playback".0 {
- Value {
- PlaybackPCM "hw:Loopback,0"
- PlaybackChannels "8"
- }
-}
-
-SectionDevice."Loopback Capture".0 {
- Value {
- CapturePCM "hw:Loopback,1"
- CaptureChannels "8"
- }
-}
diff --git a/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/HiFi.conf b/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/HiFi.conf
deleted file mode 100644
index 9d63e16e..00000000
--- a/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:TypeC"
- cset "name='PCM Playback Volume' 45"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Mi Earphones Output".0 {
- Value {
- PlaybackPCM "hw:TypeC,0"
- }
-}
-
-SectionDevice."Mi Earphones Input".0 {
- Value {
- CapturePCM "hw:TypeC,0"
- }
-}
diff --git a/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/Mi Dual Driver Earphones Type-C.conf b/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/Mi Dual Driver Earphones Type-C.conf
deleted file mode 100644
index df19b47b..00000000
--- a/ucm-config/for_all_boards/Mi Dual Driver Earphones Type-C/Mi Dual Driver Earphones Type-C.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-Comment "Mi Dual Driver Earphones Type-C"
-
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/for_all_boards/PCP-USB/HiFi.conf b/ucm-config/for_all_boards/PCP-USB/HiFi.conf
deleted file mode 100644
index ac5c7ed7..00000000
--- a/ucm-config/for_all_boards/PCP-USB/HiFi.conf
+++ /dev/null
@@ -1,20 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:PCPUSB"
-
- cset "name='Mic Capture Volume' 19"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."PCP USB Input".0 {
- Value {
- CapturePCM "hw:PCPUSB,0"
- }
-}
diff --git a/ucm-config/for_all_boards/Pixel USB-C earbuds/HiFi.conf b/ucm-config/for_all_boards/Pixel USB-C earbuds/HiFi.conf
deleted file mode 100644
index 7a607456..00000000
--- a/ucm-config/for_all_boards/Pixel USB-C earbuds/HiFi.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Google Pixel earbuds Output".0 {
- Value {
- PlaybackPCM "hw:earbuds,0"
- }
-}
-
-SectionDevice."Google Pixel earbuds Input".0 {
- Value {
- CapturePCM "hw:earbuds,0"
- IntrinsicSensitivity "-3100"
- }
-}
diff --git a/ucm-config/for_all_boards/Plankton Captured HDMI Audio/HiFi.conf b/ucm-config/for_all_boards/Plankton Captured HDMI Audio/HiFi.conf
new file mode 100644
index 00000000..1a1f4a29
--- /dev/null
+++ b/ucm-config/for_all_boards/Plankton Captured HDMI Audio/HiFi.conf
@@ -0,0 +1,24 @@
+SectionVerb {
+ Value {
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Plankton Captured HDMI Audio".0 {
+ Value {
+ CapturePCM "hw:Plankton Captured HDMI Audio,0"
+ JackType "always"
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
diff --git a/ucm-config/for_all_boards/Plankton Captured HDMI Audio/Plankton Captured HDMI Audio.conf b/ucm-config/for_all_boards/Plankton Captured HDMI Audio/Plankton Captured HDMI Audio.conf
new file mode 100644
index 00000000..6514aa1c
--- /dev/null
+++ b/ucm-config/for_all_boards/Plankton Captured HDMI Audio/Plankton Captured HDMI Audio.conf
@@ -0,0 +1,6 @@
+Comment "Plankton Captured HDMI Audio"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/for_all_boards/Plantronics DA70/HiFi.conf b/ucm-config/for_all_boards/Plantronics DA70/HiFi.conf
deleted file mode 100644
index 0840b5d1..00000000
--- a/ucm-config/for_all_boards/Plantronics DA70/HiFi.conf
+++ /dev/null
@@ -1,28 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:SoundBar"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Plantronics DA70 Output".0 {
- Comment "DA70 Output"
-
- Value {
- PlaybackPCM "hw:DA70,0"
- }
-}
-
-SectionDevice."Plantronics DA70 Input".0 {
- Comment "DA70 Input"
-
- Value {
- CapturePCM "hw:DA70,0"
- }
-}
diff --git a/ucm-config/for_all_boards/README b/ucm-config/for_all_boards/README
new file mode 100644
index 00000000..b5384358
--- /dev/null
+++ b/ucm-config/for_all_boards/README
@@ -0,0 +1,8 @@
+Regarding the two dead sym links WD15 Dock and WD19 Dock
+
+ALSA has added a ucm for the ucm the sym links they point to and the ucm
+has been patched in the chromiumos overlay. Unfortunately the alsa-lib
+installs via Makefile and make HATES files with spaces, so we are keeping
+the sym links here (even though they appear dead) they are NOT. Once
+deployed with alsa-lib 1.1.8 they will have a proper target on a dut.
+
diff --git a/ucm-config/for_all_boards/Scarlett 2i2 USB/HiFi.conf b/ucm-config/for_all_boards/Scarlett 2i2 USB/HiFi.conf
deleted file mode 100644
index f49d6816..00000000
--- a/ucm-config/for_all_boards/Scarlett 2i2 USB/HiFi.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
- EnableSequence [
- cdev "hw:USB,0"
- ]
- DisableSequence [
- ]
-}
-
-SectionDevice."Scarlett 2i2 USB Output".0 {
- Comment "Scarlett 2i2 Output"
-
- Value {
- PlaybackPCM "hw:USB,0"
- PlaybackRate "48000"
- }
-}
-
-SectionDevice."Scarlett 2i2 USB Input".0 {
- Comment "Scarlett 2i2 Input"
- Value {
- CapturePCM "hw:USB,0"
- CaptureRate "48000"
- }
-}
diff --git a/ucm-config/for_all_boards/Scarlett 2i4 USB/HiFi.conf b/ucm-config/for_all_boards/Scarlett 2i4 USB/HiFi.conf
deleted file mode 100644
index 894683cd..00000000
--- a/ucm-config/for_all_boards/Scarlett 2i4 USB/HiFi.conf
+++ /dev/null
@@ -1,27 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
- EnableSequence [
- cdev "hw:USB,0"
- ]
- DisableSequence [
- ]
-}
-
-SectionDevice."Scarlett 2i4 USB Output".0 {
- Comment "Scarlett 2i4 Output"
-
- Value {
- PlaybackPCM "hw:USB,0"
- PlaybackRate "48000"
- }
-}
-
-SectionDevice."Scarlett 2i4 USB Input".0 {
- Comment "Scarlett 2i4 Input"
- Value {
- CapturePCM "hw:USB,0"
- CaptureRate "48000"
- }
-}
diff --git a/ucm-config/for_all_boards/Scarlett 2i4 USB/Scarlett 2i4 USB.conf b/ucm-config/for_all_boards/Scarlett 2i4 USB/Scarlett 2i4 USB.conf
deleted file mode 100644
index 71ea1696..00000000
--- a/ucm-config/for_all_boards/Scarlett 2i4 USB/Scarlett 2i4 USB.conf
+++ /dev/null
@@ -1,5 +0,0 @@
-Comment "Scarlett 2i4 USB"
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/for_all_boards/USB 2.0 Camera/HiFi.conf b/ucm-config/for_all_boards/USB 2.0 Camera/HiFi.conf
deleted file mode 100644
index e4121da1..00000000
--- a/ucm-config/for_all_boards/USB 2.0 Camera/HiFi.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-SectionVerb {
- Value {
- FullySpecifiedUCM "1"
- }
-
- EnableSequence [
- cdev "hw:Camera"
- cset "name='Mic Capture Volume' 200"
- ]
-
- DisableSequence [
- ]
-}
-
-SectionDevice."Camera" {
- Value {
- CapturePCM "hw:Camera,0"
- }
-
- EnableSequence [
- ]
-
- DisableSequence [
- ]
-}
diff --git a/ucm-config/for_all_boards/USB 2.0 Camera/USB 2.0 Camera b/ucm-config/for_all_boards/USB 2.0 Camera/USB 2.0 Camera
deleted file mode 100644
index 52bd294a..00000000
--- a/ucm-config/for_all_boards/USB 2.0 Camera/USB 2.0 Camera
+++ /dev/null
@@ -1,6 +0,0 @@
-Comment "ZIQIAN N21 1080P Webcam"
-
-SectionUseCase."HiFi" {
- File "HiFi.conf"
- Comment "Default"
-}
diff --git a/ucm-config/glados/sklnau8825adi/HiFi.conf b/ucm-config/glados/sklnau8825adi/HiFi.conf
new file mode 100644
index 00000000..c10104dc
--- /dev/null
+++ b/ucm-config/glados/sklnau8825adi/HiFi.conf
@@ -0,0 +1,512 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ InputDspName "extmic_eq"
+ }
+
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset "name='codec1_out mo media0_in mi Switch' off"
+ cset "name='codec0_out mo media0_in mi Switch' on"
+ cset "name='DAC Oversampling Rate' 64"
+ cset "name='Headset Mic Switch' off"
+ cset "name='BIQ Path Select' ADC"
+ cset "name='BIQ Coefficients' 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
+ cset "name='codec0_iv_in Switch' 0"
+ cset "name='media0_out mo codec0_in mi Switch' off"
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' on"
+ cset "name='Pin 5 Mux' cvt 2"
+ cset "name='Pin 6 Mux' cvt 3"
+ cset "name='Pin 7 Mux' cvt 4"
+ cset "name='Mic Volume' 255"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ MaxSoftwareGain "2400"
+ InputDspName ""
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ CoupledMixers "Left Master,Right Master"
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI1".0 {
+ Value {
+ JackName "HDMI/DP, pcm=4 Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."HDMI2".0 {
+ Value {
+ JackName "HDMI/DP, pcm=5 Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "sklnau8825adi Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset "name='codec0_out mo media0_in mi Switch' off"
+ cset "name='codec1_out mo media0_in mi Switch' on"
+ cset "name='Headphone Jack Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:sklnau8825adi"
+ cset "name='codec0_out mo media0_in mi Switch' on"
+ cset "name='codec1_out mo media0_in mi Switch' off"
+ cset "name='Headphone Jack Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "sklnau8825adi Headset Jack"
+ CaptureControl "Mic"
+ DefaultNodeGain "800"
+ }
+
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset "name='Headset Mic Switch' on"
+ cset "name='BIQ Coefficients' 0,155,0,6,255,102,0,0,255,179,0,0,0,154,0,6,255,179,128,0"
+ cset "name='media0_out mo codec0_in mi Switch' on"
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' off"
+ ]
+
+ DisableSequence [
+ cdev "hw:sklnau8825adi"
+ cset "name='Headset Mic Switch' off"
+ cset "name='BIQ Coefficients' 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
+ cset "name='media0_out mo codec0_in mi Switch' off"
+ cset "name='media0_out mo dmic01_hifi_in mi Switch' on"
+ ]
+}
+
+SectionModifier."Hotword Model ar_eg".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ar_eg.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model cmn_cn".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/cmn_hans_cn.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model cmn_tw".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/cmn_hant_tw.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model cs_cz".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/cs_cz.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model da_dk".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/da_dk.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model de_de".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/de_de.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_au".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_au.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_gb".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_gb.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_ie".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_ie.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_in".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_in.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_ph".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_ph.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model en_us".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/en_us.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model es_419".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/es_419.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model es_ar".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/es_ar.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model es_es".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/es_es.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model es_mx".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/es_mx.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model es_us".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/es_us.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model fa_ir".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/fa_ir.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model fi_fi".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/fi_fi.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model fil_ph".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/fil_ph.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model fr_fr".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/fr_fr.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model hi_in".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/hi_in.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model hr_hr".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/hr_hr.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model id_id".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/id_id.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model it_it".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/it_it.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model ja_jp".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ja_jp.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model ko_kr".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ko_kr.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model ms_my".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ms_my.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model nb_no".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/nb_no.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model nl_nl".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/nl_nl.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model pl_pl".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/pl_pl.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model pt_br".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/pt_br.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model ro_ro".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ro_ro.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model ru_ru".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/ru_ru.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model sv_se".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/sv_se.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model th_th".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/th_th.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model tr_tr".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/tr_tr.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model vi_vn".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/vi_vn.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionModifier."Hotword Model yue_hk".0 {
+ EnableSequence [
+ cdev "hw:sklnau8825adi"
+ cset-tlv "name='hwd_in hwd 0 mdl params' /opt/google/skl-hotword-support/yue_hant_hk.hwd-blob"
+ ]
+
+ DisableSequence [
+ ]
+}
diff --git a/ucm-config/for_all_boards/C505 HD Webcam/C505 HD Webcam.conf b/ucm-config/glados/sklnau8825adi/sklnau8825adi.conf
index 126ac331..e1b2a278 100644
--- a/ucm-config/for_all_boards/C505 HD Webcam/C505 HD Webcam.conf
+++ b/ucm-config/glados/sklnau8825adi/sklnau8825adi.conf
@@ -1,4 +1,4 @@
-Comment "Logitech Webcam C505"
+Comment "Glados internal card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/jecht/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/jecht/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..17e4cb15
--- /dev/null
+++ b/ucm-config/jecht/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Jecht internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/jecht/HDA Intel PCH/HiFi.conf b/ucm-config/jecht/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/jecht/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/leon/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/leon/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..f6608a08
--- /dev/null
+++ b/ucm-config/leon/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Leon internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/leon/HDA Intel PCH/HiFi.conf b/ucm-config/leon/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..03f431e5
--- /dev/null
+++ b/ucm-config/leon/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,55 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 0"
+ cset "name='Capture Source' 0"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ DspName ""
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Playback Switch' off"
+ cset "name='Headphone Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
diff --git a/ucm-config/link/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/link/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..44e29321
--- /dev/null
+++ b/ucm-config/link/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Link internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/link/HDA Intel PCH/HiFi.conf b/ucm-config/link/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..6c78a275
--- /dev/null
+++ b/ucm-config/link/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,70 @@
+SectionVerb {
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='HP/Speaker Playback Switch' off"
+ cset "name='HP/Speaker Auto Detect Playback Switch' off"
+ cset "name='PlayEnhancement Playback Switch' on"
+ cset "name='Surround Playback Switch' on"
+ cset "name='Crystalizer Playback Switch' off"
+ cset "name='Dialog Plus Playback Switch' off"
+ cset "name='Smart Volume Playback Switch' on"
+ cset "name='X-Bass Playback Switch' on"
+ cset "name='Equalizer Playback Switch' off"
+ cset "name='Echo Cancellation Capture Switch' on"
+ cset "name='IEC958 Playback Switch' on"
+ cset "name='IEC958 Playback Switch',index=1 on"
+ cset "name='IEC958 Playback Switch',index=2 on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 99"
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='Analog-Mic2 Capture Volume' 90"
+ cset "name='Analog-Mic2 Capture Switch' on"
+ cset "name='Mic1-Boost (30dB) Capture Switch' on"
+ cset "name='AMic1/DMic Capture Switch' off"
+ cset "name='AMic1/DMic Auto Detect Capture Switch' off"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='PlayEnhancement Playback Switch' off"
+ cset "name='HP/Speaker Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='PlayEnhancement Playback Switch' on"
+ cset "name='HP/Speaker Playback Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='AMic1/DMic Capture Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='CrystalVoice Capture Switch' off"
+ cset "name='AMic1/DMic Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/for_all_boards/ICUSBAUDIO7D/ICUSBAUDIO7D.conf b/ucm-config/mccloud/HDA Intel PCH/HDA Intel PCH.conf
index 3dc10fa7..a10a4cd9 100644
--- a/ucm-config/for_all_boards/ICUSBAUDIO7D/ICUSBAUDIO7D.conf
+++ b/ucm-config/mccloud/HDA Intel PCH/HDA Intel PCH.conf
@@ -1,4 +1,4 @@
-Comment "Startech USB 7D Audio"
+Comment "Mccloud internal card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/mccloud/HDA Intel PCH/HiFi.conf b/ucm-config/mccloud/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/mccloud/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/for_all_boards/Plantronics DA70/Plantronics DA70.conf b/ucm-config/monroe/HDA Intel MID/HDA Intel MID.conf
index 7857d470..d3bf843f 100644
--- a/ucm-config/for_all_boards/Plantronics DA70/Plantronics DA70.conf
+++ b/ucm-config/monroe/HDA Intel MID/HDA Intel MID.conf
@@ -1,4 +1,4 @@
-Comment "Plantronics DA70"
+Comment "Monroe HDMI card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/monroe/HDA Intel MID/HiFi.conf b/ucm-config/monroe/HDA Intel MID/HiFi.conf
new file mode 100644
index 00000000..10cc8528
--- /dev/null
+++ b/ucm-config/monroe/HDA Intel MID/HiFi.conf
@@ -0,0 +1,15 @@
+SectionVerb {
+ Value {
+ }
+ EnableSequence [
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."OUTPUT".0 {
+ Value {
+ JackName "HDMI/DP,pcm=3 Jack"
+ OverrideNodeType "Internal Speaker"
+ }
+}
diff --git a/ucm-config/monroe/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/monroe/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..cbd74d48
--- /dev/null
+++ b/ucm-config/monroe/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Monroe internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/monroe/HDA Intel PCH/HiFi.conf b/ucm-config/monroe/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..54dd5a96
--- /dev/null
+++ b/ucm-config/monroe/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,37 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 1"
+ cset "name='Capture Source' 0"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ }
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
diff --git a/ucm-config/panther/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/panther/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..813d96e2
--- /dev/null
+++ b/ucm-config/panther/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Panther internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/panther/HDA Intel PCH/HiFi.conf b/ucm-config/panther/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/panther/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/peppy/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/peppy/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..819f8265
--- /dev/null
+++ b/ucm-config/peppy/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Peppy internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/peppy/HDA Intel PCH/HiFi.conf b/ucm-config/peppy/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..c33144d1
--- /dev/null
+++ b/ucm-config/peppy/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,55 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 1"
+ cset "name='Input Source' 1"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ DspName ""
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Playback Switch' off"
+ cset "name='Headphone Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Input Source' 0"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Input Source' 1"
+ ]
+}
diff --git a/ucm-config/rikku/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/rikku/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..d9365ccc
--- /dev/null
+++ b/ucm-config/rikku/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Rikku internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/rikku/HDA Intel PCH/HiFi.conf b/ucm-config/rikku/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/rikku/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/stout/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/stout/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..2751b940
--- /dev/null
+++ b/ucm-config/stout/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Stout internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/stout/HDA Intel PCH/HiFi.conf b/ucm-config/stout/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..20c809a9
--- /dev/null
+++ b/ucm-config/stout/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,62 @@
+SectionVerb {
+ Value {
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Volume' 87"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Volume' 87"
+ cset "name='Speaker Playback Switch' on"
+ cset "name='Mic Playback Volume' 0"
+ cset "name='Mic Playback Switch' off"
+ cset "name='Internal Mic Boost Volume' 0"
+ cset "name='Mic Boost Volume' 0"
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Master Playback Volume' 79"
+ cset "name='Master Playback Switch' on"
+ cset "name='IEC958 Playback Switch' on"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Pin Playback Switch' off"
+ cset "name='HP Pin Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='HP Pin Playback Switch' off"
+ cset "name='Speaker Pin Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ }
+}
diff --git a/ucm-config/strago/chtrt5645/HiFi.conf b/ucm-config/strago/chtrt5645/HiFi.conf
new file mode 100644
index 00000000..e51c9472
--- /dev/null
+++ b/ucm-config/strago/chtrt5645/HiFi.conf
@@ -0,0 +1,121 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5645"
+
+ cset "name='codec_out1 mix 0 pcm0_in Switch' on"
+ cset "name='media0_out mix 0 media1_in Switch' on"
+
+ cset "name='media1_in Gain 0 Ramp Delay' 50"
+ cset "name='media1_in Gain 0 Switch' off"
+ cset "name='media1_in Gain 0 Volume' 80% 80%"
+
+ cset "name='pcm0_in Gain 0 Ramp Delay' 50"
+ cset "name='pcm0_in Gain 0 Switch' off"
+ cset "name='pcm0_in Gain 0 Volume' 80% 80%"
+
+ cset "name='codec_out1 Gain 0 Ramp Delay' 50"
+ cset "name='codec_out1 Gain 0 Switch' off"
+ cset "name='codec_out1 Gain 0 Volume' 70% 70%"
+
+ cset "name='Ext Spk Switch' on"
+ cset "name='Speaker Channel Switch' on"
+ cset "name='Ext HP Switch' off"
+
+ cset "name='DAC R2 Mux' 'IF1 DAC'"
+ cset "name='DAC L2 Mux' 'IF1 DAC'"
+ cset "name='Mono DAC MIXL DAC L2 Switch' on"
+ cset "name='Mono DAC MIXR DAC R2 Switch' on"
+ cset "name='DAC2 Playback Switch' on"
+
+ cset "name='HPOVOL MIXL DAC2 Switch' on"
+ cset "name='HPOVOL MIXR DAC2 Switch' on"
+ cset "name='HPO MIX HPVOL Switch' on"
+ cset "name='HPOVOL L Switch' on"
+ cset "name='HPOVOL R Switch' on"
+
+ cset "name='SPK MIXL DAC L2 Switch' on"
+ cset "name='SPK MIXR DAC R2 Switch' on"
+ cset "name='SPOL MIX SPKVOL L Switch' on"
+ cset "name='SPOR MIX SPKVOL R Switch' on"
+ cset "name='SPKVOL L Switch' on"
+ cset "name='SPKVOL R Switch' on"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+ cset "name='ADC Capture Switch' on"
+ cset "name='Stereo1 DMIC Mux' 0"
+ cset "name='Stereo1 ADC2 Mux' 1"
+ cset "name='I2S2 Func Switch' 0"
+ cset "name='pcm1_out mix 0 media_loop2_in Switch' 1"
+ cset "name='media_loop2_out mix 0 codec_in0 Switch' 1"
+ cset "name='codec_in0 Gain 0 Ramp Delay' 50"
+ cset "name='codec_in0 Gain 0 Switch' off"
+ cset "name='codec_in0 Gain 0 Volume' 80% 80%"
+ cset "name='media_loop2_out Gain 0 Ramp Delay' 50"
+ cset "name='media_loop2_out Gain 0 Switch' off"
+ cset "name='media_loop2_out Gain 0 Volume' 80% 80%"
+ cset "name='pcm1_out Gain 0 Ramp Delay' 50"
+ cset "name='pcm1_out Gain 0 Switch' off"
+ cset "name='pcm1_out Gain 0 Volume' 80% 80%"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "chtrt5645 Headphone Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5645"
+ cset "name='Ext Spk Switch' off"
+ cset "name='Speaker Channel Switch' off"
+ cset "name='Ext HP Switch' on"
+ cset "name='HP Channel Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:chtrt5645"
+ cset "name='Ext Spk Switch' on"
+ cset "name='Speaker Channel Switch' on"
+ cset "name='Ext HP Switch' off"
+ cset "name='HP Channel Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "chtrt5645 Mic Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5645"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Int Mic Switch' off"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' 0"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' 0"
+ cset "name='RECMIXL BST1 Switch' 1"
+ cset "name='RECMIXR BST1 Switch' 1"
+ cset "name='Sto1 ADC MIXL ADC1 Switch' 1"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' 1"
+ ]
+
+ DisableSequence [
+ cdev "hw:chtrt5645"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+ cset "name='RECMIXL BST1 Switch' 0"
+ cset "name='RECMIXR BST1 Switch' 0"
+ cset "name='Sto1 ADC MIXL ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' 1"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' 1"
+ ]
+}
diff --git a/ucm-config/strago/chtrt5645/chtrt5645.conf b/ucm-config/strago/chtrt5645/chtrt5645.conf
new file mode 100644
index 00000000..14b8450f
--- /dev/null
+++ b/ucm-config/strago/chtrt5645/chtrt5645.conf
@@ -0,0 +1,6 @@
+Comment "Strago internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/strago/chtrt5650/HiFi.conf b/ucm-config/strago/chtrt5650/HiFi.conf
new file mode 100644
index 00000000..4cdc9009
--- /dev/null
+++ b/ucm-config/strago/chtrt5650/HiFi.conf
@@ -0,0 +1,129 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5650"
+
+ cset "name='codec_out0 mix 0 pcm0_in Switch' on"
+ cset "name='media0_out mix 0 media1_in Switch' on"
+
+ cset "name='media1_in Gain 0 Ramp Delay' 50"
+ cset "name='media1_in Gain 0 Switch' off"
+ cset "name='media1_in Gain 0 Volume' 80% 80%"
+
+ cset "name='pcm0_in Gain 0 Ramp Delay' 50"
+ cset "name='pcm0_in Gain 0 Switch' off"
+ cset "name='pcm0_in Gain 0 Volume' 80% 80%"
+
+ cset "name='codec_out0 Gain 0 Ramp Delay' 50"
+ cset "name='codec_out0 Gain 0 Switch' off"
+ cset "name='codec_out0 Gain 0 Volume' 80% 80%"
+
+ cset "name='Ext Spk Switch' on"
+ cset "name='Speaker Channel Switch' on"
+ cset "name='Ext HP Switch' off"
+
+ cset "name='Stereo DAC MIXL DAC L1 Switch' on"
+ cset "name='Stereo DAC MIXR DAC R1 Switch' on"
+ cset "name='DAC1 MIXL DAC1 Switch' on"
+ cset "name='DAC1 MIXR DAC1 Switch' on"
+
+ cset "name='SPK MIXL DAC L1 Switch' on"
+ cset "name='SPK MIXR DAC R1 Switch' on"
+ cset "name='SPOL MIX SPKVOL L Switch' on"
+ cset "name='SPOR MIX SPKVOL R Switch' on"
+ cset "name='SPKVOL L Switch' on"
+ cset "name='SPKVOL R Switch' on"
+ cset "name='Speaker Channel Switch' on"
+
+ cset "name='HPOVOL MIXL DAC1 Switch' on"
+ cset "name='HPOVOL MIXR DAC1 Switch' on"
+ cset "name='HPO MIX HPVOL Switch' on"
+ cset "name='HPOVOL L Switch' on"
+ cset "name='HPOVOL R Switch' on"
+ cset "name='Headphone Channel Switch' on"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+ cset "name='ADC Capture Switch' on"
+ cset "name='Stereo1 DMIC Mux' 1"
+ cset "name='Stereo1 ADC2 Mux' 1"
+ cset "name='I2S2 Func Switch' 0"
+ cset "name='RT5650 IF1 ADC Mux' 0"
+ cset "name='ADC Capture Volume' 74"
+
+ cset "name='Sto1 ADC MIXL ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' 1"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' 1"
+
+ cset "name='pcm1_out mix 0 media_loop2_in Switch' 1"
+ cset "name='media_loop2_out mix 0 codec_in0 Switch' 1"
+ cset "name='codec_in0 Gain 0 Ramp Delay' 50"
+ cset "name='codec_in0 Gain 0 Switch' off"
+ cset "name='codec_in0 Gain 0 Volume' 80% 80%"
+ cset "name='media_loop2_out Gain 0 Ramp Delay' 50"
+ cset "name='media_loop2_out Gain 0 Switch' off"
+ cset "name='media_loop2_out Gain 0 Volume' 80% 80%"
+ cset "name='pcm1_out Gain 0 Ramp Delay' 50"
+ cset "name='pcm1_out Gain 0 Switch' off"
+ cset "name='pcm1_out Gain 0 Volume' 80% 80%"
+
+
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "chtrt5650 Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5650"
+ cset "name='Ext Spk Switch' off"
+ cset "name='Ext HP Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:chtrt5650"
+ cset "name='Ext Spk Switch' on"
+ cset "name='Ext HP Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "chtrt5650 Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5650"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Int Mic Switch' off"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' 0"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' 0"
+ cset "name='RECMIXL BST1 Switch' 1"
+ cset "name='RECMIXR BST1 Switch' 1"
+ cset "name='Sto1 ADC MIXL ADC1 Switch' 1"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' 1"
+ cset "name='IN1 Boost' 1"
+ ]
+
+ DisableSequence [
+ cdev "hw:chtrt5650"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+ cset "name='RECMIXL BST1 Switch' 0"
+ cset "name='RECMIXR BST1 Switch' 0"
+ cset "name='Sto1 ADC MIXL ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' 0"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' 1"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' 1"
+ cset "name='IN1 Boost' 0"
+ ]
+}
diff --git a/ucm-config/strago/chtrt5650/chtrt5650.conf b/ucm-config/strago/chtrt5650/chtrt5650.conf
new file mode 100644
index 00000000..14b8450f
--- /dev/null
+++ b/ucm-config/strago/chtrt5650/chtrt5650.conf
@@ -0,0 +1,6 @@
+Comment "Strago internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/strago/chtrt5676/HiFi.conf b/ucm-config/strago/chtrt5676/HiFi.conf
new file mode 100644
index 00000000..dd2354fd
--- /dev/null
+++ b/ucm-config/strago/chtrt5676/HiFi.conf
@@ -0,0 +1,106 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5676"
+
+ cset "name='codec_out0 mix 0 pcm0_in Switch' on"
+ cset "name='media0_out mix 0 media1_in Switch' on"
+
+ cset "name='media1_in Gain 0 Ramp Delay' 50"
+ cset "name='media1_in Gain 0 Switch' off"
+ cset "name='media1_in Gain 0 Volume' 80% 80%"
+
+ cset "name='pcm0_in Gain 0 Ramp Delay' 50"
+ cset "name='pcm0_in Gain 0 Switch' off"
+ cset "name='pcm0_in Gain 0 Volume' 80% 80%"
+
+ cset "name='codec_out0 Gain 0 Ramp Delay' 50"
+ cset "name='codec_out0 Gain 0 Switch' off"
+ cset "name='codec_out0 Gain 0 Volume' 70% 70%"
+
+ cset "name='Ext Spk Switch' on"
+ cset "name='Ext HP Switch' off"
+
+ cset "name='DAC1 MIXL DAC1 Switch' on"
+ cset "name='DAC1 MIXR DAC1 Switch' on"
+ cset "name='Stereo DAC MIXL DAC1 L Switch' on"
+ cset "name='Stereo DAC MIXR DAC1 R Switch' on"
+ cset "name='PDM1 L Mux' 0"
+ cset "name='PDM1 R Mux' 0"
+
+ cset "name='DAC1 Mux' 0"
+ cset "name='DAC12 SRC Mux' 0"
+ cset "name='OUT1 Playback Switch' on"
+ cset "name='OUT2 Playback Switch' on"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='Stereo1 DMIC Mux' 0"
+ cset "name='Stereo1 ADC2 Mux' 1"
+ cset "name='Sto1 ADC MIXL ADC2 Switch' on"
+ cset "name='Sto1 ADC MIXR ADC2 Switch' on"
+ cset "name='IF1 ADC1 Mux' 0"
+
+ cset "name='Stereo1 ADC1 Mux' 1"
+ cset "name='Sto1 ADC MIXL ADC1 Switch' on"
+ cset "name='Sto1 ADC MIXR ADC1 Switch' on"
+ cset "name='IN1 Boost' 1"
+ cset "name='IF1 ADC1 Swap Mux' 2"
+
+ cset "name='pcm1_out mix 0 media_loop2_in Switch' 1"
+ cset "name='media_loop2_out mix 0 codec_in0 Switch' 1"
+ cset "name='codec_in0 Gain 0 Ramp Delay' 50"
+ cset "name='codec_in0 Gain 0 Switch' off"
+ cset "name='codec_in0 Gain 0 Volume' 80% 80%"
+ cset "name='media_loop2_out Gain 0 Ramp Delay' 50"
+ cset "name='media_loop2_out Gain 0 Switch' off"
+ cset "name='media_loop2_out Gain 0 Volume' 80% 80%"
+ cset "name='pcm1_out Gain 0 Ramp Delay' 50"
+ cset "name='pcm1_out Gain 0 Switch' off"
+ cset "name='pcm1_out Gain 0 Volume' 80% 80%"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "chtrt5676 Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5676"
+ cset "name='Ext Spk Switch' off"
+ cset "name='Ext HP Switch' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:chtrt5676"
+ cset "name='Ext Spk Switch' on"
+ cset "name='Ext HP Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "chtrt5676 Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:chtrt5676"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Int Mic Switch' off"
+ ]
+
+ DisableSequence [
+ cdev "hw:chtrt5676"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+ ]
+}
diff --git a/ucm-config/strago/chtrt5676/chtrt5676.conf b/ucm-config/strago/chtrt5676/chtrt5676.conf
new file mode 100644
index 00000000..14b8450f
--- /dev/null
+++ b/ucm-config/strago/chtrt5676/chtrt5676.conf
@@ -0,0 +1,6 @@
+Comment "Strago internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/tidus/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/tidus/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..ad8ba1af
--- /dev/null
+++ b/ucm-config/tidus/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Tidus internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/tidus/HDA Intel PCH/HiFi.conf b/ucm-config/tidus/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/tidus/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/tricky/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/tricky/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..f9b1aece
--- /dev/null
+++ b/ucm-config/tricky/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Tricky internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/tricky/HDA Intel PCH/HiFi.conf b/ucm-config/tricky/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/tricky/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/ucm-config/veyron/ROCKCHIP-I2S/HiFi.conf b/ucm-config/veyron/ROCKCHIP-I2S/HiFi.conf
new file mode 100644
index 00000000..a7d8020d
--- /dev/null
+++ b/ucm-config/veyron/ROCKCHIP-I2S/HiFi.conf
@@ -0,0 +1,137 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Headphone Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/for_all_boards/Logitech BRIO/Logitech BRIO.conf b/ucm-config/veyron/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
index 7059edac..0c399b0d 100644
--- a/ucm-config/for_all_boards/Logitech BRIO/Logitech BRIO.conf
+++ b/ucm-config/veyron/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
@@ -1,4 +1,4 @@
-Comment "Logitech BRIO"
+Comment "Rockchip card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/veyron/RockchipHDMI/HiFi.conf b/ucm-config/veyron/RockchipHDMI/HiFi.conf
new file mode 100644
index 00000000..bf76d6a6
--- /dev/null
+++ b/ucm-config/veyron/RockchipHDMI/HiFi.conf
@@ -0,0 +1,12 @@
+SectionVerb {
+ Value {
+ MinBufferLevel "512"
+ }
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "RockchipHDMI HDMI Jack"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+}
diff --git a/ucm-config/veyron/RockchipHDMI/RockchipHDMI.conf b/ucm-config/veyron/RockchipHDMI/RockchipHDMI.conf
new file mode 100644
index 00000000..a167d741
--- /dev/null
+++ b/ucm-config/veyron/RockchipHDMI/RockchipHDMI.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip HDMI card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron/VEYRON-I2S/HiFi.conf b/ucm-config/veyron/VEYRON-I2S/HiFi.conf
new file mode 100644
index 00000000..2698529d
--- /dev/null
+++ b/ucm-config/veyron/VEYRON-I2S/HiFi.conf
@@ -0,0 +1,158 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ cset "name='Speaker Switch' off"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ OutputDspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ cset "name='Headphone Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,1"
+ JackName "VEYRON-I2S HDMI Jack"
+ JackType "gpio"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+}
diff --git a/ucm-config/for_all_boards/Loopback/Loopback.conf b/ucm-config/veyron/VEYRON-I2S/VEYRON-I2S.conf
index 44abedda..0c399b0d 100644
--- a/ucm-config/for_all_boards/Loopback/Loopback.conf
+++ b/ucm-config/veyron/VEYRON-I2S/VEYRON-I2S.conf
@@ -1,4 +1,4 @@
-Comment "Loopback"
+Comment "Rockchip card"
SectionUseCase."HiFi" {
File "HiFi.conf"
diff --git a/ucm-config/veyron_fievel/ROCKCHIP-I2S/HiFi.conf b/ucm-config/veyron_fievel/ROCKCHIP-I2S/HiFi.conf
new file mode 100644
index 00000000..c9e570ac
--- /dev/null
+++ b/ucm-config/veyron_fievel/ROCKCHIP-I2S/HiFi.conf
@@ -0,0 +1,103 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Headphone Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/for_all_boards/Scarlett 2i2 USB/Scarlett 2i2 USB.conf b/ucm-config/veyron_fievel/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
index 88bac6ba..0c399b0d 100644
--- a/ucm-config/for_all_boards/Scarlett 2i2 USB/Scarlett 2i2 USB.conf
+++ b/ucm-config/veyron_fievel/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
@@ -1,4 +1,5 @@
-Comment "Scarlett 2i2 USB"
+Comment "Rockchip card"
+
SectionUseCase."HiFi" {
File "HiFi.conf"
Comment "Default"
diff --git a/ucm-config/veyron_fievel/RockchipHDMI/HiFi.conf b/ucm-config/veyron_fievel/RockchipHDMI/HiFi.conf
new file mode 100644
index 00000000..bf76d6a6
--- /dev/null
+++ b/ucm-config/veyron_fievel/RockchipHDMI/HiFi.conf
@@ -0,0 +1,12 @@
+SectionVerb {
+ Value {
+ MinBufferLevel "512"
+ }
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "RockchipHDMI HDMI Jack"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+}
diff --git a/ucm-config/veyron_fievel/RockchipHDMI/RockchipHDMI.conf b/ucm-config/veyron_fievel/RockchipHDMI/RockchipHDMI.conf
new file mode 100644
index 00000000..a167d741
--- /dev/null
+++ b/ucm-config/veyron_fievel/RockchipHDMI/RockchipHDMI.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip HDMI card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_fievel/VEYRON-I2S/HiFi.conf b/ucm-config/veyron_fievel/VEYRON-I2S/HiFi.conf
new file mode 100644
index 00000000..f23f3bc4
--- /dev/null
+++ b/ucm-config/veyron_fievel/VEYRON-I2S/HiFi.conf
@@ -0,0 +1,120 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ cset "name='Speaker Switch' off"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ OutputDspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ cset "name='Headphone Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,1"
+ JackName "VEYRON-I2S HDMI Jack"
+ JackType "gpio"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+}
diff --git a/ucm-config/veyron_fievel/VEYRON-I2S/VEYRON-I2S.conf b/ucm-config/veyron_fievel/VEYRON-I2S/VEYRON-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_fievel/VEYRON-I2S/VEYRON-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_jaq/ROCKCHIP-I2S/HiFi.conf b/ucm-config/veyron_jaq/ROCKCHIP-I2S/HiFi.conf
new file mode 100644
index 00000000..8523a815
--- /dev/null
+++ b/ucm-config/veyron_jaq/ROCKCHIP-I2S/HiFi.conf
@@ -0,0 +1,142 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' off"
+ cset "name='Right Speaker Mixer Right DAC Switch' off"
+ cset "name='Left Speaker Mixer Right DAC Switch' on"
+ cset "name='Right Speaker Mixer Left DAC Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Headphone Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/veyron_jaq/ROCKCHIP-I2S/ROCKCHIP-I2S.conf b/ucm-config/veyron_jaq/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_jaq/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_jaq/RockchipHDMI/HiFi.conf b/ucm-config/veyron_jaq/RockchipHDMI/HiFi.conf
new file mode 100644
index 00000000..bf76d6a6
--- /dev/null
+++ b/ucm-config/veyron_jaq/RockchipHDMI/HiFi.conf
@@ -0,0 +1,12 @@
+SectionVerb {
+ Value {
+ MinBufferLevel "512"
+ }
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "RockchipHDMI HDMI Jack"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+}
diff --git a/ucm-config/veyron_jaq/RockchipHDMI/RockchipHDMI.conf b/ucm-config/veyron_jaq/RockchipHDMI/RockchipHDMI.conf
new file mode 100644
index 00000000..a167d741
--- /dev/null
+++ b/ucm-config/veyron_jaq/RockchipHDMI/RockchipHDMI.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip HDMI card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_jaq/VEYRON-I2S/HiFi.conf b/ucm-config/veyron_jaq/VEYRON-I2S/HiFi.conf
new file mode 100644
index 00000000..2698529d
--- /dev/null
+++ b/ucm-config/veyron_jaq/VEYRON-I2S/HiFi.conf
@@ -0,0 +1,158 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 11"
+ cset "name='ADCL Volume' 11"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ cset "name='Speaker Switch' off"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ OutputDspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ cset "name='Headphone Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,1"
+ JackName "VEYRON-I2S HDMI Jack"
+ JackType "gpio"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+}
diff --git a/ucm-config/veyron_jaq/VEYRON-I2S/VEYRON-I2S.conf b/ucm-config/veyron_jaq/VEYRON-I2S/VEYRON-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_jaq/VEYRON-I2S/VEYRON-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_minnie-kernelnext b/ucm-config/veyron_minnie-kernelnext
new file mode 120000
index 00000000..5fea6bb7
--- /dev/null
+++ b/ucm-config/veyron_minnie-kernelnext
@@ -0,0 +1 @@
+veyron_minnie \ No newline at end of file
diff --git a/ucm-config/veyron_minnie/ROCKCHIP-I2S/HiFi.conf b/ucm-config/veyron_minnie/ROCKCHIP-I2S/HiFi.conf
new file mode 100644
index 00000000..bcfe9157
--- /dev/null
+++ b/ucm-config/veyron_minnie/ROCKCHIP-I2S/HiFi.conf
@@ -0,0 +1,137 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 8"
+ cset "name='ADCL Volume' 8"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Headphone Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/veyron_minnie/ROCKCHIP-I2S/ROCKCHIP-I2S.conf b/ucm-config/veyron_minnie/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_minnie/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_minnie/RockchipHDMI/HiFi.conf b/ucm-config/veyron_minnie/RockchipHDMI/HiFi.conf
new file mode 100644
index 00000000..bf76d6a6
--- /dev/null
+++ b/ucm-config/veyron_minnie/RockchipHDMI/HiFi.conf
@@ -0,0 +1,12 @@
+SectionVerb {
+ Value {
+ MinBufferLevel "512"
+ }
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "RockchipHDMI HDMI Jack"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+}
diff --git a/ucm-config/veyron_minnie/RockchipHDMI/RockchipHDMI.conf b/ucm-config/veyron_minnie/RockchipHDMI/RockchipHDMI.conf
new file mode 100644
index 00000000..a167d741
--- /dev/null
+++ b/ucm-config/veyron_minnie/RockchipHDMI/RockchipHDMI.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip HDMI card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_minnie/VEYRON-I2S/HiFi.conf b/ucm-config/veyron_minnie/VEYRON-I2S/HiFi.conf
new file mode 100644
index 00000000..fd4e6a84
--- /dev/null
+++ b/ucm-config/veyron_minnie/VEYRON-I2S/HiFi.conf
@@ -0,0 +1,158 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 8"
+ cset "name='ADCL Volume' 8"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ cset "name='Speaker Switch' off"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ OutputDspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ cset "name='Headphone Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,1"
+ JackName "VEYRON-I2S HDMI Jack"
+ JackType "gpio"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+}
diff --git a/ucm-config/veyron_minnie/VEYRON-I2S/VEYRON-I2S.conf b/ucm-config/veyron_minnie/VEYRON-I2S/VEYRON-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_minnie/VEYRON-I2S/VEYRON-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_speedy/ROCKCHIP-I2S/HiFi.conf b/ucm-config/veyron_speedy/ROCKCHIP-I2S/HiFi.conf
new file mode 100644
index 00000000..bcfe9157
--- /dev/null
+++ b/ucm-config/veyron_speedy/ROCKCHIP-I2S/HiFi.conf
@@ -0,0 +1,137 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 8"
+ cset "name='ADCL Volume' 8"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ DspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Headphone Switch' on"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headphone Left Switch' off"
+ cset "name='Headphone Right Switch' off"
+ cset "name='Headphone Switch' off"
+ cset "name='Speaker Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:ROCKCHIPI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "ROCKCHIP-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:ROCKCHIPI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
diff --git a/ucm-config/veyron_speedy/ROCKCHIP-I2S/ROCKCHIP-I2S.conf b/ucm-config/veyron_speedy/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_speedy/ROCKCHIP-I2S/ROCKCHIP-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_speedy/RockchipHDMI/HiFi.conf b/ucm-config/veyron_speedy/RockchipHDMI/HiFi.conf
new file mode 100644
index 00000000..bf76d6a6
--- /dev/null
+++ b/ucm-config/veyron_speedy/RockchipHDMI/HiFi.conf
@@ -0,0 +1,12 @@
+SectionVerb {
+ Value {
+ MinBufferLevel "512"
+ }
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ JackName "RockchipHDMI HDMI Jack"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+}
diff --git a/ucm-config/veyron_speedy/RockchipHDMI/RockchipHDMI.conf b/ucm-config/veyron_speedy/RockchipHDMI/RockchipHDMI.conf
new file mode 100644
index 00000000..a167d741
--- /dev/null
+++ b/ucm-config/veyron_speedy/RockchipHDMI/RockchipHDMI.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip HDMI card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/veyron_speedy/VEYRON-I2S/HiFi.conf b/ucm-config/veyron_speedy/VEYRON-I2S/HiFi.conf
new file mode 100644
index 00000000..fd4e6a84
--- /dev/null
+++ b/ucm-config/veyron_speedy/VEYRON-I2S/HiFi.conf
@@ -0,0 +1,158 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ MinBufferLevel "512"
+ FullySpecifiedUCM "1"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Digital EQ 3 Band Switch' off"
+ cset "name='Digital EQ 5 Band Switch' off"
+ cset "name='Digital EQ 7 Band Switch' off"
+ cset "name='Biquad Switch' off"
+ cset "name='Filter Mode' Music"
+ cset "name='ADC Oversampling Rate' 0"
+
+ cset "name='DMIC Mux' DMIC"
+ cset "name='MIC2 Mux' IN34"
+ cset "name='Right ADC Mixer MIC2 Switch' on"
+ cset "name='Left ADC Mixer MIC2 Switch' on"
+ cset "name='MIC2 Volume' 20"
+ cset "name='Headset Mic Switch' off"
+ cset "name='Int Mic Switch' on"
+
+ cset "name='ADCR Boost Volume' 4"
+ cset "name='ADCL Boost Volume' 4"
+ cset "name='ADCR Volume' 8"
+ cset "name='ADCL Volume' 8"
+
+ cset "name='Left Speaker Mixer Left DAC Switch' on"
+ cset "name='Right Speaker Mixer Right DAC Switch' on"
+ cset "name='Speaker Left Mixer Volume' 2"
+ cset "name='Speaker Right Mixer Volume' 2"
+ cset "name='Record Path DC Blocking' on"
+ cset "name='Playback Path DC Blocking' on"
+
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ cset "name='Speaker Switch' off"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ cset "name='Headphone Left Switch' on"
+ cset "name='Headphone Right Switch' on"
+ ]
+
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Speaker".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Speaker"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Left Switch' on"
+ cset "name='Speaker Right Switch' on"
+ cset "name='Speaker Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Speaker Switch' off"
+ cset "name='Speaker Left Switch' off"
+ cset "name='Speaker Right Switch' off"
+ ]
+}
+
+SectionDevice."Internal Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Int Mic"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,0"
+ MixerName "Headphone"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ OutputDspName ""
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='HP Left Out Switch' on"
+ cset "name='HP Right Out Switch' on"
+ cset "name='Headphone Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headphone Switch' off"
+ cset "name='HP Left Out Switch' off"
+ cset "name='HP Right Out Switch' off"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ CapturePCM "hw:VEYRONI2S,0"
+ MixerName "Headset Mic"
+ JackType "gpio"
+ JackName "VEYRON-I2S Headset Jack"
+ }
+
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Int Mic Switch' off"
+ cset "name='DMIC Mux' ADC"
+ cset "name='Headset Mic Switch' on"
+ cset "name='Record Path DC Blocking' on"
+ ]
+
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+
+ cset "name='Headset Mic Switch' off"
+ cset "name='DMIC Mux' DMIC"
+ cset "name='Int Mic Switch' on"
+ cset "name='Record Path DC Blocking' off"
+ ]
+}
+
+SectionDevice."HDMI".0 {
+ Value {
+ PlaybackPCM "hw:VEYRONI2S,1"
+ JackName "VEYRON-I2S HDMI Jack"
+ JackType "gpio"
+ EDIDFile "/sys/class/drm/card1-HDMI-A-1/edid"
+ }
+ EnableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+ DisableSequence [
+ cdev "hw:VEYRONI2S"
+ ]
+}
diff --git a/ucm-config/veyron_speedy/VEYRON-I2S/VEYRON-I2S.conf b/ucm-config/veyron_speedy/VEYRON-I2S/VEYRON-I2S.conf
new file mode 100644
index 00000000..0c399b0d
--- /dev/null
+++ b/ucm-config/veyron_speedy/VEYRON-I2S/VEYRON-I2S.conf
@@ -0,0 +1,6 @@
+Comment "Rockchip card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/wolf/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/wolf/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..8c8d57ed
--- /dev/null
+++ b/ucm-config/wolf/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Wolf internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/wolf/HDA Intel PCH/HiFi.conf b/ucm-config/wolf/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..03f431e5
--- /dev/null
+++ b/ucm-config/wolf/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,55 @@
+SectionVerb {
+ Value {
+ OutputDspName "speaker_eq"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Master Playback Switch' on"
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+
+ cset "name='Capture Switch' on"
+ cset "name='Capture Volume' 39"
+ cset "name='Mic Boost Volume' 2"
+ cset "name='Internal Mic Boost Volume' 0"
+ cset "name='Capture Source' 0"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Headphone".0 {
+ Value {
+ JackName "Headphone Jack"
+ DspName ""
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Speaker Playback Switch' off"
+ cset "name='Headphone Playback Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Headphone Playback Switch' off"
+ cset "name='Speaker Playback Switch' on"
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 1"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Source' 0"
+ ]
+}
diff --git a/ucm-config/zako/HDA Intel PCH/HDA Intel PCH.conf b/ucm-config/zako/HDA Intel PCH/HDA Intel PCH.conf
new file mode 100644
index 00000000..81234e11
--- /dev/null
+++ b/ucm-config/zako/HDA Intel PCH/HDA Intel PCH.conf
@@ -0,0 +1,6 @@
+Comment "Zako internal card"
+
+SectionUseCase."HiFi" {
+ File "HiFi.conf"
+ Comment "Default"
+}
diff --git a/ucm-config/zako/HDA Intel PCH/HiFi.conf b/ucm-config/zako/HDA Intel PCH/HiFi.conf
new file mode 100644
index 00000000..5e280c25
--- /dev/null
+++ b/ucm-config/zako/HDA Intel PCH/HiFi.conf
@@ -0,0 +1,32 @@
+SectionVerb {
+ Value {
+ NoCreateDefaultOutputNode "1"
+ NoCreateDefaultInputNode "1"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ cset "name='Capture Volume' 23"
+ cset "name='Master Playback Switch' on"
+ cset "name='Master Playback Volume' 87"
+ ]
+ DisableSequence [
+ ]
+}
+
+SectionDevice."Mic".0 {
+ Value {
+ JackName "Mic Jack"
+ }
+ EnableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' on"
+ ]
+ DisableSequence [
+ cdev "hw:PCH"
+
+ cset "name='Capture Switch' off"
+ ]
+}
diff --git a/unblocked_terms.txt b/unblocked_terms.txt
deleted file mode 100644
index cba7545a..00000000
--- a/unblocked_terms.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-# KEEP THIS COMMENT IN YOUR COPY.
-#
-# Don't delete this file if you want to keep keyword_check enabled even if it's
-# empty.
-#
-# See repohooks/README.md for more details.
-
-master
-\bnative
-white.?list