Ryle Radio 1.1.2
An open-source "radio" system for Unity, allowing tracks, tuning, broadcasters, and more!
Loading...
Searching...
No Matches
RyleRadio.Components.RadioOutput Class Reference

The main scene component for a radio that plays it through an AudioSource. More...

Inheritance diagram for RyleRadio.Components.RadioOutput:

Public Types

enum  MultiplePlayersSelector { Youngest , Oldest , Random }
 The method by which a RadioTrackPlayer is chosen from this output. Really only matters when you're playing the same track repeatedly causing overlaps. More...

Public Member Functions

override void Init ()
 Initializes the output itself, and creates all required every required RadioTrackPlayer.
RadioTrackPlayer PlayOneShot (string _id)
 Plays a track as a one-shot. A one-shot destroys itself when its track ends.
RadioTrackPlayer PlayLoop (string _id)
 Plays a track as a loop. A loop restarts when the track ends, then continues to play.
bool TryGetPlayer (string _trackID, out RadioTrackPlayer _player, bool _createNew=false, MultiplePlayersSelector _multiplePlayerSelector=MultiplePlayersSelector.Youngest)
 Gets an active RadioTrackPlayer from this output.
Public Member Functions inherited from RyleRadio.Components.Base.RadioComponent
void Init ()
 Initialises this component.

Protected Member Functions

virtual void Update ()
 Updates cachedPos.
void LocalInit ()
 Initializes the RadioData- this needs to be separated from Init() as it would be recursive otherwise.
void PlayerCreation (RadioTrackPlayer _player)
 Sets up and stores a new RadioTrackPlayer and alerts any RadioObserver of its creation.
virtual void OnAudioFilterRead (float[] _data, int _channels)
 Assigns a set of samples from the radio to play from the AudioSource- this preserves the settings on the Source, e.g: volume, 3D. This is the main driving method for the radio's playback.
void GetOutput (ref float[] _data, int _channels)
 Gets a set of samples from the radio, and push it along to the next samples- that is, get some samples from the radio, and move it on.
void FillCacheClip ()
 Generate and store the next chunk of audio that will be played on WebGL. This is called just before the next chunk is generated.

Protected Attributes

float tune
 The current tune value of this output- akin to the frequency of a real radio. Controls what tracks can be heard through tune power. Never modify this directly except for in the inspector, use Tune instead.
List< RadioTrackPlayerplayers = new()
 The players used by this output.
Vector3 cachedPos
 The position of this object as of the last frame update. We can't access transform.position from the audio thread, so we cache it here.
Protected Attributes inherited from RyleRadio.Components.Base.RadioComponent
RadioData data
 The RadioData (aka just radio) that this component is linked to.

Properties

List< RadioObserverObservers = new() [get, private set]
 Every RadioObserver associated with this output.
Action< float > OnTune = new(_ => { }) [get, set]
 Event called whenever Tune is changed.
Action OnInit = new(() => { }) [get, set]
 Event called when this output is finished initializing- mainly useful for WebGL when we use AwaitLoadingThenInit.
float Tune [get, set]
 The tune clamped to the full range.
float Tune01 [get]
 Tune scaled to [0 - 1], useful for UI
float DisplayTune [get]
 Tune with limited decimal points- looks better when displayed, more like an actual radio
bool Loaded [get]
 Public accessor for loaded.
Properties inherited from RyleRadio.Components.Base.RadioComponent
RadioData Data [get]
 Read-only accessor for data.

Private Member Functions

void ExecOnTune ()
 Called when tune is modified in the inspector.
void FixedUpdate ()
 Updates audio playback in WebGL, does nothing on other platforms.
void OnDestroy ()
IEnumerator AwaitLoadingThenInit ()
 Waits for all AudioClips used in this radio to be loaded before initializing the radio. This is used as WebGL will cause errors if a clip is used before it's fully loaded.
void StartPlayers ()
 Creates every RadioTrackPlayer that this output needs for playback.

Private Attributes

float baseSampleRate
 The normal sample rate of this output, applied to each RadioTrackPlayer.
Action playEvents = () => { }
 Called at the end of every audio cycle so that we don't interrupt threads when manipulating RadioTrackPlayers.
AudioClip cacheClipSecond
 The AudioClip used internally to emulate audio streaming on WebGL- half of this is played at a time, and the other half is generated in advance.
AudioClip cacheClipFirst
int totalCacheChunkLength = 0
 The total number of samples in each half of the cache clip.
float cacheClipChunkDuration = .04f
 The size of half the cache clip used for WebGL playback- this is the amount of audio the cache clip stores in advance during playback before switching to the other half of the clip.
AudioSource source
 The AudioSource attached to this Output. This is assigned automatically.
bool isInFirstHalf = false
 Whether or not the cache clip playback is in the second half of the clip.
bool loaded = false
 Whether or not the clips in this radio have been loaded.
float[] cacheClipSamples

Detailed Description

The main scene component for a radio that plays it through an AudioSource.

See RadioTrackPlayer as well for more info on how playback works

Definition at line 21 of file RadioOutput.cs.

Member Enumeration Documentation

◆ MultiplePlayersSelector

The method by which a RadioTrackPlayer is chosen from this output. Really only matters when you're playing the same track repeatedly causing overlaps.

Enumerator
Youngest 

Selects the youngest player.

Oldest 

Selects the oldest player.

Random 

Selects a random player (probably useless but funny to have)

Definition at line 26 of file RadioOutput.cs.

Member Function Documentation

◆ AwaitLoadingThenInit()

IEnumerator RyleRadio.Components.RadioOutput.AwaitLoadingThenInit ( )
private

Waits for all AudioClips used in this radio to be loaded before initializing the radio. This is used as WebGL will cause errors if a clip is used before it's fully loaded.

Definition at line 221 of file RadioOutput.cs.

◆ ExecOnTune()

void RyleRadio.Components.RadioOutput.ExecOnTune ( )
private

Called when tune is modified in the inspector.

Definition at line 151 of file RadioOutput.cs.

◆ FillCacheClip()

void RyleRadio.Components.RadioOutput.FillCacheClip ( )
protected

Generate and store the next chunk of audio that will be played on WebGL. This is called just before the next chunk is generated.

We need to use this method as WebGL doesn't support audio streaming. Because this system also requires audio to be modified in realtime, we can't simply generate a couple seconds of audio and just play that- we need to modify that audio each frame depending on what the player does- e.g: tuning The methodology for this system is as follows:

  1. Generate a small chunk of audio (usually Time.fixedDeltaTime)
  2. Assign this audio to one of two short AudioClips
  3. When the AudioSource reaches the halfway point or end of this chunk, generate some of the next one and assign it to a separate AudioClip
  4. Switch clips so that the audio updates on web

This is obviously not perfect, and the main issue we face here is a constant popping sound when switching back and forth between clips- unfortunately, as it stands, this is a required tradeoff due to WebGL's audio limitations. If there's a smoother way to get this functionality working, please do give it a try or let me know :)

Definition at line 595 of file RadioOutput.cs.

Referenced by FixedUpdate(), and Init().

◆ FixedUpdate()

void RyleRadio.Components.RadioOutput.FixedUpdate ( )
private

Updates audio playback in WebGL, does nothing on other platforms.

See: FillCacheClip

Definition at line 172 of file RadioOutput.cs.

◆ GetOutput()

void RyleRadio.Components.RadioOutput.GetOutput ( ref float[] _data,
int _channels )
protected

Gets a set of samples from the radio, and push it along to the next samples- that is, get some samples from the radio, and move it on.

Parameters
_dataAn array (usually empty) that the samples will be written to. The length of the array is the number of samples used recorded
_channelsThe number of channels being played- usually this should be at one, I'm not confident in its functionality otherwise

Definition at line 537 of file RadioOutput.cs.

Referenced by FillCacheClip(), and OnAudioFilterRead().

◆ Init()

override void RyleRadio.Components.RadioOutput.Init ( )

Initializes the output itself, and creates all required every required RadioTrackPlayer.

Definition at line 277 of file RadioOutput.cs.

◆ LocalInit()

void RyleRadio.Components.RadioOutput.LocalInit ( )
protected

Initializes the RadioData- this needs to be separated from Init() as it would be recursive otherwise.

Definition at line 266 of file RadioOutput.cs.

Referenced by AwaitLoadingThenInit().

◆ OnAudioFilterRead()

virtual void RyleRadio.Components.RadioOutput.OnAudioFilterRead ( float[] _data,
int _channels )
protectedvirtual

Assigns a set of samples from the radio to play from the AudioSource- this preserves the settings on the Source, e.g: volume, 3D. This is the main driving method for the radio's playback.

The method itself appears to have been initially introduced so devs could create custom audio filters, but it just so happens we can use it for direct output of samples too!

IMPORTANT NOTE ABOUT WEBGL:

WebGL can't use this method, as it doesn't support audio streaming. I've implemented a "streaming emulation" system creating and storing clips repeatedly, but it's a bit rough around the edges and causes some popping artefacts. Please try to avoid WebGL with this package when possible, or use a pop removal filter at runtime. See FillCacheClip for a bit more info :)

See: GetOutput

Parameters
_dataWhatever other audio is playing from the AudioSource- preferably nothing
_channelsThe number of channels the AudioSource is using- the radio itself is limited to one channel, but still outputs as two- they'll just be identical.

Definition at line 525 of file RadioOutput.cs.

◆ OnDestroy()

void RyleRadio.Components.RadioOutput.OnDestroy ( )
private

Definition at line 205 of file RadioOutput.cs.

◆ PlayerCreation()

void RyleRadio.Components.RadioOutput.PlayerCreation ( RadioTrackPlayer _player)
protected

Sets up and stores a new RadioTrackPlayer and alerts any RadioObserver of its creation.

Parameters
_playerThe new player to set up

Definition at line 321 of file RadioOutput.cs.

Referenced by PlayLoop(), PlayOneShot(), and StartPlayers().

◆ PlayLoop()

RadioTrackPlayer RyleRadio.Components.RadioOutput.PlayLoop ( string _id)

Plays a track as a loop. A loop restarts when the track ends, then continues to play.

Parameters
_id
Returns

Definition at line 419 of file RadioOutput.cs.

◆ PlayOneShot()

RadioTrackPlayer RyleRadio.Components.RadioOutput.PlayOneShot ( string _id)

Plays a track as a one-shot. A one-shot destroys itself when its track ends.

Parameters
_id
Returns

Definition at line 384 of file RadioOutput.cs.

Referenced by TryGetPlayer().

◆ StartPlayers()

void RyleRadio.Components.RadioOutput.StartPlayers ( )
private

Creates every RadioTrackPlayer that this output needs for playback.

Definition at line 362 of file RadioOutput.cs.

Referenced by Init().

◆ TryGetPlayer()

bool RyleRadio.Components.RadioOutput.TryGetPlayer ( string _trackID,
out RadioTrackPlayer _player,
bool _createNew = false,
MultiplePlayersSelector _multiplePlayerSelector = MultiplePlayersSelector::Youngest )

Gets an active RadioTrackPlayer from this output.

Parameters
_trackIDThe ID of the track used by the player
_playerOutput parameter containing the found player
_createNewWhether or not a new player should be created if one can't be found. Players created this way are always one-shots
_multiplePlayerSelectorHow a player is selected when multiple are present for the same track
Returns
True if a player was found or created, false if not

Definition at line 452 of file RadioOutput.cs.

◆ Update()

virtual void RyleRadio.Components.RadioOutput.Update ( )
protectedvirtual

Updates cachedPos.

Definition at line 160 of file RadioOutput.cs.

Member Data Documentation

◆ baseSampleRate

float RyleRadio.Components.RadioOutput.baseSampleRate
private

The normal sample rate of this output, applied to each RadioTrackPlayer.

Definition at line 53 of file RadioOutput.cs.

Referenced by Init(), PlayLoop(), PlayOneShot(), and StartPlayers().

◆ cacheClipChunkDuration

float RyleRadio.Components.RadioOutput.cacheClipChunkDuration = .04f
private

The size of half the cache clip used for WebGL playback- this is the amount of audio the cache clip stores in advance during playback before switching to the other half of the clip.

Definition at line 75 of file RadioOutput.cs.

Referenced by Init().

◆ cacheClipFirst

AudioClip RyleRadio.Components.RadioOutput.cacheClipFirst
private

Definition at line 65 of file RadioOutput.cs.

◆ cacheClipSamples

float [] RyleRadio.Components.RadioOutput.cacheClipSamples
private

Definition at line 92 of file RadioOutput.cs.

◆ cacheClipSecond

AudioClip RyleRadio.Components.RadioOutput.cacheClipSecond
private

The AudioClip used internally to emulate audio streaming on WebGL- half of this is played at a time, and the other half is generated in advance.

Definition at line 64 of file RadioOutput.cs.

Referenced by FillCacheClip(), and Init().

◆ cachedPos

Vector3 RyleRadio.Components.RadioOutput.cachedPos
protected

The position of this object as of the last frame update. We can't access transform.position from the audio thread, so we cache it here.

Definition at line 48 of file RadioOutput.cs.

Referenced by GetOutput(), and Update().

◆ isInFirstHalf

bool RyleRadio.Components.RadioOutput.isInFirstHalf = false
private

Whether or not the cache clip playback is in the second half of the clip.

Definition at line 85 of file RadioOutput.cs.

Referenced by FillCacheClip(), and FixedUpdate().

◆ loaded

bool RyleRadio.Components.RadioOutput.loaded = false
private

Whether or not the clips in this radio have been loaded.

Definition at line 90 of file RadioOutput.cs.

Referenced by AwaitLoadingThenInit(), and FixedUpdate().

◆ players

List<RadioTrackPlayer> RyleRadio.Components.RadioOutput.players = new()
protected

The players used by this output.

Definition at line 43 of file RadioOutput.cs.

Referenced by GetOutput(), PlayerCreation(), PlayOneShot(), and TryGetPlayer().

◆ playEvents

Action RyleRadio.Components.RadioOutput.playEvents = () => { }
private

Called at the end of every audio cycle so that we don't interrupt threads when manipulating RadioTrackPlayers.

Definition at line 58 of file RadioOutput.cs.

Referenced by GetOutput(), PlayLoop(), and PlayOneShot().

◆ source

AudioSource RyleRadio.Components.RadioOutput.source
private

The AudioSource attached to this Output. This is assigned automatically.

Definition at line 80 of file RadioOutput.cs.

Referenced by FillCacheClip().

◆ totalCacheChunkLength

int RyleRadio.Components.RadioOutput.totalCacheChunkLength = 0
private

The total number of samples in each half of the cache clip.

Definition at line 70 of file RadioOutput.cs.

Referenced by FillCacheClip(), FixedUpdate(), and Init().

◆ tune

float RyleRadio.Components.RadioOutput.tune
protected

The current tune value of this output- akin to the frequency of a real radio. Controls what tracks can be heard through tune power. Never modify this directly except for in the inspector, use Tune instead.

Definition at line 38 of file RadioOutput.cs.

Referenced by ExecOnTune(), and Init().

Property Documentation

◆ DisplayTune

float RyleRadio.Components.RadioOutput.DisplayTune
get

Tune with limited decimal points- looks better when displayed, more like an actual radio

Definition at line 137 of file RadioOutput.cs.

◆ Loaded

bool RyleRadio.Components.RadioOutput.Loaded
get

Public accessor for loaded.

Definition at line 145 of file RadioOutput.cs.

◆ Observers

List<RadioObserver> RyleRadio.Components.RadioOutput.Observers = new()
getprivate set

Every RadioObserver associated with this output.

Definition at line 98 of file RadioOutput.cs.

Referenced by PlayerCreation().

◆ OnInit

Action RyleRadio.Components.RadioOutput.OnInit = new(() => { })
getset

Event called when this output is finished initializing- mainly useful for WebGL when we use AwaitLoadingThenInit.

Definition at line 108 of file RadioOutput.cs.

◆ OnTune

Action<float> RyleRadio.Components.RadioOutput.OnTune = new(_ => { })
getset

Event called whenever Tune is changed.

Definition at line 103 of file RadioOutput.cs.

Referenced by ExecOnTune(), and Init().

◆ Tune

float RyleRadio.Components.RadioOutput.Tune
getset

The tune clamped to the full range.

Definition at line 113 of file RadioOutput.cs.

Referenced by GetOutput().

◆ Tune01

float RyleRadio.Components.RadioOutput.Tune01
get

Tune scaled to [0 - 1], useful for UI

Definition at line 129 of file RadioOutput.cs.


The documentation for this class was generated from the following file: