@arwes/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, bleeps, processing loops, glitches, and chimes, 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:
npm install @arwes/sounds
The sounds management tooling requires React v17 and Howler v2.2 as peer-dependencies.
npm install react@17 react-dom@17 prop-types howler@2.2
In TypeScript, the following type packages are needed:
npm install @types/react@17 @types/react-dom@17 @types/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, player settings, and bleeps settings. With the configured settings, the provider creates the bleeps to provide to the components.
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:
import React, { FC } from 'react';import { BleepsProvider, BleepsAudioSettings } from '@arwes/sounds';const audioSettings: BleepsAudioSettings = {common: {volume: 0.5, // default 1disabled: false // default false}};const App: FC = ({ children }) => (<BleepsProvider audioSettings={audioSettings}>{children}</BleepsProvider>);
Sound volume can go from 0
to 1
.
If sounds are disabled, no bleeps are passed to the components.
Players Settings
A player settings define the sound file data.
In an application component example, the players could be configured like:
import React, { FC } from 'react';import { BleepsProvider, BleepsPlayersSettings } from '@arwes/sounds';const playersSettings: BleepsPlayersSettings = {click: { // On user click.src: ['/path/to/sounds/click.mp3']},type: { // Text typing loop sound.src: ['/path/to/sounds/type.mp3'],loop: true}};const App: FC = ({ children }) => (<BleepsProvider playersSettings={playersSettings}>{children}</BleepsProvider>);
The click
player will use the file click.mp3
in MP3 format.
The type
player will use the file type.mp3
in MP3 format as a loop sound.
It means that the player will play in a loop until explicitely stopped.
Bleeps Settings
The bleeps settings define which player to use and audio settings to use.
Based on the application example players settings, the bleeps can be configured like:
import React, { FC } from 'react';import { BleepsProvider, BleepsSettings } from '@arwes/sounds';const bleepsSettings: BleepsSettings = {tap: {player: 'click'},typing: {player: 'type'}};const App: FC = ({ children }) => (<BleepsProvider bleepsSettings={bleepsSettings}>{children}</BleepsProvider>);
The bleep names can be the same or different from the player names. There can be multiple bleeps based on the same player settings.
The bleeps can also have categories.
Consumers
A React component can consume bleeps using the useBleeps
React hook.
It requires a parent BleepsProvider
with bleeps settings to receive the
generated bleeps. In case there is no provider found, an empty bleeps object
is returned.
A bleep is a sound player and implements the audio settings applicable.
Assuming a tap
bleep provided by a parent provider, a button component can
use it like this:
import React, { FC } from 'react';import { useBleeps } from '@arwes/sounds';const ButtonComponent: FC = ({ children }) => {const bleeps = useBleeps();const onClick = () => bleeps.tap.play();return (<button onClick={onClick}>{children}</button>);};
A complete example can look like this:
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. You may use optional chaining for that.
If the bleep is enabled and the player click
does not exist, it will throw an error.
Shared Sounds
By default, bleeps are shared by all components. 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 provider is 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 tomp3
.webm
has nearly full browser coverage with a great combination of compression and quality. You'll need themp3
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.