Arwes LogotypeArwes Logotext

Sounds

Define, manage, and control interactive sound effects using Howler in React.

Based on the UI/UX guidelines, the sounds tools can be used for application interface sounds management. Futuristic science fiction user interfaces usually execute short experiential sounds such as beeps and bleeps on events or state transitions.

These tools are not intended for sounds with long durations such as music songs.

The sounds tools require the React component tree to allow the dynamic communication between components and Howler for sound management.

It goes hand in hand with the animation tools, though it is not a dependency.

It is advised to follow the Sound Accessibility recommendations.

Installation

All the tools are bundled and can be installed with the following NPM package:

bash
npm install @arwes/sounds

The sounds management tooling requires React v17 and Howler v2.2 as peer-dependencies.

bash
npm install react@17
npm install react-dom@17
npm install howler@2.2

Bleeps

A short sound used in Arwes application components is called a bleep. Bleeps can be used on user events such as user interactions, application events such as notifications, or animation flow transitions on specific components along with the animation tools.

Providers

Since bleeps in an application are shared among its components, there needs to be a global data provider of the audio settings and the player settings. Then these settings are consumed by components with specific configurations.

The provider only provides the sounds settings, it does not create or process the bleep sounds themselves, since each component knows what sounds configurations are required.

Audio settings and players settings are provided simultaneously.

Audio Settings

The audio settings define the general audio sound settings which are normally transversal for sound control in an application. They can be applicable to all bleeps and to categories of bleeps.

For example, enabling all sounds with an specific volume can be set in a application component like:

tsx
import React, { FC } from 'react';
import { BleepsProvider, BleepsAudioSettings } from '@arwes/sounds';
const audio: BleepsAudioSettings = {
common: {
volume: 0.5, // default 1
disabled: false // default false
}
};
const App: FC = ({ children }) => (
<BleepsProvider audio={audio}>
{children}
</BleepsProvider>
);
export { App };

Sound volume can go from 0 to 1.

If sounds are disabled, no bleeps are created in the components.

With only audio settings, the components can not create bleeps yet. Players settings are required.

Players Settings

A player settings define the sound file data.

A bleep is created based on the applicable audio settings and the defined player settings.

In an application component example, the players could be configured like:

tsx
import React, { FC } from 'react';
import { BleepsProvider, BleepsPlayersSettings } from '@arwes/sounds';
const players: BleepsPlayersSettings = {
click: {
src: ['/path/to/sounds/click.mp3']
},
typing: {
src: ['/path/to/sounds/typing.mp3'],
loop: true
}
};
const App: FC = ({ children }) => (
<BleepsProvider players={players}>
{children}
</BleepsProvider>
);
export { App };

The click player will use the file click.mp3 in MP3 format.

The typing player will use the file typing.mp3 in MP3 format as a loop sound. It means that the player will play in a loop until explicitely stopped.

Along with audio settings, the provider configures the sounds settings of an application.

Consumers

A React component can consume bleeps using the withBleeps higher-order component (HOC). It requires a parent BleepsProvider provided settings to work.

A component bleep references a sound player and implements the audio settings.

Assuming a click player provided by a parent provider, a button component can use it like this:

tsx
import React, { FC } from 'react';
import { withBleeps, Bleeps, BleepsSettings } from '@arwes/sounds';
interface ButtonProps {
bleeps: Bleeps
}
const ButtonComponent: FC<ButtonProps> = ({ bleeps, children }) => {
const onClick = () => bleeps.tap.play();
return (
<button onClick={onClick}>
{children}
</button>
);
};
const buttonBleeps: BleepsSettings = {
tap: {
player: 'click'
}
};
const Button = withBleeps(buttonBleeps)(ButtonComponent);
export { ButtonProps, Button };

A complete example can look like this:

JSX

If the applicable audio settings disable the bleep, the sound will not be available in the component. So if the component should work with enabled/disabled bleeps, it should check if it exists before using it.

If the bleep is enabled and the player click does not exist, it will throw an error.

Shared Sounds

Bleeps are shared by all instances of the component. It means that if any of the component instances try to play or stop the sound, it would be the same bleep sound. The same goes for all the other bleep API methods.

Since an intensive application can have hundreds or thousands of component instances with different sounds, if the sounds were created each time, it would highly compromise performance.

Preloading

Bleeps are preloaded on creation time, not on definition time. So the sounds would be loaded when the components consuming bleeps are mounted.

Functionalities for custom sound loading are still in progress.

Recommended Audio Formats

As recommended by howlerjs:

"If your goal is to have the best balance of small filesize and high quality, based on extensive production testing, your best bet is to default to webm and fallback to mp3. webm has nearly full browser coverage with a great combination of compression and quality. You'll need the mp3 fallback for Internet Explorer."

Since Arwes is not supported in Internet Explorer out of the box, the recommendation is to use webm audio format.


You can see and play with more examples in the playground.