Struct NativeSource
This is a reference to one of all native sources you obtained at Initialize(). Parallels UnityEngine.AudioSource of Unity except they are at native side, you play an audio using it.
Main way to get this is by GetNativeSource(Int32), GetNativeSourceAuto(), or GetNativeSourceAuto(INativeSourceSelector)
Namespace: E7.Native
Assembly: E7.NativeAudio.dll
Syntax
public struct NativeSource
Properties
Index
It's like an ID of this native source. This is zero-indexed of how many native sources you get at Initialize() If you initialize 3 native sources, then this could be 0, 1, or 2.
Declaration
public readonly int Index { get; }
Property Value
Type | Description |
---|---|
System.Int32 |
IsValid
This is used to separate a struct
returned from Native Audio's
GetNativeSource(Int32) method
from a default struct
. (A trick to make struct
kinda nullable.)
Declaration
public readonly bool IsValid { get; }
Property Value
Type | Description |
---|---|
System.Boolean |
Methods
GetPlaybackTime()
Return the current playback time of this native source. It is relative to the start of audio data currently playing on the source in seconds.
Declaration
public float GetPlaybackTime()
Returns
Type | Description |
---|---|
System.Single |
Remarks
The API is very time sensitive and may or may not change the value in the same frame. (depending on where you call it in the script)
This behaviour is similar to when calling UnityEngine.AudioSettings.dspTime or UnityEngine.AudioSource.time property, those two are in the same update step.
Note that UnityEngine.Time.realtimeSinceStartup is not in an update step unlike audio time, and will change every time you call even in 2 consecutive lines of code.
A looping audio played by sourceLoop has a playback time resets to 0 everytime a new loop arrives.
[iOS] Get AL_SEC_OFFSET
attribute. It update in a certain discrete step,
and if that step happen in the middle of the frame this method will return different value
depending on where in the script you call it. The update step timing is THE SAME as
UnityEngine.AudioSettings.dspTime and UnityEngine.AudioSource.time.
I observed (in iPad 3, iOS 9) that this function sometimes lags on first few calls. It might help to pre-warm by calling this several times in loading screen or something.
[Android] Use GetPosition
of SLPlayItf
interface. It update in a certain discrete step,
and if that step happen in the middle of the frame this method will return different value
depending on where in the script you call it. The update step timing is INDEPENDENT from
UnityEngine.AudioSettings.dspTime and UnityEngine.AudioSource.time.
Because of how "stop hack" was implemented, any stopped audio will have a playback time equals to audio's length (rather than 0).
Pause()
Pause this native source.
The source is not protected against being chosen for other audio while pausing, and if that happens the pause status will be cleared out.
Declaration
public void Pause()
Play(NativeAudioPointer)
A native source will play an audio using loaded audio memory at native side,
specified by nativeAudioPointer
.
Declaration
public void Play(NativeAudioPointer nativeAudioPointer)
Parameters
Type | Name | Description |
---|---|---|
NativeAudioPointer |
nativeAudioPointer |
Exceptions
Type | Condition |
---|---|
System.InvalidOperationException |
Thrown when you attempt to play an unloaded audio. |
Play(NativeAudioPointer, NativeSource.PlayOptions)
A native source will play an audio using loaded audio memory at native side,
specified by nativeAudioPointer
.
Declaration
public void Play(NativeAudioPointer nativeAudioPointer, NativeSource.PlayOptions playOptions)
Parameters
Type | Name | Description |
---|---|---|
NativeAudioPointer |
nativeAudioPointer |
|
NativeSource.PlayOptions |
playOptions |
Customize your play. Begin creating the option from defaultOptions |
Exceptions
Type | Condition |
---|---|
System.InvalidOperationException |
Thrown when you attempt to play an unloaded audio. |
PlayPrepared()
(EXPERIMENTAL) Play the audio "blindly" without NativeAudioPointer, but believing that the prepared audio at Prepare(NativeAudioPointer) is still associated with this native source.
If successful, the play could be potentially faster depending on platforms.
If you waited too long and the native source has already been used with other audio, this may produce unexpected result such as repeating an audio you were not expecting when you prepared. With careful native source planning, you can know that this will or will not happen.
[iOS] Use this after Prepare(NativeAudioPointer).
[Android] No effect, Android has no prepare implemented yet.
Declaration
public void PlayPrepared()
PlayPrepared(NativeSource.PlayOptions)
(EXPERIMENTAL) Play the audio "blindly" without NativeAudioPointer, but believing that the prepared audio at Prepare(NativeAudioPointer) is still associated with this native source.
If successful, the play could be potentially faster depending on platforms.
If you waited too long and the native source has already been used with other audio, this may produce unexpected result such as repeating an audio you were not expecting when you prepared. With careful native source planning, you can know that this will or will not happen.
[iOS] Use this after Prepare(NativeAudioPointer).
[Android] No effect, Android has no prepare implemented yet.
Declaration
public void PlayPrepared(NativeSource.PlayOptions playOptions)
Parameters
Type | Name | Description |
---|---|---|
NativeSource.PlayOptions |
playOptions |
Prepare(NativeAudioPointer)
(EXPERIMENTAL) Try to make the next Play(NativeAudioPointer) faster by pre-associating the pointer to this native source. Whether if this is possible or not depends on platform.
To "fire" the prepared audio, use the parameterless play PlayPrepared() method.
Not recommended to care about this generally, because the gain could be next to nothing for hassle you get. But it is a method stub for the future where there maybe a significant optimization in doing so.
[iOS] Implemented, but likely negligible.. (didn't profile extensively yet, but theoretically there is something to prepare here.)
[Android] Not implemented, no effect.
Declaration
public void Prepare(NativeAudioPointer nativeAudioPointer)
Parameters
Type | Name | Description |
---|---|---|
NativeAudioPointer |
nativeAudioPointer |
An audio to prepare into this native source. |
Remarks
[iOS] Normally on Play(NativeAudioPointer) OpenAL will
- Choose a source at native side, depending on your NativeSource.PlayOptions when using Play(NativeAudioPointer, NativeSource.PlayOptions) if manually. Or automatically round-robin without options.
- Stop that source, and then assign a new audio buffer to it.
- Play that source.
Preparing make it do 1. and 2. preemptively. Then PlayPrepared() performs 3. "blindly" without caring about the current audio. If you didn't wait too long, the preparation should be usable.
[Android] No effect as OpenSL ES play audio by pushing data into SLAndroidSimpleBufferQueueItf
.
All the prepare is already at the Load(AudioClip). I cannot find any other way
to pre-speeding this up.
Resume()
Resume this native source.
If by the time you call resume the source has already been used to play other audio, the resume will have no effect since the pause status had already been cleared out.
Declaration
public void Resume()
SetPan(Single)
This pan is based on "balance effect" and not a "constant energy pan". That is at the center you hear each side fully. (Constant energy pan has 3dB attenuation to both on center.)
Declaration
public void SetPan(float pan)
Parameters
Type | Name | Description |
---|---|---|
System.Single |
pan |
-1 for full left, 0 for center, 1 for full right. |
Remarks
[iOS] 2D panning in iOS will be emulated in OpenAL's 3D audio engine by splitting your stereo sound into a separated mono sounds, then position each one on left and right ear of the listener. When panning, instead of adjusting gain we will just move the source further from the listener and the distance attenuation will do the work. (Gain is reserved to the setting volume command, so we have 2 stage of gain adjustment this way.)
[Android] Maps to SLVolumeItf
interface -> SetStereoPosition
SetPlaybackTime(Single)
Set a playback time of this native source. If the source is in a paused state it is immediately resumed. You can set it even while the native source is playing.
Declaration
public void SetPlaybackTime(float offsetSeconds)
Parameters
Type | Name | Description |
---|---|---|
System.Single |
offsetSeconds |
SetVolume(Single)
Change the volume of native source while it is playing.
Declaration
public void SetVolume(float volume)
Parameters
Type | Name | Description |
---|---|---|
System.Single |
volume |
Remarks
[iOS] Maps to AL_GAIN
. It is a scalar amplitude multiplier, so the value can go over 1.0
for increasing volume but can be clipped. If you put 0.5f, it is attenuated by 6 dB.
[Android] Maps to SLVolumeItf
interface -> SetVolumeLevel
.
The floating volume parameter will be converted to millibel (20xlog10x100) so that putting 0.5f
here results in 6dB attenuation.
Stop()
Immediately stop this native source. If it was playing an audio then effectively it stops the audio.
Declaration
public void Stop()
Remarks
[iOS] One of all OpenAL sources that was used to play this sound will stop.
[Android] One of all SLAndroidSimpleBufferQueue
that was used to play this sound will stop.