Created
May 18, 2016 19:42
-
-
Save cubed2d/cf1f37fc02cea7fc48bc7306b43ee87b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using UnityEngine; | |
using System; | |
using System.Collections; | |
public class SineSynth : MonoBehaviour | |
{ | |
[Range(100,1000)] | |
public double Frequency = 440; | |
[Range(0.05f, 0.3f)] | |
public double Gain = 0.05; // Amplitude? | |
public int sampleCount, channelCount; | |
private double increment, incrementLinear; | |
private double phase, phaseLinear; | |
private double samplingFrequency = 48000; | |
public AnimationCurve curve; | |
public WaveType WaveType; | |
[Range(2,50)] | |
public int WaveRefinement = 20; | |
int[] harmonics; | |
void Start() | |
{ | |
int bpm = 120; | |
float beat = 60 / bpm; | |
harmonics = new int[50]; | |
harmonics[0] = 3; | |
for (int i = 1; i < 50; i++) | |
{ | |
harmonics[i] = harmonics[i - 1] + 2; | |
} | |
curve = new AnimationCurve(); | |
FllCurve(); | |
} | |
void FllCurve() | |
{ | |
while (curve.length > 0) | |
{ | |
curve.RemoveKey(0); | |
} | |
float t = 0; | |
for (int i = 0; i < 1024; i++) | |
{ | |
curve.AddKey(t, 0); | |
t += 2f; | |
} | |
} | |
int count; | |
void OnAudioFilterRead(float[] data, int channels) | |
{ | |
count = 0; | |
// update increment in case frequency has changed | |
channelCount = channels; | |
sampleCount = data.Length / channels; | |
increment = Frequency * 2 * Math.PI / samplingFrequency; | |
incrementLinear = increment / (Math.PI * 2); | |
for (var i = 0; i < data.Length; i = i + channels) | |
{ | |
phase = phase + increment; | |
phaseLinear = phaseLinear + incrementLinear; | |
// this is where we copy audio data to make them “available” to Unity | |
//float sample = SineSyth(); | |
float sample = PerfectSyth(); | |
data[i] = sample; | |
try | |
{ | |
var key = curve[count]; | |
key.value = sample; | |
curve.MoveKey(count, key); | |
} | |
catch | |
{ | |
Debug.Log("fff"); | |
} | |
// if we have stereo, we copy the mono data to each channel | |
if (channels == 2) data[i + 1] = sample; | |
if (phase > 2 * Math.PI) phase = 0; | |
if (phaseLinear > 1) phaseLinear = 0; | |
count++; | |
} | |
} | |
private float SineSyth() | |
{ | |
float sample = (float)(Gain * Math.Sin(phase)); | |
if (WaveType != WaveType.Sine) | |
{ | |
for (int j = 2; j < WaveRefinement; j++) | |
{ | |
switch (WaveType) | |
{ | |
case WaveType.Square: | |
sample += (float)(Gain * (Math.Sin((j * 2 - 1) * phase) / (j * 2 - 1))); | |
break; | |
case WaveType.Triangle: | |
sample += (float)(Gain * (Math.Sin((j * 2 - 1) * phase) / Math.Pow(2, (j * 2 - 1)))); | |
break; | |
case WaveType.Saw: | |
sample += (float)(Gain * (Math.Sin((j * 2) * phase) / (j))); | |
break; | |
case WaveType.Noise: | |
break; | |
} | |
} | |
} | |
return sample; | |
} | |
private float PerfectSyth() | |
{ | |
float sample = 0; | |
switch (WaveType) | |
{ | |
case WaveType.Sine: | |
sample = (float)Math.Sin(Math.PI * 2.0 * phaseLinear); | |
break; | |
case WaveType.Square: | |
sample = phaseLinear < 0.5 ? 1 : -1; | |
break; | |
case WaveType.Triangle: | |
sample = (float)(phaseLinear < 0.25 ? phaseLinear * 4.0 : phaseLinear < 0.75 ? 2.0 - phaseLinear * 4.0 : phaseLinear * 4.0 - 4.0); | |
break; | |
case WaveType.Saw: | |
sample = (float)(phaseLinear < 0.5 ? phaseLinear * 2.0 : phaseLinear * 2.0 - 2.0); | |
break; | |
case WaveType.Noise: | |
sample = 0.5f; | |
break; | |
default: | |
break; | |
} | |
return (float)Gain * sample; | |
} | |
} | |
public enum WaveType | |
{ | |
Sine, | |
Square, | |
Triangle, | |
Saw, | |
Noise | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment