Commit 69ea7238 authored by Nathan De Castro's avatar Nathan De Castro

Now using RMS, made mesh smaller

parent 44344a15
......@@ -49,6 +49,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Assets\AudioAnalysis.cs" />
<Compile Include="Assets\Scripts\AI\AI.cs" />
<Compile Include="Assets\Scripts\AI\CurrentPlayer.cs" />
<Compile Include="Assets\Scripts\Effects\BigEnabler.cs" />
......
 using UnityEngine;
public class AudioAnalysis : MonoBehaviour {
static public AudioAnalysis i;
public float RmsValue;
public float DbValue;
public float PitchValue;
private const int QSamples = 1024;
private const float RefValue = 0.1f;
private const float Threshold = 0.02f;
float[] _samples;
private float[] _spectrum;
private float _fSample;
void Start () {
i = this;
GetComponent<AudioSource> ().clip = Microphone.Start ("Built-in Microphone", true, 1, AudioSettings.outputSampleRate);
GetComponent<AudioSource> ().loop = true;
GetComponent<AudioSource> ().Play ();
GetComponent<AudioSource> ().volume = 0.0f;
_samples = new float[QSamples];
_spectrum = new float[QSamples];
_fSample = AudioSettings.outputSampleRate;
}
void Update () {
AnalyzeSound ();
}
void AnalyzeSound () {
GetComponent<AudioSource> ().GetOutputData (_samples, 0); // fill array with samples
int i;
float sum = 0;
for (i = 0; i < QSamples; i++) {
sum += _samples[i] * _samples[i]; // sum squared samples
}
RmsValue = Mathf.Sqrt (sum / QSamples); // rms = square root of average
DbValue = 20 * Mathf.Log10 (RmsValue / RefValue); // calculate dB
if (DbValue < -160) DbValue = -160; // clamp it to -160dB min
// get sound spectrum
GetComponent<AudioSource> ().GetSpectrumData (_spectrum, 0, FFTWindow.BlackmanHarris);
float maxV = 0;
var maxN = 0;
for (i = 0; i < QSamples; i++) { // find max
if (!(_spectrum[i] > maxV) || !(_spectrum[i] > Threshold))
continue;
maxV = _spectrum[i];
maxN = i; // maxN is the index of max
}
float freqN = maxN; // pass the index to a float variable
if (maxN > 0 && maxN < QSamples - 1) { // interpolate index using neighbours
var dL = _spectrum[maxN - 1] / _spectrum[maxN];
var dR = _spectrum[maxN + 1] / _spectrum[maxN];
freqN += 0.5f * (dR * dR - dL * dL);
}
PitchValue = freqN * (_fSample / 2) / QSamples; // convert index to frequency
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 0affc6b8d6d55dd4692f15bf27ff327d
timeCreated: 1490099850
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
fileFormatVersion: 2
guid: ea36b06c362d00a46b21d2c6fe734634
timeCreated: 1490029294
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
fileFormatVersion: 2
guid: d28af33c617a9d843ac1c7e4dfc26a7a
timeCreated: 1490029683
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
This source diff could not be displayed because it is too large. You can view the blob instead.
fileFormatVersion: 2
guid: 07450b72d45f7884181c594c53bcbcf0
timeCreated: 1490096407
licenseType: Free
NativeFormatImporter:
userData:
assetBundleName:
assetBundleVariant:
......@@ -10,7 +10,7 @@ public class BigEnabler : MonoBehaviour {
}
// Update is called once per frame
void Update () {
if (AudioManager.instance.GetPitchValue () == 1) {
if (AudioManager.instance.GetAveragePitch ()[2] > 0.5f) {
Activated = true;
} else {
Activated = false;
......
......@@ -10,7 +10,7 @@ public class MediumEnabler : MonoBehaviour {
}
// Update is called once per frame
void Update () {
if (AudioManager.instance.GetPitchValue () == 1) {
if (AudioManager.instance.GetAveragePitch ()[1] < 0.5f) {
Activated = true;
} else {
Activated = false;
......
......@@ -10,7 +10,7 @@ public class SmallEnabler : MonoBehaviour {
}
// Update is called once per frame
void Update () {
if (AudioManager.instance.GetPitchValue () == 0) {
if (AudioManager.instance.GetAveragePitch ()[0] < 0.5f) {
Activated = true;
} else {
Activated = false;
......
......@@ -6,7 +6,6 @@ public class AudioManager : MonoBehaviour {
public static AudioManager instance;
//Global
private AudioClip mic;
private AudioSource mic_source;
public float volume_range_min;
public float volume_range_max;
......@@ -16,73 +15,105 @@ public class AudioManager : MonoBehaviour {
public float light_angle_max;
public float splash_force_value;
private float rms;
private float vol;
private float low_pitch = 0;
private float med_pitch = 0;
private float high_pitch = 0;
void Start () {
instance = this;
mic_source = GetComponent<AudioSource> ();
// print ("AudioManager initialized");
mic = Microphone.Start ("Built-in Microphone", true, 1, buffer_size); //Microphone setup (null will select the default Microphone)
mic_source.clip = mic;
mic_source.clip = Microphone.Start ("Built-in Microphone", true, 1, 256); //Microphone setup (null will select the default Microphone);
mic_source.loop = true;
mic_source.Play ();
mic_source.volume = 0.0f;
}
void Update () {
PitchAnalysis ();
AmplitudeAnalysis ();
}
public Vector3 GetSpecEnergy () {
float[] spec_data = new float[buffer_size]; //Creates an array pre-allocated (We want it quite small to reduce latency, I made it tweakable from the inspector)
mic.GetData (spec_data, 0); //Stores all the output data into the array I pre-allocated
public void AmplitudeAnalysis () {
int buf_size = 256;
float[] spec_data = new float[buf_size]; //Creates an array pre-allocated (We want it quite small to reduce latency, I made it tweakable from the inspector)
mic_source.clip.GetData (spec_data, 0); //Stores all the output data into the array I pre-allocated
float vol_sum = 0;
for (int i = 0; i < buf_size; i++) {
vol_sum += Mathf.Abs (spec_data[i] * spec_data[i]); //Only grabs the second Third values of the array (so the "low" pitch values)
}
rms = Mathf.Sqrt (vol_sum / buf_size) * 100; //RMS value
vol = 0;
if (!(vol < -30))
vol = 20 * Mathf.Log10 (rms / 0.1f);
else vol = -30;
}
public float GetRMS () {
return rms;
}
public float GetVolume(){
return vol;
}
public void PitchAnalysis () {
int buf_size = 256;
float[] spec_data = new float[buf_size];
AudioListener.GetSpectrumData (spec_data, 0, FFTWindow.Rectangular);
print (spec_data[100]);
//Low Pitch
float low_pitch_sum = 0; //Inits a float to store the sum of all the index arrays
for (int spec_index = 0; spec_index < spec_data.Length / 3; spec_index++) {
for (int spec_index = 0; spec_index < 20; spec_index++) {
low_pitch_sum += Mathf.Abs (spec_data[spec_index]); //Only grabs the first Third values of the array (so the "low" pitch values)
}
//Medium Pitch
float mid_pitch_sum = 0; //Inits a float to store the sum of all the index arrays
for (int spec_index = 0; spec_index < spec_data.Length / 3; spec_index++) {
mid_pitch_sum += Mathf.Abs (spec_data[spec_index + spec_data.Length / 3]); //Only grabs the second Third values of the array (so the "low" pitch values)
for (int spec_index = 20; spec_index < 100; spec_index++) {
mid_pitch_sum += Mathf.Abs (spec_data[spec_index]); //Only grabs the second Third values of the array (so the "low" pitch values)
}
//High Pitch<
float high_pitch_sum = 0; //Inits a float to store the sum of all the index arrays
for (int spec_index = 0; spec_index < spec_data.Length / 3; spec_index++) {
high_pitch_sum += Mathf.Abs (spec_data[spec_index + ((spec_data.Length / 3) * 2)]); //Only grabs the third Third values of the array (so the "low" pitch values)
for (int spec_index = 100; spec_index < spec_data.Length; spec_index++) {
high_pitch_sum += Mathf.Abs (spec_data[spec_index]); //Only grabs the third Third values of the array (so the "low" pitch values)
}
return new Vector3 ((low_pitch_sum / (spec_data.Length / 3) * 30), (mid_pitch_sum / (spec_data.Length / 3) * 30), (high_pitch_sum / (spec_data.Length / 3) * 30)); //Populates a Final vectore with the average of the sums of the all three parts of the buffer
}
public float GetAverageVolume () {
return ((GetSpecEnergy ()[0] + GetSpecEnergy ()[1] + GetSpecEnergy ()[2]) / 3); //Grouping all 3 arrays into 1 to get average of all values (global volume)
low_pitch = low_pitch_sum / 20;
med_pitch = mid_pitch_sum / 80;
high_pitch = high_pitch_sum / 156;
}
public Vector4 GetPitchData () {
float[] spec_data = new float[1024];
mic_source.GetSpectrumData (spec_data, 0, FFTWindow.Rectangular);
float Bin_1 = (spec_data[0] + spec_data[2] + spec_data[4]) / 3;
float Bin_2 = (spec_data[10] + spec_data[11] + spec_data[12]) / 3;
float Bin_3 = (spec_data[20] + spec_data[21] + spec_data[22]) / 3;
float Bin_4 = (spec_data[40] + spec_data[41] + spec_data[42] + spec_data[43]) / 4;
float Bin_5 = (spec_data[80] + spec_data[81] + spec_data[82] + spec_data[83]) / 4;
float Bin_6 = (spec_data[160] + spec_data[161] + spec_data[162] + spec_data[163]) / 5;
float Bin_7 = (spec_data[320] + spec_data[321] + spec_data[322] + spec_data[323]) / 5;
return new Vector4(Bin_1, Bin_3, Bin_5, Bin_7);
public Vector3 GetAveragePitch () {
return new Vector3 (low_pitch, med_pitch, high_pitch);
}
public float GetLightAngle () {
bool threshold_reached = PlayerSound.instance.GetComponentInChildren<Light> ().spotAngle > light_angle_max;
if (!threshold_reached) {
return GetAverageVolume () * light_angle_value;
return rms * light_angle_value;
} else {
return light_angle_max;
}
}
public int GetSplashForce () {
return (int) (GetAverageVolume () * splash_force_value);
return (int) (rms * splash_force_value);
}
public Color GetLightColor () {
Color output;
//Linear interpolation:
if (linear) {
float r = Mathf.Abs ((GetAverageVolume () - volume_range_min) / volume_range_max);
float r = Mathf.Abs ((rms - volume_range_min) / volume_range_max);
float b = Mathf.Abs (1 - r);
output = new Color (r, 0, b, 0.8f);
} else {
......@@ -91,13 +122,4 @@ public class AudioManager : MonoBehaviour {
return output;
}
public int GetPitchValue () {
int output = 0;
if (GetAverageVolume () > volume_range_max - (volume_range_max / 3)) {
return output = 2;
} else if (GetAverageVolume () > volume_range_max / 3) {
return output = 1;
}
return output;
}
}
\ No newline at end of file
......@@ -5,12 +5,8 @@ public class PlayerSound : MonoBehaviour {
//LIGHT
private Light light_self;
private Color update_color;
private float update_blue;
private float update_red;
private float light_angle;
public bool use_mic = false;
// Use this for initialization
void Start () {
instance = this;
......@@ -19,16 +15,10 @@ public class PlayerSound : MonoBehaviour {
// Update is called once per frame
void Update () {
light_angle = AudioManager.instance.GetLightAngle ();
// Fade color change:
// Range 40 - 220
update_color = AudioManager.instance.GetLightColor ();
if (use_mic && this.gameObject.tag == "Player") {
light_self.spotAngle = light_angle;
light_self.color = update_color;
light_self.spotAngle = AudioManager.instance.GetLightAngle ();;
light_self.color = AudioManager.instance.GetLightColor ();;
}
}
}
\ No newline at end of file
......@@ -11,19 +11,16 @@ public class RippleEffect : MonoBehaviour {
//This is why we need to create our own plane with many many vertices
private Mesh mesh; //Will store the created mesh
private Vector3[] vertices; //private Vector3[] normals ;
public float dampner = 0.800f; //How fast we want the wave to fade out
public float dampner; //How fast we want the wave to fade out
private int splash_force = 150; //How strongly we want our splash to be
private int splash_force_mic = 0; //Variable that will update the splash_force according to the mic
private bool swap_buffer = true; //Switches between the first and the second buffer
private bool ticked = false;
public int update_rate = 120;
public int mic_threshold = 2;
public int spread_bit_shift = 1;
public float wave_height_max = 2.0f;
static public int update_rate = 5;
public int spread_bit_shift;
private Vector3[] current_vertices;
public int cols = 128; //Number of the columns we want our plane to have (The bigger this is, the more computer intensive the calculations will be)
public int rows = 128; //Number of the rows we want our plane to have
public int cols; //Number of the columns we want our plane to have (The bigger this is, the more computer intensive the calculations will be)
public int rows; //Number of the rows we want our plane to have
void Start () {
MeshFilter mesh_filter = GetComponent<MeshFilter> (); //Attaches the mesh filter in he object to the mesh filter variable
......@@ -39,7 +36,7 @@ public class RippleEffect : MonoBehaviour {
vertex_indexes = new int[vertices.Length]; // Create an int array and allocates it's size to the number of vertices
/* ***************** Initializes and Populates the buffers (These two for loops have been inspired by the work of Ben Britten) ******************** */
/* ***************** Initializes and Populates then buffers (These two for loops have been inspired by the work of Ben Britten) ******************** */
int vertices_index = 0;
for (vertices_index = 0; vertices_index < vertices.Length; vertices_index++) {
vertex_indexes[vertices_index] = -1;
......@@ -93,10 +90,11 @@ public class RippleEffect : MonoBehaviour {
}
// Update is called once per frame
void Update () {
ticked = tick (update_rate);
splash_force_mic = AudioManager.instance.GetSplashForce ();
SplashDetect (); //Checks wether a splash has been initiated
update_rate = 3 + Mathf.Abs(20 - ((int) AudioManager.instance.GetRMS ()));
if (tick (update_rate) && PlayerSound.instance.use_mic == true && AudioManager.instance.GetRMS () >= 4f) {
splash_force_mic = AudioManager.instance.GetSplashForce ();
SplashDetect (); //Checks wether a splash has been initiated
}
int[] current_buffer;
if (swap_buffer) {
// process the ripples for this frame
......@@ -116,31 +114,31 @@ public class RippleEffect : MonoBehaviour {
{
current_index = vertex_indexes[i];
current_vertices[current_index] = vertices[current_index];
current_vertices[current_index].y += (current_buffer[i] * 1.0f / splash_force_mic) * wave_height_max; //This is what raises the current "tile"'s Y value by the splash force times the maximum height of the wave}
current_vertices[current_index].y += (current_buffer[i] * 1.0f / 100); //This is what raises the current "tile"'s Y value by the splash force times the maximum height of the wave}
}
GetComponent<MeshFilter> ().mesh = mesh; //Updates it to unity
mesh.vertices = current_vertices; //Updates the mesh! :)
}
void SplashDetect () {
if (ticked && splash_force_mic > mic_threshold) //Either Microphone output or the space bar
{
/* Ray cast function to set the splash position */
RaycastHit player_hit; //Will store all the info on the object the ray will collide
Vector3 player_down = CurrentPlayer.instance.player.transform.TransformDirection (Vector3.down); //Create a raycast from the player's position downwards
if (Physics.Raycast (CurrentPlayer.instance.player.transform.position, player_down, out player_hit)) // Draws a ray downwards from the player and stores the impact location
{
// First we must init the tiles
Bounds bounds = mesh.bounds;
float xStep = (bounds.max.x - bounds.min.x) / cols;
float zStep = (bounds.max.z - bounds.min.z) / rows;
float xCoord = (bounds.max.x - bounds.min.x) - ((bounds.max.x - bounds.min.x) * player_hit.textureCoord.x); //Sets the X coordinates for the splash
float zCoord = (bounds.max.z - bounds.min.z) - ((bounds.max.z - bounds.min.z) * (player_hit.textureCoord.y)); //Sets the Y coordinates for the splash
float column = (xCoord / xStep);
float row = (zCoord / zStep);
SplashAtPoint ((int) column, (int) row); //Generates the splash!
}
/* Ray cast function to set the splash position */
RaycastHit player_hit; //Will store all the info on the object the ray will collide
Vector3 player_down = CurrentPlayer.instance.player.transform.TransformDirection (Vector3.down); //Create a raycast from the player's position downwards
if (Physics.Raycast (CurrentPlayer.instance.player.transform.position, player_down, out player_hit)) // Draws a ray downwards from the player and stores the impact location
{
// First we must init the tiles
Bounds bounds = mesh.bounds;
float xStep = (bounds.max.x - bounds.min.x) / cols;
float zStep = (bounds.max.z - bounds.min.z) / rows;
float xCoord = (bounds.max.x - bounds.min.x) - ((bounds.max.x - bounds.min.x) * player_hit.textureCoord.x); //Sets the X coordinates for the splash
float zCoord = (bounds.max.z - bounds.min.z) - ((bounds.max.z - bounds.min.z) * (player_hit.textureCoord.y)); //Sets the Y coordinates for the splash
float column = (xCoord / xStep);
float row = (zCoord / zStep);
SplashAtPoint ((int) column, (int) row); //Generates the splash!
}
if (GhostSound.instance != null && GhostSound.instance.made_noise) {
print ("Ghost made some noise");
RaycastHit ghost_hit; //Will store all the info on the object the ray will collide
......
......@@ -10,7 +10,7 @@ public class Info : MonoBehaviour {
}
void Update () {
info_text.text = "Average Vol: " + AudioManager.instance.GetAverageVolume () + " Max: " + AudioManager.instance.volume_range_max;
info_text.text = "RMS: " + AudioManager.instance.GetRMS () + " Pitch: " + AudioManager.instance.GetAveragePitch ();
}
}
\ No newline at end of file
......@@ -10,7 +10,7 @@ public class Visibility : MonoBehaviour {
}
void Update () {
info_text.text = AudioManager.instance.GetPitchValue().ToString();
info_text.text = "Power: " + RippleEffect.update_rate;
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
fileFormatVersion: 2
guid: 50f848649c0a61744b46913114b6881a
guid: 1c3b6dae14201a549871460d54030ee2
timeCreated: 1485509989
licenseType: Free
DefaultImporter:
......
No preview for this file type
No preview for this file type
Base path: C:/Program Files/Unity/Editor/Data
Cmd: getPlatforms
Cmd: compileSnippet
api=4 type=0 insize=1517 outsize=666 kw= pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Cmd: compileSnippet
api=4 type=1 insize=1517 outsize=666 kw= pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Cmd: compileSnippet
api=4 type=0 insize=1023 outsize=2090 kw=DIRECTIONAL SHADOWS_SCREEN DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON _EMISSION pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Cmd: compileSnippet
api=4 type=1 insize=1023 outsize=5638 kw=DIRECTIONAL SHADOWS_SCREEN DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON _EMISSION pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Cmd: compileSnippet
api=4 type=0 insize=1023 outsize=2102 kw=DIRECTIONAL SHADOWS_SCREEN LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON _EMISSION pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Cmd: compileSnippet
api=4 type=1 insize=1023 outsize=4846 kw=DIRECTIONAL SHADOWS_SCREEN LIGHTMAP_ON DIRLIGHTMAP_COMBINED DYNAMICLIGHTMAP_ON _EMISSION pd=UNITY_ENABLE_REFLECTION_BUFFERS UNITY_PBS_USE_BRDF1 UNITY_SPECCUBE_BOX_PROJECTION UNITY_SPECCUBE_BLENDING SHADER_API_DESKTOP ok=1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment