logo
Video Call
On this page

Game Voice

2024-09-27

Feature Overview

Concept Explanation

  • Range: The range within which a listener receives audio.
  • Orientation: Refers to the listener's position and facing direction in the game world coordinates. For details, please refer to Set the listener's current position.
  • Listener: A user in the room who receives audio.
  • Speaker: A user in the room who sends audio.

Feature Description

Starting from version 2.11.0, ZEGO Express SDK has added a game voice module, mainly including: range voice, 3D audio effects, and team voice.

FeatureDescription

Range Voice

Listeners in the room have range limitations on the distance at which they can receive audio. If a speaker is beyond that range, they cannot be heard. To ensure voice clarity, when more than 20 people nearby are speaking, only the 20 closest speakers can be heard.

Assuming the maximum audio receiving range is set to R, and the distance between the speaker and the listener is r, then:

  • When r < R, it means the speaker is within the normal range, and the listener can hear the sound.
  • When r ≥ R, it means the speaker is beyond the maximum range, and the listener cannot hear the sound.

The above image only takes the range voice mode as "World" as an example. For more sound reachability under different mode combinations, please refer to Set Common Voice Mode.

3D Audio EffectsSound has 3D spatial sense and attenuates with distance.

Common Voice Mode

Players can choose to join a team and support freely switching between "World", "Team Only", and "Secret Team" voice modes within the room.

  • World: Players can communicate with other players in the world, and can also communicate with teammates.
  • Team Only: Players can only communicate with teammates.
  • Secret Team: Players can communicate with teammates, and can only hear voice from other players in the world range.
Note
  • Communication between teammates is not affected by "range" and "3D audio effects". For details, please see Set Common Voice Mode.
  • If you want to customize voice send/receive capabilities, please refer to Set Custom Voice Mode.

Application Scenarios

Game voice features are suitable for battle royale games and metaverse scenarios.

In battle royale games, team voice provides team functionality. Teams can be changed before and after the game starts. Developers do not need to focus on stream grouping and publish/play stream implementation, directly implementing team voice functionality.

In battle royale games and metaverse scenarios, 3D audio effects are provided. When listening to speaker audio effects, there is a sense of direction and distance, making the scene feel more realistic.

Example Source Code Download

Please refer to Download Example Source Code to get the source code.

For related source code, please check the files in the "/ZegoExpressExample/Examples/AdvancedAudioProcessing/RangeAudio" directory.

Prerequisites

Before implementing range voice, please ensure:

Precautions

Warning

Please pay close attention to the following precautions when using the range voice feature to avoid integration issues.

If you are already using ZEGO Express SDK's real-time audio and video functionality, please note the following:

  • Since the range voice module is implemented based on ZegoExpressEngine's publish/play stream interfaces, you don't need to focus on the concept of publish/play streams when using it. In range voice scenarios, the concept of publishing audio stream becomes "enable microphone", and the concept of playing audio stream becomes "enable speaker". It is recommended not to use startPublishingStream and startPlayingStream interfaces for publish/play stream operations while integrating the range voice feature to avoid effect conflicts.
  • Publish/play stream related callbacks in the range voice module (onPublisherStateUpdate, onPlayerStateUpdate, onPublisherQualityUpdate, and onPlayerQualityUpdate) will no longer take effect.

Usage Steps

The above image only shows the core steps and interfaces for implementing game voice functionality. Developers can refer to the detailed introduction in the following documentation according to business needs and implement other related interfaces.

1 Create Engine

Call the createEngine interface, pass the obtained AppID and AppSign into the parameters "appID" and "appSign", and create an engine singleton object. The engine currently only supports creating one instance at a time. Beyond that, it will return null.

/** Define SDK engine object */
ZegoExpressEngine engine;

ZegoEngineProfile profile = new ZegoEngineProfile();
/** Please obtain through official website registration, format is 123456789L */
profile.appID = appID;
/** 64 characters, please obtain through official website registration, format is "0123456789012345678901234567890123456789012345678901234567890123" */
profile.appSign = appSign;
/** General scenario access, please choose the appropriate scenario according to actual situation */
profile.scenario = ZegoScenario.DEFAULT;
/** Set app's application object */
profile.application = getApplication();
/** Create engine */
engine = ZegoExpressEngine.createEngine(profile, null);

2 Create Range Voice Module

Call the createRangeAudio method to create a range voice instance.

ZegoRangeAudio rangeAudio = engine.createRangeAudio();
if (rangeAudio == null) {
    printf("Failed to create range voice instance module");
}

3 Listen to Range Voice Event Callbacks

You can call the setEventHandler interface as needed to set event callbacks for the microphone, used to listen to microphone enable state onRangeAudioMicrophoneStateUpdate notifications.

// set range audio event handler
rangeAudio.setEventHandler(new IZegoRangeAudioEventHandler() {
    @Override
    public void onRangeAudioMicrophoneStateUpdate(ZegoRangeAudio rangeAudio, ZegoRangeAudioMicrophoneState state, int errorCode) {
        super.onRangeAudioMicrophoneStateUpdate(rangeAudio, state, errorCode);
        AppLogger.getInstance().callApi("microphone state update. state: %s, errorCode: %d", state, errorCode);
    }
});

4 Login to Room

After creating a ZegoUser user object by passing in the user ID parameter userID and userName, call the loginRoom interface, passing in the room ID parameter roomID and user parameter user, to log in to the room.

Warning
  • Within the same AppID, ensure that roomID is globally unique.
  • Within the same AppID, ensure that userID is globally unique. It is recommended that developers set it to a meaningful value and associate userID with their own business account system.
  • userID cannot be empty, otherwise it will cause room login failure.
/** Create user */
ZegoUser user = new ZegoUser("user1");

/** Start logging in to room */
engine.loginRoom("room1", user);
Note

When a user has successfully logged in to a room, if the application exits abnormally, after restarting the application, developers need to first call the logoutRoom interface to exit the room, then call the loginRoom interface to log in to the room again.

5 Set the Listener's Current Position

Developers can call the updateSelfPosition interface to set the listener's own position and orientation, or update their position and facing direction in the world coordinate system when their own orientation changes.

Note
  • If this interface is not called to set position information before calling enableSpeaker to enable the speaker, you will not be able to receive sound from anyone other than teammates.
  • The coordinate values of the three axes of your own coordinate system can be obtained through the rotation angle conversion matrix of a third-party 3D engine.
Parameter NameDescription
positionYour coordinates in the world coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
axisForwardThe unit vector of the forward axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
axisRightThe unit vector of the right axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
axisUpThe unit vector of the up axis of your coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
// Your coordinates in the world coordinate system, in the order of front, right, up.
float[] position = new float[]{100.0, 100.0, 100.0};
// Unit vector of your forward facing direction in your coordinate system.
float[] axisForward = new float[]{1.0,0.0,0.0};
// Unit vector of your right facing direction in your coordinate system.
float[] axisRight = new float[]{0.0,1.0,0.0};
// Unit vector of your up facing direction in your coordinate system.
float[] axisUp = new float[]{0.0,0.0,1.0};

rangeAudio.updateSelfPosition(position, axisForward, axisRight, axisUp);

6 Add or Update Speaker Position Information

After successfully logging in to the room, you need to call the updateAudioSource interface to add or update speaker position information.

Warning
  • In World mode: Need to update the positions of the listener and all speakers in the room. In Secret Team mode: Need to update the positions of all speakers in the room who are within the audio receiving range and in World mode. If speaker positions are not set, or if speakers are beyond the listener's range, there will be situations where sound cannot be heard.
  • Here, speakers refer to other people in the room, and listeners refer to yourself.
  • userID: The ID of other speaking users in the room.
  • position: The speaker's coordinates in the world coordinate system. The parameter is a float array of length 3. The three values represent the coordinate values of front, right, and up in order.
// User coordinates in the world coordinate system, in the order of front, right, up.
float[] position = new float[]{100.0, 100.0, 100.0};
// Add/update user position
rangeAudio.updateAudioSource("abc",position);

7 (Optional) Set Audio Receiving Range

Call the setAudioReceiveRange interface to set the maximum range at which the listener receives audio distance, that is, taking yourself as the starting point, the set distance as a three-dimensional space in 3D space. After setting this range, when 3D audio effects are enabled, the sound will attenuate as distance increases until it exceeds the set range, at which point there will be no more sound.

// Set the maximum range for audio receiving distance. Sounds beyond this range will not be heard
rangeAudio.setAudioReceiveRange(1000);

You can also further control the attenuation range through the setAudioReceiveRange interface. When the distance is less than min, the volume will not attenuate as distance increases; when the distance is greater than max, you will not be able to hear the other party's sound.

// Set the attenuation range interval for 3D audio effects [min, max]
ZegoReceiveRangeParam param = new ZegoReceiveRangeParam();
param.min = reciveRangeMin;
param.max = reciveRangeMax;
rangeAudio.setAudioReceiveRange(param);
Note

If the audio receiving distance is not set, it means you can only receive voices from within your own team and cannot receive all sounds outside the team. After setting, voice within the team will not be limited by the audio receiving distance and will not have 3D audio effects.

8 (Optional) Implement 3D Audio Effects

Enable 3D Audio Effects

Call the enableSpatializer interface to set 3D audio effects. When enable is true, it means 3D audio effects are enabled. At this time, the audio of non-team members in the room will produce spatial changes as the speaker's distance and direction from you changes. When it is false, it means 3D audio effects are disabled. (Can be enabled or disabled at any time)

Warning

This function only takes effect for people outside the team.

rangeAudio.enableSpatializer(true);

Set 3D Audio Effects for Local Players

Developers can use media player or audio effect player as sound sources and set their positions in the world coordinate system. This function can be applied to playing background music at a specified position in a virtual world scene, giving it 3D audio effects.

  1. Call the enableSpatializer interface to enable 3D audio effects.
  2. Set 3D audio effects for local players
// Enable 3D audio effects, this step is a prerequisite
rangeAudio.enableSpatializer(true);

// Set the position of local players
// Media Player
// 1. Create media player
ZegoMediaPlayer mediaPlayer = engine.createMediaPlayer();
// 2. Set the media player's position in the world coordinate system
float [] mediaPlayerPosition = new float[3];
mediaPlayer.updatePosition(mediaPlayerPosition);
// 3. Use media player to load media resources
ZegoMediaPlayerResource resource = new ZegoMediaPlayerResource();
resource.loadType = ZegoMultimediaLoadType.FILE_PATH;
resource.filePath = "path";
mediaPlayer.loadResourceWithConfig(resource, new IZegoMediaPlayerLoadResourceCallback() {
    @Override
    public void onLoadResourceCallback(int errorCode) {
        if (errorCode == 0)
            mediaPlayer.start();
    }
});

// Audio Effect Player
// 1. Create audio effect player
ZegoAudioEffectPlayer audioEffectPlayer = engine.createAudioEffectPlayer();
// 2. Start playing audio effect resources
int effectSoundID = 1;
String path = "path";
audioEffectPlayer.start(effectSoundID, path, null);
// 3. After receiving [onAudioEffectPlayStateUpdate] callback with state ZegoAudioEffectPlayState.Playing
//    Set the audio effect player's position in the world coordinate system
float [] audioEffectPlayerPosition = new float[3];
audioEffectPlayer.updatePosition(effectSoundID, audioEffectPlayerPosition);

9 Enable Microphone and Speaker

After successfully logging in to the room:

  • Call the enableMicrophone interface to set whether to enable the microphone. When enable is true, it means enabled, and the SDK will automatically use the main channel to publish audio stream. When it is false, it means disabled. (Can be enabled or disabled at any time)

    Developers can listen to the onRangeAudioMicrophoneStateUpdate event callback to get the updated microphone state.

  • Call the enableSpeaker interface to set whether to enable the speaker. When enable is true, it means enabled, and the SDK will automatically pull audio streams within the room. When it is false, it means disabled. (Can be enabled or disabled at any time)

Warning

After calling the enableSpeaker interface, when the maximum number of play streams is exceeded (currently 20), it will prioritize pulling team member audio streams (team mode needs to be set), then pull world audio streams closest to your own range.

// Enable microphone
rangeAudio.enableMicrophone(true);
// Enable speaker
rangeAudio.enableSpeaker(true);

10 (Optional) Join Team and Set Voice Mode

Join Team

Call the setTeamID interface to set the team ID you want to join as needed (ID can be changed at any time). After setting the ID, you can directly join. After joining a team, communication with teammates in the same team is not limited by range voice and 3D audio effects.

rangeAudio.setTeamID("123");

Set Common Voice Mode

Call the setRangeAudioMode interface to set the range voice mode (can switch modes at any time). When the mode parameter is ZegoRangeAudioModeWorld or ZegoRangeAudioSecretTeam, it means you can hear the voices of all people in World mode. When it is ZegoRangeAudioModeTeam, it means you can only hear the voices of other members in the same team.

Voice ModeParameter ValueFeature Description
WorldWORLDAfter setting this mode, this user can communicate with team members and can also communicate with people in World mode within range.
Team OnlyTEAMAfter setting this mode, this user can only communicate with team members.
Secret TeamSECRET_TEAMAfter setting this mode, this user can communicate with team members and can only receive voice from people in World mode within range.
rangeAudio.setRangeAudioMode(ZegoRangeAudioMode.WORLD);

Under different range voice modes, the receivability of speaker voices varies.

  • Assuming user A's mode is "World", the sound receivability of user B under different range voice modes is as follows:
Same TeamWithin Maximum RangeRange Voice ModeCan A Hear B's Voice?Can B Hear A's Voice?
YesYesWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoYesWorldYesYes
Team OnlyNoNo
Secret TeamNoYes
NoWorldNoNo
Team OnlyNoNo
Secret TeamNoNo
  • Assuming user A's mode is "Team Only", the sound receivability of user B under different range voice modes is as follows:
Same TeamWithin Maximum RangeRange Voice ModeCan A Hear B's Voice?Can B Hear A's Voice?
YesYesWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoYesWorldNoNo
Team OnlyNoNo
Secret TeamNoNo
NoWorldNoNo
Team OnlyNoNo
Secret TeamNoNo
  • Assuming user A's mode is "Secret Team", the sound receivability of user B under different range voice modes is as follows:
Same TeamWithin Maximum RangeRange Voice ModeCan A Hear B's Voice?Can B Hear A's Voice?
YesYesWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoWorldYesYes
Team OnlyYesYes
Secret TeamYesYes
NoYesWorldYesNo
Team OnlyNoNo
Secret TeamNoNo
NoWorldNoNo
Team OnlyNoNo
Secret TeamNoNo

Set Custom Voice Mode

Warning
  • Custom voice mode and common voice mode cannot be used simultaneously.
  • If you need to use custom voice mode, please ensure that all online users in game voice use Express SDK version 3.3.0 or higher.

Through custom voice mode, you can freely control audio send/receive logic to complete various audio interactions. An example is as follows: Assuming A, B, and C are members of the same team, and C is within A's receiving range, you can achieve the expected audio experience through the configuration in the table

UserSpeaking ExpectationListening ExpectationSpeaking Mode ConfigurationListening Mode ConfigurationRemarks
 ASend audio to team members and other users within rangeReceive audio from team members and other users within rangeAllAllA can communicate with both B and C
BSend audio only to team membersReceive audio only from team membersTeamTeamB can only communicate with A
CSend audio only to users within rangeReceive audio only from users within rangeWorldWorldC can only communicate with A
rangeAudio.setRangeAudioCustomMode(ZegoRangeAudioSpeakMode.ALL, ZegoRangeAudioListenMode.ALL);

11 Destroy Range Voice Module

When the range voice module is no longer needed, you can call the destroyRangeAudio interface to destroy it and release the resources occupied by the range voice module.

engine.destroyRangeAudio(rangeAudio);

12 Exit Room

Call the logoutRoom interface to exit the room. After exiting, the microphone and speaker will be automatically turned off (i.e., you cannot send your own audio or hear other people's audio), and the speaker information list will be cleared.

// Exit room
engine.logoutRoom("roomID");

FAQ

  1. How many streams can be played simultaneously within the listening range at most?

To ensure voice clarity, when more than 20 people nearby are speaking, you can only hear the voices of the 20 closest speakers. If there are more than 20 people and the distance is the same, the order is determined by the order in which each userID was first passed when calling the updateAudioSource interface.

  1. Does the "range" in range voice refer to the listening range or the speaking range?

The "range" in range voice refers to the listening range.

  1. Do team members in team voice have 3D audio effects when communicating?

Voice within the team has the effect of normal communication; there are currently no 3D audio effects.

  1. If I am already calling the publish stream interface, will there be conflicts when using range voice?

Range voice currently uses the main channel to send audio. If the client has already used the main channel, there will be conflicts.

Previous

Audio and Video Stream Encryption

Next

Mass-Scale Range Audio and Video