You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.1 KiB
128 lines
4.1 KiB
#if UNITY_EDITOR |
|
using UnityEditor; |
|
#endif |
|
using UnityEngine; |
|
|
|
#if UNITY_EDITOR |
|
[ExecuteInEditMode] |
|
#endif |
|
|
|
[AddComponentMenu("")] |
|
public class SfxrAudioPlayer : MonoBehaviour { |
|
|
|
/** |
|
* usfxr |
|
* |
|
* Copyright 2013 Zeh Fernando |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
* |
|
*/ |
|
|
|
/** |
|
* SfxrAudioPlayer |
|
* This is the (internal) behavior script responsible for streaming audio to the engine |
|
* |
|
* @author Zeh Fernando |
|
*/ |
|
|
|
|
|
// Properties |
|
private bool isDestroyed = false; // If true, this instance has been destroyed and shouldn't do anything yes |
|
private bool needsToDestroy = false; // If true, it has been scheduled for destruction (from outside the main thread) |
|
private bool runningInEditMode = false; // If true, it is running from the editor and NOT playing |
|
|
|
// Instances |
|
private SfxrSynth sfxrSynth; // SfxrSynth instance that will generate the audio samples used by this |
|
|
|
|
|
// ================================================================================================================ |
|
// INTERNAL INTERFACE --------------------------------------------------------------------------------------------- |
|
|
|
void Start() { |
|
// Creates an empty audio source so this GameObject can receive audio events |
|
AudioSource soundSource = gameObject.AddComponent<AudioSource>(); |
|
soundSource.clip = new AudioClip(); |
|
soundSource.volume = 1f; |
|
soundSource.pitch = 1f; |
|
soundSource.priority = 128; |
|
soundSource.Play(); |
|
} |
|
|
|
void Update() { |
|
// Destroys self in case it has been queued for deletion |
|
if (sfxrSynth == null) { |
|
// Rogue object (leftover) |
|
// When switching between play and edit mode while the sound is playing, the object is restarted |
|
// So, queues for destruction |
|
needsToDestroy = true; |
|
} |
|
|
|
if (needsToDestroy) { |
|
needsToDestroy = false; |
|
Destroy(); |
|
} |
|
} |
|
|
|
void OnAudioFilterRead(float[] __data, int __channels) { |
|
// Requests the generation of the needed audio data from SfxrSynth |
|
|
|
if (!isDestroyed && !needsToDestroy && sfxrSynth != null) { |
|
bool hasMoreSamples = sfxrSynth.GenerateAudioFilterData(__data, __channels); |
|
|
|
// If no more samples are needed, there's no more need for this GameObject so schedule a destruction (cannot do this in this thread) |
|
if (!hasMoreSamples) { |
|
needsToDestroy = true; |
|
if (runningInEditMode) { |
|
// When running in edit mode, Update() is not called on every frame |
|
// We can't call Destroy() directly either, since Destroy() must be ran from the main thread |
|
// So we just attach our Update() to the editor's update event |
|
#if UNITY_EDITOR |
|
EditorApplication.update += Update; |
|
#endif |
|
} |
|
} |
|
} |
|
} |
|
|
|
|
|
// ================================================================================================================ |
|
// PUBLIC INTERFACE ----------------------------------------------------------------------------------------------- |
|
|
|
public void SetSfxrSynth(SfxrSynth __sfxrSynth) { |
|
// Sets the SfxrSynth instance that will generate the audio samples used by this |
|
sfxrSynth = __sfxrSynth; |
|
} |
|
|
|
public void SetRunningInEditMode(bool __runningInEditMode) { |
|
// Sets the SfxrSynth instance that will generate the audio samples used by this |
|
runningInEditMode = __runningInEditMode; |
|
} |
|
|
|
public void Destroy() { |
|
// Stops audio immediately and destroys self |
|
if (!isDestroyed) { |
|
isDestroyed = true; |
|
sfxrSynth = null; |
|
if (runningInEditMode || !Application.isPlaying) { |
|
// Since we're running in the editor, we need to remove the update event, AND destroy immediately |
|
#if UNITY_EDITOR |
|
EditorApplication.update -= Update; |
|
#endif |
|
UnityEngine.Object.DestroyImmediate(gameObject); |
|
} else { |
|
UnityEngine.Object.Destroy(gameObject); |
|
} |
|
} |
|
} |
|
}
|
|
|