This website uses cookies to improve our services and deliver relevant ads.
By interacting with this site, you agree to this use. For more information, see our Cookies Policy
Use the Platform VoIP service to add voice chat to your app.
The VoIP service transmits PCM (pulse-code modulation) data between users that the Platform SDK decodes to audio.
VoIP is peer-to-peer so your app will limited by bandwidth in most cases. In general, the VoIP service becomes unstable if you have 12, or more, connections. We recommend no more than 8 connections on Rift and 4 on Gear VR. You may be able to support more if you use push to talk or some proximity type muting.
If you're building a Gear VR app, please review Parties for information about supporting Party VoIP.
To integrate Application VoIP in your Native application, follow the steps below. The methods can be called from your client app.
Send a VoIP connection request:
Native - ovr_Voip_Start()
Unity - Platform.Voip.Start()
Initiate a VoIP connection request. Review the ovr_Voip_Start page for information about the parameters and return data structure.
Accept a VoIP connection request:
Native - ovr_Voip_Accept()
Unity - Platform.Voip.Accept()
Accept a VoIP connection request. Review the ovr_Voip_Accept page for information about the parameters and return data structure.
Retrieve the maximum size of the buffer:
Native - ovr_Voip_GetOutputBufferMaxSize()
Unity - Platform.Voip.GetOutputBufferMaxSize()
Retrieve the size of the internal ringbuffer used by the VoIP system in elements. This size is the maximum number of elements that can ever be returned by ovr_Voip_GetPCM or ovr_Voip_GetPCMFloat. Review the ovr_Voip_GetOutputBufferMaxSize page for information about the parameters and return data structure.
Retrieve PCM data from a user (16 bit fixed point):
Native - ovr_Voip_GetPCM()
Unity - Platform.Voip.GetPCM()
Retrieve all available samples of voice data from a specified user and copy them into the outputBuffer. The VoIP system will generate data at roughly the rate of 480 samples per 10ms. This function should be called every frame with 50ms (2400 elements) of buffer size to account for frame rate variations. The data format is 16 bit fixed point 48khz mono.
Review the ovr_Voip_GetPCM page for information about the parameters and return data structure.
Retrieve PCM data from a user (32 bit floating point):
Native - ovr_Voip_GetPCMFloat()
Unity - Platform.Voip.GetPCMFloat()
Retrieve all available samples of voice data from a specified user and copy them into the outputBuffer The VoIP system will generate data at roughly the rate of 480 samples per 10ms. This function should be called every frame with 50ms (2400 elements) of buffer size to account for frame rate variations. The data format is 32 bit floating point 48khz mono.
Review the ovr_Voip_GetPCMFloat page for information about the parameters and return data structure.
We do not recommend using the floating point methods unless necessary. This operation requires additional resources when compared to the integer based process.
Retrieve the number of PCM data files available:
Native - ovr_Voip_GetPCMSize()
Unity - Platform.Voip.GetPCMSize()
Retrieve the current number of audio samples available to read from a specified user. This function is inherently racy, it's possible that data can be added between a call to this function and a subsequent call to ovr_Voip_GetPCM or ovr_Voip_GetPCMFloat.
Review the ovr_Voip_GetPCMSize page for information about the parameters and return data structure.
Retrieve PCM data with a timestamp from a user (16 bit fixed point):
Native - ovr_Voip_GetPCMWithTimestamp()
Unity - Platform.Voip.GetPCMWithTimestamp()
Like ovr_Voip_GetPCM, this function copies available audio samples from a specified user into a buffer. Along with the audio samples, this function also stores the timestamp of the first sample in the output parameter timestamp. This timestamp can be used for synchronization, see ovr_Voip_GetSyncTimestamp for more details. The data format is 16 bit fixed point 48khz mono.
This function may return data early, even if there's more data available, to keep the batch of audio samples returned with a single timestamp small. For example, if 30ms worth of audio is in the buffer, this function may return 480 samples (10ms) each time it's called. Therefore, it's recommended to call this as long as there's data in the buffer (i.e. the function returns a non-zero result).
Review the ovr_Voip_GetPCMWithTimestamp page for information about the parameters and return data structure.
Retrieve PCM Data with a timestamp from a user (32 bit floating point):
Native - ovr_Voip_GetPCMWithTimestampFloat()
Unity - Platform.Voip.GetPCMWithTimestampFloat()
Like ovr_Voip_GetPCMFloat, this function copies available audio samples from a specified user into a buffer. Along with the audio samples, this function also stores the timestamp of the first sample in the output parameter timestamp. This timestamp can be used for synchronization, see ovr_Voip_GetSyncTimestamp for more details. The data format is 32 bit floating point 48khz mono.
This function may return data early, even if there's more data available, in order to keep the batch of audio samples with a single timestamp small. For example, if there's 30ms worth of audio in the buffer, this function may return 480 samples (10ms) each time it's called. Therefore, it's recommended to call this as long as there's data in the buffer (i.e. the function returns a non-zero result).
Review the ovr_Voip_GetPCMWithTimestampFloat page for information about the parameters and return data structure.
We do not recommend using the floating point methods unless necessary. This operation requires additional resources when compared to the integer based process.
Retrieve the sync timestamp for the sender:
Native - ovr_Voip_GetSyncTimestamp()
Unity - Platform.Voip.GetSyncTimestamp()
Returns a timestamp used for synchronizing audio samples sent to the given user with an external data stream.
Timestamps associated with audio frames are implicitly transmitted to remote peers; on the receiving side, they can be obtained by using ovr_Voip_GetPCMWithTimestamp. ovr_Voip_GetSyncTimestamp is used to fetch those timestamps on the sending side. An application can insert the value returned by this function into each data packet and compare it to the value returned by GetPCMWithTimestamp on the receiving side to determine the ordering of two events (sampling audio and composing a data packet).
This function assumes that a voice connection to the user already exists; it returns 0 if that isn't the case.
Review the ovr_Voip_GetSyncTimestamp page for information about the parameters and return data structure.
Retrieve the difference (in µs) between two timestamps:
Native - ovr_Voip_GetSyncTimestampDifference()
Unity - Platform.Voip.GetSyncTimestampDifference()
Retrieve the calculated difference between two sync timestamps, in microseconds. returned by ovr_Voip_GetSyncTimestamp, ovr_Voip_GetPCMWithTimestamp, or ovr_Voip_GetPCMWithTimestampFloat.
Return value will be negative if lhs is smaller than rhs, zero if both timestamps are the same, and positive otherwise. The absolute value of the result is the time in microseconds between the two sync timestamps.
Review the ovr_Voip_GetSyncTimestampDifference page for information about the parameters and return data structure.
Retrieve the mute state of the microphone:
Native - ovr_Voip_GetSystemVoipMicrophoneMuted()
Unity - Platform.Voip.GetSystemVoipMicrophoneMuted()
Retrieves the mute state for the microphone. Review the ovr_Voip_GetSystemVoipMicrophoneMuted page for information about the parameters and return data structure.
Retrieve the VoIP system status:
Native - ovr_Voip_GetSystemVoipStatus()
Unity - Platform.Voip.GetSystemVoipStatus()
Retrieve the VoIP system status. Information about the VoIP status can be found on SystemVoipStatus. Review the ovr_Voip_GetSystemVoipStatus page for information about the parameters and return data structure.
Set the microphone filter callback:
Native - ovr_Voip_SetMicrophoneFilterCallback()
Unity - Platform.Voip.SetMicrophoneFilterCallback()
Set a callback that will be called every time audio data is captured by the microphone. The callback function must match this format:
void filterCallback(int16_t pcmData[], size_t pcmDataLength, int frequency, int numChannels);
The pcmData param is used for both input and output. pcmDataLength is the size of pcmData in elements. numChannels will be 1 or 2. If numChannels is 2, then the channel data will be interleaved in pcmData. frequency is the input data sample rate in hertz.
Review the ovr_Voip_SetMicrophoneFilterCallback page for information about the parameters and return data structure.
Mute/unmute the microphone:
Native - ovr_Voip_SetMicrophoneMuted()
Unity - Platform.Voip.SetMicrophoneMuted()
This function is used to enable or disable the local microphone. When muted, the microphone will not transmit any audio. VoIP connections are unaffected by this state. New connections can be established or closed whether the microphone is muted or not. This can be used to implement push-to-talk, or a local mute button. The default state is unmuted.
Review the ovr_Voip_SetMicrophoneMuted page for information about the parameters and return data structure.
Set the VoIP output sample rate:
Native - ovr_Voip_SetOutputSampleRate()
Unity - Platform.Voip.SetOutputSampleRate()
Sets the output sample rate. Audio data will be resampled as it is placed into the internal ringbuffer. Review the ovr_Voip_SetOutputSampleRate page for information about the parameters and return data structure.
Terminate the VoIP connection:
Native - ovr_Voip_Stop()
Unity - Platform.Voip.Stop()
Ends a VoIP session with the specified user. Note that a muting functionality should be used to temporarily stop sending audio; restarting a VoIP session after tearing it down may be an expensive operation.
Review the ovr_Voip_Stop page for information about the parameters and return data structure.
This section will walk you through the basic process of implementing VoIP in your Unity app. A complete example of a Unity app The general process of implementing VoIP is:
Voip.SetVoipConnectRequestCallback((Message<NetworkingPeer> msg) => {
Voip.Accept(msg.Data.ID);
});Voip.SetVoipStateChangeCallback((Message<NetworkingPeer> msg) => {
Debug.LogFormat("peer {0} is in state {1}", msg.Data.ID, msg.Data.State);
});var audioSource = gameObject.AddComponent <VoipAudioSourceHiLevel>(); audioSource.senderID = remotePeer.ID;
Var voipAudio = RemoteAvatar.GetComponent<VoipAudioSourceHiLevel>(); voipAudio.audioSource.spatialize = true;
Oculus.Platform.Voip.Stop(userID); Voip.Stop(remotePeer.ID);
This section will walk you through the basic process of implementing VoIP in your Native app. The general process of implementing VoIP is:
Notifications and the Message Queue
As mentioned earlier in this guide, the VoIP service uses notifications to update your app on the status of the connection and service. Review the Requests and Messages page for more information about the message queue and notifications.
For example, a native application may listen for state changes using:
case ovrMessage_Notification_Voip_StateChange: {
ovrNetworkingPeerHandle netPeer = ovr_Message_GetNetworkingPeer(message);
ovrPeerConnectionState netState = ovr_NetworkingPeer_GetState(netPeer);
printf(
"User: %llu, voip state %s\n",
ovr_NetworkingPeer_GetID(netPeer),
ovrPeerConnectionState_ToString(netState)
);
}
Break;The VrVoiceChat Unity app provided in the Platform SDK download demonstrates using the Cloud Storage service to save multiple records and perform conflict resolution. Please see the Sample Apps page for more information about the apps that are available.
using UnityEngine;
using System.Collections;
using Oculus.Platform;
using Oculus.Platform.Models;
// Helper class to manage the Voice-over-IP connection to the
// remote user
public class VoipManager
{
// the ID of the remote user I expect to talk to
private ulong m_remoteID;
// the last reported state of the VOIP connection
private PeerConnectionState m_state = PeerConnectionState.Unknown;
// the GameObject where the remote VOIP will project from
private readonly GameObject m_remoteHead;
public VoipManager(GameObject remoteHead)
{
m_remoteHead = remoteHead;
Voip.SetVoipConnectRequestCallback(VoipConnectRequestCallback);
Voip.SetVoipStateChangeCallback(VoipStateChangedCallback);
}
public void ConnectTo(ulong userID)
{
m_remoteID = userID;
var audioSource = m_remoteHead.AddComponent<VoipAudioSourceHiLevel>();
audioSource.senderID = userID;
// ID comparison is used to decide who initiates and who gets the Callback
if (PlatformManager.MyID < m_remoteID)
{
Voip.Start(userID);
}
}
public void Disconnect()
{
if (m_remoteID != 0)
{
Voip.Stop(m_remoteID);
Object.Destroy(m_remoteHead.GetComponent<VoipAudioSourceHiLevel>(), 0);
m_remoteID = 0;
m_state = PeerConnectionState.Unknown;
}
}
public bool Connected
{
get
{
return m_state == PeerConnectionState.Connected;
}
}
void VoipConnectRequestCallback(Message<NetworkingPeer> msg)
{
Debug.LogFormat("Voip request from {0}, authorized is {1}", msg.Data.ID, m_remoteID);
if (msg.Data.ID == m_remoteID)
{
Voip.Accept(msg.Data.ID);
}
}
void VoipStateChangedCallback(Message<NetworkingPeer> msg)
{
Debug.LogFormat("Voip state to {0} changed to {1}", msg.Data.ID, msg.Data.State);
if (msg.Data.ID == m_remoteID)
{
m_state = msg.Data.State;
if (m_state == PeerConnectionState.Timeout &&
// ID comparison is used to decide who initiates and who gets the Callback
PlatformManager.MyID < m_remoteID)
{
// keep trying until hangup!
Voip.Start(m_remoteID);
}
}
PlatformManager.SetBackgroundColorForState();
}
}