-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVoice.cs
More file actions
107 lines (96 loc) · 4.48 KB
/
Copy pathVoice.cs
File metadata and controls
107 lines (96 loc) · 4.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using UnityEngine;
using System;
[RequireComponent(typeof(AudioSource))]
[RequireComponent(typeof(NoteToFreq))]
public class Voice : MonoBehaviour
{
//misc references
public ChordSpawner parentChordSpawnerRef;
//wave-gen stuff
private double increment;
private double phase;
private readonly double sampling_frequency = 44100;
public bool overrideWaveType = false;
public ChordSpawner.WaveTypesSelector _wavetypeenmumfromchord;
//volume stuff
public float currentOscGain = 0f;
public float targetOscGain = 0.1f;
[Range(0, 1)]
public float targetOscGainMP = 1f;
public float oscGainLerpSpeed = 0.25f;
//note stuff
public float frequency = 220;
private double finalOscGain = 0.1f;
private float actualFrequency;
public float newFrequency = 440;
public float noteLerpSpeedInSec = 1f;
//noise gen
private System.Random randomNumber = new System.Random();
private readonly float offset = 0.01f;
//deltatime inside audiothread
private double lastDSPtime;
private double currentDSPtime;
private double deltaDSPtime;
//START / BEGIN PLAY
private void Start()
{
gameObject.GetComponent<AudioSource>().volume = targetOscGain; //initialize volume on audiosource
lastDSPtime = AudioSettings.dspTime;//initialize audio tick delta calculation memory
}
//AUDIOTHREAD
void OnAudioFilterRead(float[] data, int channels)
{
//find audio tick delta inside audio thread
currentDSPtime = AudioSettings.dspTime;
deltaDSPtime = currentDSPtime - lastDSPtime;
lastDSPtime = currentDSPtime;
// update increment in case frequency has changed
increment = actualFrequency * 2.0 * System.Math.PI / sampling_frequency;
//triangle helper
double trianglehelp = actualFrequency * 2.0 / sampling_frequency;
for (var i = 0; i < data.Length; i = i + channels)
{
phase = phase + increment;
//select wave type
switch (_wavetypeenmumfromchord)
{
case ChordSpawner.WaveTypesSelector.Sine:
//generate sine wave
data[i] = (float)(System.Math.Sin(phase));
break;
case ChordSpawner.WaveTypesSelector.Triangle:
//generate triangle wave
double div = i * trianglehelp;
data[i] = (float)(((((int)div) % 2 == 0) ? -finalOscGain : finalOscGain) * (1.0 - 2.0 * (div - (int)div)));
break;
case ChordSpawner.WaveTypesSelector.Square:
//generate square wave
data[i] = Mathf.Sign(Mathf.Sin((float)phase * 2f * Mathf.PI));
break;
case ChordSpawner.WaveTypesSelector.Noise:
//generate noise wave
data[i] = offset - 1.0f + (float)randomNumber.NextDouble() * 2.0f;
break;
}
//make sure channel-summing doesn't blow stuff up
if (channels == 2) data[i + 1] = data[i];
//reset out-of-bounds wave-phase
if (phase > 2 * System.Math.PI) phase = 0;
}
//send frequency changes async, from gamethread
frequency = Mathf.MoveTowards(frequency, newFrequency, ((frequency + newFrequency) * (1 / noteLerpSpeedInSec)) * (float)deltaDSPtime);
actualFrequency = frequency;
}
//GAMETHREAD
private void Update()
{
if (overrideWaveType == false && _wavetypeenmumfromchord != parentChordSpawnerRef._waveTypesSelector) //locally override waveType of this voice?
{
_wavetypeenmumfromchord = parentChordSpawnerRef._waveTypesSelector;
}
//send volume changes
currentOscGain = Mathf.MoveTowards(currentOscGain, targetOscGain, oscGainLerpSpeed * Time.deltaTime); //interp current gain towards target gain
finalOscGain = currentOscGain * targetOscGainMP; //multiply volume with
gameObject.GetComponent<AudioSource>().volume = (float)finalOscGain; //set volume on audioSOURCE
}
}