Skip to content

Instantly share code, notes, and snippets.

@keijiro
Last active April 5, 2022 04:59
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keijiro/6037861 to your computer and use it in GitHub Desktop.
Save keijiro/6037861 to your computer and use it in GitHub Desktop.
「Unity でシンセを作るワークショップ」コピペ帳
////////////////////////////////
//////////////////////////////// BASIC SETUP
////////////////////////////////
var freq = 440.0;
var semitone = 0;
var octave = 0;
private var sampleRate = 44100.0;
private var time01 = 0.0;
private var noteOn = false;
function UpdateSynth() {
freq = 440.0 * Mathf.Pow(2.0, (semitone - 9 + octave * 12) / 12.0);
}
function TickSynth() {
// ---------------- EDIT HERE ----------------
return Mathf.Sin(time01 * Mathf.PI * 2);
}
function Start() {
sampleRate = AudioSettings.outputSampleRate;
}
function Update() {
ProcessKeyboard();
FindObjectOfType(OscilloscopeInput).freq = freq / 4;
}
function OnAudioFilterRead(data : float[], channels : int) {
UpdateSynth();
var delta = freq / sampleRate;
for (var i = 0; i < data.Length; i += 2) {
time01 += delta;
time01 -= Mathf.Floor(time01);
data[i] = data[i + 1] = TickSynth();
}
}
private var keyboardArray = [
'a', 'w', 's', 'e', 'd',
'f', 't', 'g', 'y', 'h', 'u', 'j',
'k', 'o', 'l', 'p', ';'
];
private var lastPressedKey = '';
function ProcessKeyboard() {
for (var i = 0; i < keyboardArray.Length; i++) {
var key = keyboardArray[i];
if (Input.GetKeyDown(key)) {
semitone = i;
lastPressedKey = key;
noteOn = true;
} else if (Input.GetKeyUp(key) && lastPressedKey == key) {
lastPressedKey = '';
noteOn = false;
}
}
if (Input.GetKeyDown('z')) octave--;
if (Input.GetKeyDown('x')) octave++;
}
////////////////////////////////
//////////////////////////////// WAVEFORM FUNCTIONS
////////////////////////////////
// Sine wave
return Mathf.Sin(time01 * Mathf.PI * 2);
// Sawtooth wave
return time01 * 2 - 1;
// Square wave
return time01 < 0.5 ? -1 : 1;
// Pulse wave
return time01 < modulation ? -1 : 1;
// Triange wave
return time01 < 0.25 ? time01 * 4 : (time01 < 0.75 ? 2.0 - time01 * 4.0 : time01 * 4 - 4);
// Saturated sine wave
return Mathf.Clamp(Mathf.Sin(time01 * Mathf.PI * 2) * 2.0, -1.0, 1.0);
// 4-bit Sine wave
return Mathf.Floor(Mathf.Sin(time01 * Mathf.PI * 2) * 8) / 8;
// FM Synthesis
var mod = Mathf.Sin(time01 * Mathf.PI * 2 * 8) * modulation;
return Mathf.Sin(time01 * Mathf.PI * 2 + mod);
////////////////////////////////
//////////////////////////////// ENVELOPE
////////////////////////////////
private var envelope = 0.0;
var attack = 0.1;
var release = 0.5;
function TickSynth() {
if (noteOn) {
envelope += 1.0 / (sampleRate * attack);
} else {
envelope -= 1.0 / (sampleRate * release);
}
envelope = Mathf.Clamp01(envelope);
return Mathf.Sin(time01 * Mathf.PI * 2) * envelope;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment