Skip to content

Commit

Permalink
Merge pull request #186 from bridie-hifi/2021-10-07-release
Browse files Browse the repository at this point in the history
Merge into Release branch
  • Loading branch information
sabrina-shanman authored Oct 7, 2021
2 parents f95cce0 + 1fac6ce commit 856b4c9
Show file tree
Hide file tree
Showing 8 changed files with 110 additions and 30 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hifi-spatial-audio",
"version": "2.0.0",
"version": "2.1.0",
"description": "The High Fidelity Audio Client Library allows developers to integrate High Fidelity's spatial audio technology into their projects.",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
51 changes: 40 additions & 11 deletions src/classes/HiFiAudioAPIData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,17 @@ export class HiFiAudioAPIData {
* A volume level below this value is considered background noise and will be smoothly gated off.
* The floating point value is specified in dBFS (decibels relative to full scale) with values between -96 dB (indicating no gating)
* and 0 dB (effectively muting the input from this user). It is in the same decibel units as the VolumeDecibels component of UserDataSubscription.
* Setting this value to `NaN` will cause the volume threshold from the space to be used instead.
*
* **COMPATIBILITY WARNING:** Currently, setting `volumeThreshold` to `null` will also reset its value to the space default volume threshold.
* In the future, the value of `volumeThreshold` will only be reset if it is set to `NaN`.
* A `volumeThreshold` set to `null` will in the future will be treated as if `volumeThreshold` is not supplied.
* If your spatial audio client application is currently resetting `volumeThreshold` by setting it to `null`, please change
* it to set `volumeThreshold` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
*
* If you don't supply a `volumeThreshold` when constructing instantiations of this class, the previous value of `volumeThreshold` will
* be used. If `volumeThreshold` has never been supplied, the volume threshold of the space will be used instead.
*/
volumeThreshold: number;
/**
Expand All @@ -61,23 +72,29 @@ export class HiFiAudioAPIData {
* This value affects how far a user's sound will travel in 3D space, without affecting the user's loudness.
* By default, there is a global attenuation value (set for a given space) that applies to all users in a space. This default space
* attenuation is usually 0.5, which represents a reasonable approximation of a real-world fall-off in sound over distance.
* Lower numbers represent less attenuation (i.e. sound travels farther); higher numbers represent more attenuation (i.e. sound drops
* off more quickly).
*
* When setting this value for an individual user, the following holds:
* - Positive numbers should be between 0 and 1, and they represent a logarithmic attenuation. This range is recommended, as it is
* - A value of `NaN` causes the user to inherit the global attenuation for a space, or, if zones are defined for the space,
* the attenuation settings at the user's position. **COMPATIBILITY WARNING:** Currently, setting `userAttenuation` to 0 will
* also reset its value to the space/zone default attenuation.
* In the future, the value of `userAttenuation` will only be reset if it is set to `NaN`.
* A `userAttenuation` set to 0 will in the future be treated as a "broadcast mode", making
* the user audible throughout the entire space.
* If your spatial audio client application is currently resetting `userAttenuation` by setting it to 0, please change
* it to set `userAttenuation` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
* - Positive numbers between 0 and 1 (excluding 0) represent logarithmic attenuation. This range is recommended, as it is
* more natural sounding. Smaller numbers represent less attenuation, so a number such as 0.2 can be used to make a particular
* user's audio travel farther than other users', for instance in "amplified" concert type settings. Similarly, an extremely
* small non-zero number (e.g. 0.00001) can be used to effectively turn off attenuation for a given user within a reasonably
* sized space, resulting in a "broadcast mode" where the user can be heard throughout most of the space regardless of their location
* relative to other users. (Note: The actual value "0" is used internally to represent the default; for setting minimal attenuation,
* small non-zero numbers should be used instead. See also "userRolloff" below.)
* user's audio travel farther than other users', for instance in "amplified" concert type settings. A number such as 0.02 will
* make the user's audio travel even farther.
* - A value of near 0, such as 0.001, will greatly reduce attenuation for a given user, resulting effectively in a "broadcast mode" where the user can be
* heard throughout the entire space regardless of their location relative to other users.
* - Negative attenuation numbers are used to represent linear attenuation, and are a somewhat artificial, non-real-world concept. However,
* this setting can be used as a blunt tool to easily test attenuation, and tune it aggressively in extreme circumstances. When using linear
* attenuation, the setting is the distance in meters at which the audio becomes totally inaudible.
*
* If you don't supply an `userAttenuation` when constructing instantiations of this class, `userAttenuation` will be `null` and the
* default will be used.
* If you don't supply a `userAttenuation` when constructing instantiations of this class, the previous value of `userAttenuation` will
* be used. If `userAttenuation` has never been supplied, the attenuation of the space will be used instead.
*
* ✔ The client sends `userAttenuation` data to the server when `_transmitHiFiAudioAPIDataToServer()` is called.
*
Expand All @@ -93,7 +110,19 @@ export class HiFiAudioAPIData {
* extremely high values (e.g. 99999) should be used in combination with "broadcast mode"-style userAttenuation settings to cause the
* broadcasted voice to sound crisp and "up close" even at very large distances.
*
* If you don't supply an `userRolloff` when constructing instantiations of this class, `userRolloff` will be `null`.
* A `userRolloff` of `NaN` will cause the user to inherit the global frequency rolloff for the space, or, if zones are defined
* for the space, the frequency rolloff settings at the user's position.
*
* **COMPATIBILITY WARNING:** Currently, setting `userRolloff` to 0 will also reset its value to the space/zone default rolloff
* In the future, the value of `userRolloff` will only be reset if it is set to `NaN`
* A `userRolloff` set to 0 will in the future be treated as a valid frequency rolloff value,
* which will cause the user's sound to become muffled over a short distance.
* If your spatial audio client application is currently resetting `userRolloff` by setting it to 0, please change
* it to set `userRolloff` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
*
* If you don't supply a `userRolloff` when constructing instantiations of this class, the previous value of `userRolloff` will
* be used. If `userRolloff` has never been supplied, the frequency rolloff of the space will be used instead.
*
* ✔ The client sends `userRolloff` data to the server when `_transmitHiFiAudioAPIDataToServer()` is called.
*
Expand Down
46 changes: 37 additions & 9 deletions src/classes/HiFiCommunicator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -979,15 +979,42 @@ export class HiFiCommunicator {
* @param __namedParameters
* @param position - The new position of the user.
* @param orientation - The new orientation of the user (in Quaternion form)
* @param volumeThreshold - The new volumeThreshold of the user. Setting this to null will use the space default volume threshold.
* @param volumeThreshold - The new volumeThreshold of the user. Setting this to `NaN` will reset its value to the space default volume threshold.
*
* **COMPATIBILITY WARNING:** Currently, setting `volumeThreshold` to `null` will also reset its value to the space default volume threshold.
* In the future, the value of `volumeThreshold` will only be reset if it is set to `NaN`.
* A `volumeThreshold` set to `null` will in the future will be treated as if `volumeThreshold` is not supplied.
* If your spatial audio client application is currently resetting `volumeThreshold` by setting it to `null`, please change
* it to set `volumeThreshold` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
* @param hiFiGain - This value affects how loud User A will sound to User B at a given distance in 3D space.
* This value also affects the distance at which User A can be heard in 3D space.
* Higher values for User A means that User A will sound louder to other users around User A, and it also means that User A will be audible from a greater distance.
* The new hiFiGain of the user.
*
* @param userAttenuation - This value affects how far a user's voice will travel in 3D space.
* The new attenuation value for the user.
* Setting this to `NaN` will use the space default attenuation, or, if zones are defined for the space,
* the attenuation settings at the user's position.
*
* **COMPATIBILITY WARNING:** Currently, setting `userAttenuation` to 0 will also reset its value to the space/zone default attenuation.
* In the future, the value of `userAttenuation` will only be reset if it is set to `NaN`.
* A `userAttenuation` set to 0 will in the future be treated as a "broadcast mode", making
* the user audible throughout the entire space.
* If your spatial audio client application is currently resetting `userAttenuation` by setting it to 0, please change
* it to set `userAttenuation` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
*
* @param userRolloff - This value affects the frequency rolloff for a given user.
* The new rolloff value for the user.
* Setting this to `NaN` or 0 will use the space default rolloff, or, if zones are defined for the space,
* the frequency rolloff settings at the user's position.
*
* **COMPATIBILITY WARNING:** Currently, setting `userRolloff` to 0 will also reset its value to the space/zone default rolloff
* In the future, the value of `userRolloff` will only be reset if it is set to `NaN`
* A `userRolloff` set to 0 will in the future be treated as a valid frequency rolloff value,
* which will cause the user's sound to become muffled over a short distance.
* If your spatial audio client application is currently resetting `userRolloff` by setting it to 0, please change
* it to set `userRolloff` to `NaN` instead, in order for it to continue working with future versions of
* High Fidelity's Spatial Audio API.
*/
private _updateUserData({ position, orientation, volumeThreshold, hiFiGain, userAttenuation, userRolloff }: { position?: Point3D, orientation?: Quaternion, volumeThreshold?: number, hiFiGain?: number, userAttenuation?: number, userRolloff?: number } = {}): void {
if (position) {
Expand All @@ -1011,17 +1038,17 @@ export class HiFiCommunicator {
this._currentHiFiAudioAPIData.orientation.z = orientation.z ?? this._currentHiFiAudioAPIData.orientation.z;
}

if (typeof (volumeThreshold) === "number" ||
if (typeof (volumeThreshold) === "number" || // May be NaN
volumeThreshold === null) {
this._currentHiFiAudioAPIData.volumeThreshold = volumeThreshold;
}
if (typeof (hiFiGain) === "number") {
this._currentHiFiAudioAPIData.hiFiGain = Math.max(0, hiFiGain);
}
if (typeof (userAttenuation) === "number") {
if (typeof (userAttenuation) === "number") { // May be NaN
this._currentHiFiAudioAPIData.userAttenuation = userAttenuation;
}
if (typeof (userRolloff) === "number") {
if (typeof (userRolloff) === "number") { // May be NaN
this._currentHiFiAudioAPIData.userRolloff = Math.max(0, userRolloff);
}
}
Expand Down Expand Up @@ -1067,18 +1094,18 @@ export class HiFiCommunicator {
this._lastTransmittedHiFiAudioAPIData.orientation.z = dataJustTransmitted.orientation.z ?? this._lastTransmittedHiFiAudioAPIData.orientation.z;
}

if (typeof (dataJustTransmitted.volumeThreshold) === "number" ||
if (typeof (dataJustTransmitted.volumeThreshold) === "number" || // May be NaN
dataJustTransmitted.volumeThreshold === null) {
this._lastTransmittedHiFiAudioAPIData["volumeThreshold"] = dataJustTransmitted.volumeThreshold;
}

if (typeof (dataJustTransmitted.hiFiGain) === "number") {
this._lastTransmittedHiFiAudioAPIData["hiFiGain"] = dataJustTransmitted.hiFiGain;
}
if (typeof (dataJustTransmitted.userAttenuation) === "number") {
if (typeof (dataJustTransmitted.userAttenuation) === "number") { // May be NaN
this._lastTransmittedHiFiAudioAPIData["userAttenuation"] = dataJustTransmitted.userAttenuation;
}
if (typeof (dataJustTransmitted.userRolloff) === "number") {
if (typeof (dataJustTransmitted.userRolloff) === "number") { // May be NaN
this._lastTransmittedHiFiAudioAPIData["userRolloff"] = dataJustTransmitted.userRolloff;
}
if (typeof (dataJustTransmitted._otherUserGainQueue) === "object") {
Expand Down Expand Up @@ -1172,6 +1199,7 @@ export class HiFiCommunicator {

/**
* A simple function that calls {@link _updateUserData}, followed by {@link _transmitHiFiAudioAPIDataToServer}.
* See {@link HiFiAudioAPIData} for what data can be sent to the High Fidelity Audio API Server.
* Developers can call this function as often as they want. This function will update the internal data store of the user's
* position, orientation, etc. No matter how often developers call this function, the internal data store transmission is rate-limited
* and will only be sent to the server once every `transmitRateLimitTimeoutMS` milliseconds. When the internal data store is transmitted,
Expand Down
31 changes: 26 additions & 5 deletions src/classes/HiFiMixerSession.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/**
* Code in this module is used internally by the [[HiFiCommunicator]] object to manage the connection between client and server.
* Developers do not need to and should not consider this module when writing their applications.
* Code in this module is used by [[HiFiCommunicator]] object to manage the connection between client and server.
* This module is also home to some types used to manage client volume state, for example
* {@link OnMuteChangedCallback}.
* The class HiFiMixerSession is an internal class. Developers do not need to and should not consider it
* when writing their applications.
* @packageDocumentation
*/

Expand Down Expand Up @@ -32,17 +35,33 @@ const PERSONAL_VOLUME_ADJUST_TIMEOUT_MS = 5000;

type ConnectionStateChangeHandler = (state: HiFiConnectionStates, result: HiFiConnectionAttemptResult) => void;

/** @internal */
interface AudionetSetOtherUserGainsForThisConnectionResponse {
success: boolean,
reason?: string
}

/**
* The result of calling {@link HiFiCommunicator.setOtherUserGainsForThisConnection}, which adjusts the
* gain of one or more users for the communicator's current connection only.
*/
export interface SetOtherUserGainsForThisConnectionResponse {
/**
* `true` if the gains of other users were adjusted, `false` otherwise
*/
success: boolean,
/**
* if {@link success} is `false`, then a message explaining why the gains of other users could not be adjusted
*/
error?: string,
/** @internal */
audionetSetOtherUserGainsForThisConnectionResponse?: AudionetSetOtherUserGainsForThisConnectionResponse
}

/**
* The result of calling {@link HiFiCommunicator.setOtherUserGainForThisConnection}, which adjusts the
* gain of another user for the communicator's current connection only.
*/
export type SetOtherUserGainForThisConnectionResponse = SetOtherUserGainsForThisConnectionResponse;

/**
Expand Down Expand Up @@ -114,6 +133,7 @@ export type OnMuteChangedCallback = (muteChangedEvent: MuteChangedEvent) => void
/**
* Instantiations of this class contain data about a connection between a client and a mixer.
* Client library users shouldn't have to care at all about the variables and methods contained in this class.
* @internal
*/
export class HiFiMixerSession {
/**
Expand Down Expand Up @@ -1207,7 +1227,7 @@ export class HiFiMixerSession {
}
}

if (typeof (currentHifiAudioAPIData.volumeThreshold) === "number" ||
if (typeof (currentHifiAudioAPIData.volumeThreshold) === "number" || // May be NaN
currentHifiAudioAPIData.volumeThreshold === null) {
dataForMixer["T"] = currentHifiAudioAPIData.volumeThreshold;
}
Expand All @@ -1216,11 +1236,11 @@ export class HiFiMixerSession {
dataForMixer["g"] = Math.max(0, currentHifiAudioAPIData.hiFiGain);
}

if (typeof (currentHifiAudioAPIData.userAttenuation) === "number") {
if (typeof (currentHifiAudioAPIData.userAttenuation) === "number") { // May be NaN
dataForMixer["a"] = currentHifiAudioAPIData.userAttenuation;
}

if (typeof (currentHifiAudioAPIData.userRolloff) === "number") {
if (typeof (currentHifiAudioAPIData.userRolloff) === "number") { // May be NaN
dataForMixer["r"] = Math.max(0, currentHifiAudioAPIData.userRolloff);
}

Expand Down Expand Up @@ -1272,6 +1292,7 @@ export class HiFiMixerSession {
let commandController = this._raviSession.getCommandController();

if (commandController) {
// Stringified NaN values get converted to null, which the mixer interprets as unset
let stringifiedDataForMixer = JSON.stringify(dataForMixer);
commandController.sendInput(stringifiedDataForMixer);
return {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export { apiVersion };
// Scroll down to check out those shorter synonyms.
export { HiFiAudioAPIData, ReceivedHiFiAudioAPIData, Point3D, Quaternion } from "./classes/HiFiAudioAPIData";
export { HiFiCommunicator, HiFiConnectionStates, HiFiUserDataStreamingScopes } from "./classes/HiFiCommunicator";
export { SetOtherUserGainForThisConnectionResponse, SetOtherUserGainsForThisConnectionResponse, MuteReason, MuteChangedEvent, OnMuteChangedCallback } from "./classes/HiFiMixerSession";
export { WebRTCSessionParams } from "./libravi/RaviSession";
export { AvailableUserDataSubscriptionComponents, UserDataSubscription } from "./classes/HiFiUserDataSubscription";
export { HiFiLogLevel, HiFiLogger } from "./utilities/HiFiLogger";
Expand Down
2 changes: 1 addition & 1 deletion src/utilities/HiFiMath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export class Quaternion {
axis.x = this.x / imaginaryLength;
axis.y = this.y / imaginaryLength;
axis.z = this.z / imaginaryLength;
let wholeLength = Math.sqrt(imaginaryLength + this.w * this.w);
let wholeLength = Math.sqrt(imaginaryLength2 + this.w * this.w);
let angle = 2.0 * Math.acos(this.w / wholeLength);
if (angle < 0.0) {
// we choose the axis that corresponds to positive angle
Expand Down
Loading

0 comments on commit 856b4c9

Please sign in to comment.