Last active
June 6, 2018 14:09
-
-
Save shiena/78ce11495d0e4ef8e9d9371660ca9ec7 to your computer and use it in GitHub Desktop.
UnityでProcedual Audio
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
/* | |
* refs | |
* http://tips.hecomi.com/entry/2014/11/11/021147 | |
* http://d.hatena.ne.jp/nakamura001/20120724/1343148980 | |
* https://gist.github.com/keijiro/3806478 | |
* https://codepen.io/DavidSabine/pen/kyAlJ | |
* https://femurdesign.com/theremin/ | |
*/ | |
using UnityEngine; | |
using UnityEngine.UI; | |
[RequireComponent(typeof(AudioSource))] | |
public class Sinus : MonoBehaviour | |
{ | |
const float PI2 = Mathf.PI * 2; | |
const float PI_2 = Mathf.PI / 2.0f; | |
public Text toggle; | |
[Range(55, 1760)] | |
public float frequency = 440; | |
public float gain = 0.4f; | |
private float increment; | |
private float phase; | |
private float sampling_frequency = 44100; | |
private bool playing = false; | |
private AudioSource audio_; | |
void Awake() | |
{ | |
// オーディオ出力設定、44100 Hz がデフォルト | |
sampling_frequency = AudioSettings.outputSampleRate; | |
audio_ = GetComponent<AudioSource>(); | |
audio_.clip = AudioClip.Create("(null)", 44100, 1, 44100, true, (data) => { }); | |
audio_.loop = true; | |
} | |
/// <summary> | |
/// If OnAudioFilterRead is implemented, Unity will insert a custom filter into the | |
/// audio DSP chain. | |
/// </summary> | |
/// <param name="data">An array of floats comprising the audio data.</param> | |
/// <param name="channels">An int that stores the number of channels | |
/// of audio data passed to this delegate.</param> | |
void SineWave(float[] data, int channels) | |
{ | |
// update increment in case frequency has changed | |
increment = frequency * 2 * Mathf.PI / sampling_frequency; | |
for (var i = 0; i < data.Length; i += channels) | |
{ | |
phase += increment; | |
data[i] = gain * Mathf.Sin(phase); | |
// if we have stereo, we copy the mono data to each channel | |
if (channels == 2) | |
{ | |
data[i + 1] = data[i]; | |
} | |
if (phase > 2 * Mathf.PI) | |
{ | |
phase = 0; | |
} | |
} | |
} | |
void SquareWave(float[] data, int channels) | |
{ | |
increment = frequency * 2 * Mathf.PI / sampling_frequency; | |
for (var i = 0; i < data.Length; i = i + channels) | |
{ | |
phase += increment; | |
data[i] = (float)(gain * ((phase % PI2) < PI2 * 0.5 ? 1.0 : -1.0)); | |
if (channels == 2) | |
{ | |
data[i + 1] = data[i]; | |
} | |
if (phase > 2 * Mathf.PI) | |
{ | |
phase = 0; | |
} | |
} | |
} | |
void OnAudioFilterRead(float[] data, int channels) | |
{ | |
if (!playing) | |
{ | |
return; | |
} | |
SineWave(data, channels); | |
} | |
public void TogglePlay() | |
{ | |
if (playing) | |
{ | |
audio_.Stop(); | |
toggle.text = "Play"; | |
} | |
else | |
{ | |
audio_.Play(); | |
toggle.text = "Stop"; | |
} | |
playing = !playing; | |
} | |
public void SetFrequency(float f) | |
{ | |
frequency = f; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment