Created
October 21, 2017 12:01
-
-
Save r618/d74f07b6049fce20f1dc0dfa546bda89 to your computer and use it in GitHub Desktop.
example of some LASP <-> Unity
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* just example of tighter LASP <-> Unity exchange | |
*/ | |
using System.Collections; | |
using UnityEngine; | |
using UnityEngine.Events; | |
[RequireComponent(typeof(AudioSource))] | |
public class AudioInputLasp : MonoBehaviour | |
{ | |
// ======================================================================================================================================== | |
#region Editor | |
/// <summary> | |
/// Recording samplerate provided by LASP default recording device | |
/// </summary> | |
[HideInInspector] | |
int recRate = 0; | |
[Header("[Setup]")] | |
[Tooltip("When checked the recording will start automatically on Start with parameters set in Inspector. Otherwise StartCoroutine(Record()) of this component.")] | |
public bool recordOnStart = true; | |
#region Unity events | |
[System.Serializable] | |
public class EventWithStringParameter : UnityEvent<string> { }; | |
[System.Serializable] | |
public class EventWithStringBoolParameter : UnityEvent<string, bool> { }; | |
[System.Serializable] | |
public class EventWithStringStringParameter : UnityEvent<string, string> { }; | |
[System.Serializable] | |
public class EventWithStringStringStringParameter : UnityEvent<string, string, string> { }; | |
[Header("[Events]")] | |
public EventWithStringParameter OnRecordingStarted; | |
public EventWithStringBoolParameter OnRecordingPaused; | |
public EventWithStringParameter OnRecordingStopped; | |
public EventWithStringStringParameter OnError; | |
#endregion | |
#endregion | |
// ======================================================================================================================================== | |
#region Init | |
/// <summary> | |
/// Component startup sync | |
/// Also in case of recording FMOD needs some time to enumerate all present recording devices - we need to wait for it. Check this flag when using from scripting. | |
/// </summary> | |
[HideInInspector] | |
public bool ready = false; | |
void Start() | |
{ | |
// setup the AudioSource | |
var audiosrc = this.GetComponent<AudioSource>(); | |
if (audiosrc) | |
{ | |
audiosrc.playOnAwake = false; | |
audiosrc.Stop(); | |
audiosrc.clip = null; | |
} | |
/* | |
* Nudge LASP a little to open at start | |
*/ | |
float[] ftemp = new float[512]; | |
Lasp.AudioInput.RetrieveWaveform(Lasp.FilterType.Bypass, ftemp, Time.frameCount); | |
if (this.recordOnStart) | |
StartCoroutine(this.Record()); | |
this.ready = true; | |
} | |
#endregion | |
// ======================================================================================================================================== | |
#region Recording | |
[Header("[Runtime]")] | |
[Tooltip("Set during recording.")] | |
public bool isRecording = false; | |
[Tooltip("Set during recording.")] | |
public bool isPaused = false; | |
public IEnumerator Record() | |
{ | |
if (this.isRecording) | |
{ | |
Debug.LogWarning("Already recording."); | |
yield break; | |
} | |
if (!this.isActiveAndEnabled) | |
{ | |
Debug.LogWarning("Will not start on disabled GameObject."); | |
yield break; | |
} | |
this.isRecording = false; | |
this.isPaused = false; | |
this.Stop_Internal(); // try to clean partially started recording / Start initialized system | |
/* | |
* create some sound with corresponding rate | |
*/ | |
recRate = (int)Lasp.AudioInput.GetSampleRate(); | |
// LASP supports only mono | |
var recChannels = 1; | |
var outputChannles = 2; // note: this should be according to user selected output in AudioSettings.speakerMode | |
var asource = this.GetComponent<AudioSource>(); | |
asource.pitch = (float)(recRate * recChannels) / (float)(AudioSettings.outputSampleRate * outputChannles); | |
asource.Play(); | |
this.isRecording = true; | |
if (this.OnRecordingStarted != null) | |
this.OnRecordingStarted.Invoke(this.gameObject.name); | |
yield return StartCoroutine(this.RecordCR()); | |
} | |
int frameCountX; | |
IEnumerator RecordCR() | |
{ | |
while (this.isRecording) | |
{ | |
this.frameCountX = Time.frameCount; | |
yield return null; | |
} | |
} | |
public void Pause(bool pause) | |
{ | |
if (!this.isRecording) | |
{ | |
Debug.LogWarning("Not recording.."); | |
return; | |
} | |
this.isPaused = pause; | |
Debug.LogFormat("{0}", this.isPaused ? "paused." : "resumed."); | |
if (this.OnRecordingPaused != null) | |
this.OnRecordingPaused.Invoke(this.gameObject.name, this.isPaused); | |
} | |
void OnAudioFilterRead(float[] data, int channels) | |
{ | |
Lasp.AudioInput.RetrieveWaveform(Lasp.FilterType.Bypass, data, this.frameCountX); | |
} | |
#endregion | |
// ======================================================================================================================================== | |
#region Shutdown | |
public void Stop() | |
{ | |
Debug.Log("Stopping.."); | |
this.StopAllCoroutines(); | |
this.Stop_Internal(); | |
if (this.OnRecordingStopped != null) | |
this.OnRecordingStopped.Invoke(this.gameObject.name); | |
} | |
/// <summary> | |
/// Stop and try to release FMOD sound resources | |
/// </summary> | |
void Stop_Internal() | |
{ | |
var asource = this.GetComponent<AudioSource>(); | |
if (asource) | |
{ | |
asource.Stop(); | |
Destroy(asource.clip); | |
asource.clip = null; | |
} | |
this.isRecording = false; | |
this.isPaused = false; | |
} | |
void OnDisable() | |
{ | |
this.Stop(); | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment