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.

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.

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.

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.

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.

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.

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.

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);