Audio Volume

The purpose of this document is to introduce the concept and functionalities of Audio Volume, its implementation details in the Audio Subsystem, as well as the volume control flow between the Audio Volume and the application layer.

Volume control is one of the fundamental features of the Audio Subsystem. The Audio Subsystem design incorporates volume adjustment capabilities for basic audio data streams, such as playback, voice communication and record streams. Furthermore, for specialized use cases like notification sounds, ambient sound transparency, AUX audio looping, and audio codec format conversion, the Audio Subsystem provides a series of APIs within relevant software modules to support volume control. Additionally, the Audio Subsystem supports volume balancing functionalities. The arrows in the diagram below illustrate the interactions among the modules related to volume control within the Audio Subsystem.

../../../_images/audio_subsystem_architecture4.png

Audio Subsystem Architecture

Overview

The Audio Subsystem’s volume control functionality is designed with clear boundary definitions. From the application layer’s perspective, the volume is categorized into different levels, allowing users to switch between these levels to control volume in real-time. These levels are ultimately converted into a 16-bit signed integer representing the gain value, which is then sent to the DSP by the Audio Path module at the appropriate time. The Audio Path module manages the lifecycle and control timing of all audio data streams, thus allowing precise control of the gain. The following diagram provides a simple description of this work flow.

../../../_images/audio_volume_overview.png

Audio Volume Overview

Technically, the Audio Subsystem uses a 16-bit signed integer to represent the gain value, with the unit being 1/128 dB. For instance, the 16-bit signed integer 0xFF80 represents a gain of -1 dB.

The gain value associated with each level must be specified by the application layer, and there are two methods to achieve this. One method is through the DSPConfig Tool, where settings can be configured directly, as shown in the diagram below. The other method involves using the APIs provided by Audio Route module to register a callback, where the specific implementation of the callback will determine the gain values. Please refer to the Audio Route for more details.

../../../_images/DspCfgTool_GainSetting.png

DSPConfigTool Gain Setting

Volume Settings

The Audio Subsystem allows for volume setting on various categories of data streams. However, due to some categories supporting only single instance and others supporting multiple instances, there are slight differences in the internal implementation within the Audio Subsystem. Here, we use Voice Prompt AUDIO_CATEGORY_VP and playback AUDIO_CATEGORY_AUDIO as examples to explain these differences.

Voice Prompt Volume Settings

Since Voice Prompt only supports a single instance, its volume adjustment process is relatively simple. The application calls voice_prompt_volume_set() to set a volume out level. Then the Notification module will call the interface provided by the lower level Audio Path module if the Voice Prompt is not muted. Finally, the converted DAC gain value will be passed to the DSP to make the volume setting work.

../../../_images/audio_volume_vp_volume_set.png

Voice Prompt Volume Settings

Playback Volume Settings

Since the playback supports multiple instances, its volume adjustment process is relatively more complex compared to Voice Prompt. This involves two modules: Audio Volume and Audio Track. Additionally, because events are thrown to the application layer during the volume adjustment process, the Audio Manager module is also involved.

The Audio Volume module provides a set of APIs for controlling Audio Stream volume. The supported Audio Stream types are defined in the T_AUDIO_STREAM_TYPE enumeration. The Audio Volume module manages the global volume levels for all types of Audio Streams. Additionally, the Audio Track module offers a simliar set of APIs to adjust the volume levels for individual Audio Track instances of a specific Audio Stream type.

As shown in the diagram below, the overall process is similar to that of the Voice Prompt. It should be noted that the Audio Track module will iterate through the playback Audio Track instances in the system, setting the gain value for each instance individually. Additionally, if the volume adjustment for the playback is successful, the application layer will receive an event containing both the current effective level and the previous level. This information is useful for the application layer to facilitate further user interactions.

../../../_images/audio_volume_playback_volume_set.png

Playback Volume Settings

Volume Balance

Sometimes end users, especially those with hearing impairments, need to adjust the left and right volume to achieve a satisfactory listening experience. The Audio Subsystem provides a volume balancing function to meet this need. This function is applicable to music playback, voice communications and notifications. End users can specify an appropriate scaling factor to shift the final output volume towards the left or right channel, as illustrated in the diagram below.

../../../_images/audio_volume_balance_ui.png

Volume Balance User Interface

Technically, the volume balance is a specical form of volume adjustment. It works by keeping the volume of one channel unchanged while reducing the volume of the other channel by a certain scaling factor. This scaling factor is represented as a floating-point number between -1.0 and +1.0 and is specified by the application layer based on user’s requirements. The default value of this scaling factor is 0, which means the volume balance effect is not applied by default. If the user wants to shift the volume to the left, the scaling factor should be between -1.0 and 0. If the user wants to shift the volume to the right, the scaling factor should be between 0 and +1.0. The diagram below shows the internal implementation of the volume balance scaling adjustment.

../../../_images/audio_volume_balance_scale_flow.png

Volume Balance Scaling Flow

Below are the APIs related to volume balance. As indicated by their naming, these APIs allow you to get or set the current volume balance scaling factor in runtime. This group of APIs can only be used for the AUDIO_STREAM_TYPE_PLAYBACK and AUDIO_STREAM_TYPE_VOICE types. For Voice Prompts and Ringtones, the Audio Subsystem also provides similar functionality APIs.

float audio_volume_balance_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_balance_set(T_AUDIO_STREAM_TYPE type, float scale);

It should be noted that both the level value of the volume and the scaling factor of the volume balance are specified by the application, with no specific order of precedence required between them. The application can adjust the volume level value multiple times through the API audio_volume_out_set() and then call the API audio_volume_balance_set() to specify the scaling factor. The Audio Subsystem will remember each level value specified by the application and always perform the scaling adjustment based on the most recently specified level value to achieve the volume balance effect.

API Usage

The APIs provided by the Audio Volume module can be divided into 2 groups according to different setting directions:

  • The volume out level access.

  • The volume in level access.

Volume Out Level Access

This group of APIs can be used for the AUDIO_STREAM_TYPE_PLAYBACK and AUDIO_STREAM_TYPE_VOICE types. As indicated by their naming, these APIs allow you to access the maximum and minimum volume output level, check or adjust the current volume output level, and mute or unmute the current volume output level.

uint8_t audio_volume_out_max_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_out_max_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

uint8_t audio_volume_out_min_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_out_min_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

uint8_t audio_volume_out_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_out_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

bool audio_volume_out_mute(T_AUDIO_STREAM_TYPE type);

bool audio_volume_out_unmute(T_AUDIO_STREAM_TYPE type);

bool audio_volume_out_is_muted(T_AUDIO_STREAM_TYPE type);

Volume In Level Access

This group of APIs can be used for the AUDIO_STREAM_TYPE_RECORD and AUDIO_STREAM_TYPE_VOICE types. As indicated by their naming, these APIs allow you to access the maximum and minimum volume input level, check or adjust the current volume input level, and mute or unmute the current volume input level.

uint8_t audio_volume_in_max_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_in_max_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

uint8_t audio_volume_in_min_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_in_min_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

uint8_t audio_volume_in_get(T_AUDIO_STREAM_TYPE type);

bool audio_volume_in_set(T_AUDIO_STREAM_TYPE type, uint8_t volume);

bool audio_volume_in_mute(T_AUDIO_STREAM_TYPE type);

bool audio_volume_in_unmute(T_AUDIO_STREAM_TYPE type);

bool audio_volume_in_is_muted(T_AUDIO_STREAM_TYPE type);