TV 输入框架 (TIF) 管理器与音频路由 API 配合使用,以支持灵活的音频路径更改。当系统芯片 (SoC) 实现了 TV 硬件抽象层 (HAL) 时,每个 TV 输入源(HDMI IN、调谐器等)都会提供 TvInputHardwareInfo,以便为音频类型和地址指定 AudioPort 信息。
实体音频输入/输出设备具有相应的 AudioPort。
软件音频输出/输入流表示为 AudioMixPort(AudioPort 的子类)。
然后,TIF 将 AudioPort 信息用于音频路由 API。
图 1. TV 输入框架 (TIF)
要求
SoC 必须通过以下音频路由 API 支持功能来实现音频 HAL:
音频端口
TV 音频输入端口具有相应的音频源端口实现。TV 音频输出端口具有相应的音频接收器端口实现。可在任意 TV 输入音频端口和任意 TV 输出音频端口之间创建音频通路。
默认输入
AudioRecord(使用默认输入源创建)必须在 Android TV 上采集“虚拟 Null 输入源”,以获取 AUDIO_DEVICE_IN_DEFAULT。
设备环回
需要支持 AUDIO_DEVICE_IN_LOOPBACK 输入,这是所有 TV 输出(11 Khz、16bit 单声道或 48 Khz、16bit 单声道)的所有音频输出的完整组合。仅用于音频采集。
/* audio port configuration structure used to specify a particular configuration of an audio port */ structaudio_port_config { audio_port_handle_t id; /* port unique ID */ audio_port_role_t role; /* sink or source */ audio_port_type_t type; /* device, mix ... */ unsignedint config_mask; /* e.g AUDIO_PORT_CONFIG_ALL */ unsignedint sample_rate; /* sampling rate in Hz */ audio_channel_mask_t channel_mask; /* channel mask if applicable */ audio_format_t format; /* format if applicable */ structaudio_gain_configgain;/* gain to apply if applicable */ union { structaudio_port_config_device_extdevice;/* device specific info */ structaudio_port_config_mix_extmix;/* mix specific info */ structaudio_port_config_session_extsession;/* session specific info */ } ext; }; structaudio_port { audio_port_handle_t id; /* port unique ID */ audio_port_role_t role; /* sink or source */ audio_port_type_t type; /* device, mix ... */ unsignedint num_sample_rates; /* number of sampling rates in following array */ unsignedint sample_rates[AUDIO_PORT_MAX_SAMPLING_RATES]; unsignedint num_channel_masks; /* number of channel masks in following array */ audio_channel_mask_t channel_masks[AUDIO_PORT_MAX_CHANNEL_MASKS]; unsignedint num_formats; /* number of formats in following array */ audio_format_t formats[AUDIO_PORT_MAX_FORMATS]; unsignedint num_gains; /* number of gains in following array */ structaudio_gaingains[AUDIO_PORT_MAX_GAINS]; structaudio_port_configactive_config;/* current audio port configuration */ union { structaudio_port_device_extdevice; structaudio_port_mix_extmix; structaudio_port_session_extsession; } ext; };
structaudio_hw_device { : /** * Routing control */
/* Creates an audio patch between several source and sink ports. * The handle is allocated by the HAL and should be unique for this * audio HAL module. */ int (*create_audio_patch)(struct audio_hw_device *dev, unsignedint num_sources, conststruct audio_port_config *sources, unsignedint num_sinks, conststruct audio_port_config *sinks, audio_patch_handle_t *handle);
/* Release an audio patch */ int (*release_audio_patch)(struct audio_hw_device *dev, audio_patch_handle_t handle);
/* Fills the list of supported attributes for a given audio port. * As input, "port" contains the information (type, role, address etc...) * needed by the HAL to identify the port. * As output, "port" contains possible attributes (sampling rates, formats, * channel masks, gain controllers...) for this port. */ int (*get_audio_port)(struct audio_hw_device *dev, struct audio_port *port);
/* Set audio port configuration */ int (*set_audio_port_config)(struct audio_hw_device *dev, conststruct audio_port_config *config);
测试 DEVICE_IN_LOOPBACK
如需测试用于 TV 监控的 DEVICE_IN_LOOPBACK,请使用以下测试代码。运行测试后,采集到的音频将保存到 /sdcard/record_loopback.raw 中,您可以使用 FFmpeg 收听。