Create a PCM subchannel mixer
#include <audio_driver.h> ado_pcm_subchn_mixer_t *ado_pcm_subchn_mixer_create ( ado_pcm_subchn_t *subchn, ado_mixer_t *mixer, ado_pcm_subchn_mixer_config_t *config );
The ado_pcm_subchn_mixer_create() function is a convenience function for creating mixer elements and callbacks for volume control of a PCM subchannel device. If your audio chip supports more than one simultaneous subchannel, and has gain and or mute controls for each subchannel, this convenience function will simplify their control.
typedef struct ado_pcm_subchn_mixer_config { HW_CONTEXT_T *hw_context; PCM_SUBCHN_CONTEXT_T *pcm_sc_context; uint32_t channel_mask; uint32_t volume_jointly:1; snd_mixer_element_volume1_range_t volume_range; uint32_t mute_jointly:1; void (*volume_set) (HW_CONTEXT_T * hw_context, PCM_SUBCHN_CONTEXT_T * pcm_sc_context, int32_t * volumes, int32_t mute, ado_pcm_subchn_mixer_config_t *config); void (*mute_set) (HW_CONTEXT_T * hw_context, PCM_SUBCHN_CONTEXT_T * pcm_sc_context, int32_t * volumes, int32_t mute, ado_pcm_subchn_mixer_config_t *config); } ado_pcm_subchn_mixer_config_t;
A pointer to the new subchn mixer, or NULL if an error occurred (errno is set).
The ado_pcm_subchn_mixer_t structure is an opaque data type. You'll need a pointer to it when you call ado_pcm_subchn_mixer_destroy() to destroy the subchannel mixer. |
This example of how to setup a subchannel mixer is taken from the vortex driver. Due to legal restrictions, the full source to the vortex driver isn't availiable in the DDK. The vortex has individual volume and mute controls for each channel of the stereo stream. The volume controls have a range of 0 to 255 settings, corresponding to a decibel range of -102.35 dB to 0 dB.
The vortex hardware functions, vortex_mixer_input_gain() and vortex_mixer_input_mute() set the hardware volume and mute. But in order to work, those functions need to know which hardware mixer and which mixer input the signals are routed through, so this information is kept in the PCM_SUBCHN_CONTEXT_T *vsc variable.
static void vortex_subchn_volume_set( HW_CONTEXT_T * vortex, PCM_SUBCHN_CONTEXT_T * vsc, int32_t * volumes, int32_t mute, ado_pcm_subchn_mixer_config_t * config) { if (vortex->card_type == VORTEX_CARD_TYPE_AU8830) { vortex_mixer_input_gain_8830 (vortex, vsc->mixL, vsc->mixinL, volumes[0]); vortex_mixer_input_gain_8830 (vortex, vsc->mixR, vsc->mixinR, volumes[1]); } else { vortex_mixer_input_gain_8820 (vortex, vsc->mixL, vsc->mixinL, volumes[0]); vortex_mixer_input_gain_8820 (vortex, vsc->mixR, vsc->mixinR, volumes[1]); } } static void vortex_subchn_mute_set (HW_CONTEXT_T * vortex, PCM_SUBCHN_CONTEXT_T * vsc, int32_t * volumes, int32_t mute, ado_pcm_subchn_mixer_config_t * config) { if (vortex->card_type == VORTEX_CARD_TYPE_AU8830) { vortex_mixer_input_mute_8830 (vortex, vsc->mixL, vsc->mixinL, mute & (1 << 0)); vortex_mixer_input_mute_8830 (vortex, vsc->mixR, vsc->mixinR, mute & (1 << 1)); } else { vortex_mixer_input_mute_8820 (vortex, vsc->mixL, vsc->mixinL, mute & (1 << 0)); vortex_mixer_input_mute_8820 (vortex, vsc->mixR, vsc->mixinR, mute & (1 << 1)); } } int32_t vortex_playback_aquire (HW_CONTEXT_T * vortex, PCM_SUBCHN_CONTEXT_T ** vsc, ado_pcm_config_t * config, ado_pcm_subchn_t * subchn, uint32_t * why_failed) { … memset (&vsc_mix_cfg, 0, sizeof (vsc_mix_cfg)); vsc_mix_cfg.hw_context = vortex; vsc_mix_cfg.pcm_sc_context = *vsc; vsc_mix_cfg.channel_mask = SND_MIXER_CHN_MASK_STEREO; vsc_mix_cfg.volume_range.min = 0; vsc_mix_cfg.volume_range.max = 0xff; vsc_mix_cfg.volume_range.min_dB = -10235; vsc_mix_cfg.volume_range.max_dB = 0; vsc_mix_cfg.volume_set = vortex_subchn_volume_set; vsc_mix_cfg.mute_set = vortex_subchn_mute_set; if (((*vsc)->scmix = ado_pcm_subchn_mixer_create ( subchn, vortex->mixer, &vsc_mix_cfg)) == NULL) { return (ENOMEM); } … } int32_t vortex_playback_release (HW_CONTEXT_T * vortex, PCM_SUBCHN_CONTEXT_T * vsc, ado_pcm_config_t * config) { … ado_pcm_subchn_mixer_destroy (vsc->scmix); … }
QNX Neutrino
Safety: | |
---|---|
Cancellation point | No |
Interrupt handler | No |
Signal handler | No |
Thread | No |
ado_pcm_subchn_mixer_destroy()