Skip to content

Instantly share code, notes, and snippets.

@mzandvliet
Created December 23, 2020 21:33
Show Gist options
  • Save mzandvliet/a09072a535a6d989fd000520cc5066b2 to your computer and use it in GitHub Desktop.
Save mzandvliet/a09072a535a6d989fd000520cc5066b2 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
/*
Possible effects to model:
Attenuation of taps
- Apparent surface area
- angle of incidence
Frequency dependent effects
- Air absorbtion
- material absorption
Architectural/geometrical detail
- stair steps (90 vs. 91)
- stair rails
- outer layers (9)
- top cabin
Diffraction
--
Oh wait, none of that is needed, this just works.
Ah well, mystery solved.
*/
public class Quetzalcoatl : MonoBehaviour
{
[SerializeField] private AudioClip _impulseClip;
private const float SpeedOfSound = 321f;
private int _numStairSteps = 91;
private AudioClip _resultClip;
private AudioSource _source;
void Start()
{
var stopWatch = System.Diagnostics.Stopwatch.StartNew();
var impulse = new float[_impulseClip.samples];
var result = new float[_impulseClip.samples * 4];
_impulseClip.GetData(impulse, 0);
Vector3 listenPos = new Vector3(0f, 1.5f, 0f);
for (int i = 0; i < impulse.Length; i++)
{
result[i] += impulse[i];
}
for (int i = 0; i < _numStairSteps; i++)
{
Vector3 stepPos = StepPos(i);
float roundTripDist = Vector3.Distance(listenPos, stepPos) * 2f;
float delaySecs = roundTripDist / SpeedOfSound;
int delaySamples = (int)(_impulseClip.frequency * delaySecs);
float atten = 1f / _numStairSteps;
for (int j = 0; j < impulse.Length; j++)
{
if (delaySamples + j > result.Length) {
Debug.LogError("Oops, result buffer isn't long enough for step reflection: " + i);
return;
}
result[delaySamples + j] += impulse[j] * atten;
}
}
_resultClip = AudioClip.Create("reflection", result.Length, 1, _impulseClip.frequency, false);
_resultClip.SetData(result, 0);
_source = gameObject.AddComponent<AudioSource>();
_source.clip = _resultClip;
var filePath = Path.ChangeExtension(Path.Combine(Path.Combine(Directory.GetParent(Application.dataPath).FullName, "SoundOutput"), "render_"+System.DateTime.UtcNow.ToFileTimeUtc().ToString()), "wav");
Debug.Log("Saving to: " + filePath);
UnitySpeechToText.Utilities.SavWav.Save(filePath, _resultClip);
stopWatch.Stop();
Debug.Log($"Render complete, took: {(stopWatch.ElapsedMilliseconds / 1000f)} seconds");
}
private static Vector3 StepPos(int step) {
const float stepDepth = 0.33f;
const float stepHeight = 0.33f;
Vector3 stairStart = new Vector3(0f, 0f, 25f);
return stairStart + new Vector3(
0f,
stepHeight * step,
stepDepth * step
);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) {
_source.Play();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment