├── .gitignore ├── Assets ├── Audio.meta ├── Audio │ ├── Chamber of Secrets for 1.wav │ └── Chamber of Secrets for 1.wav.meta ├── Lib.meta ├── Lib │ ├── External.meta │ ├── External │ │ ├── DSPLib.meta │ │ ├── DSPLib │ │ │ ├── DSPLib.cs │ │ │ └── DSPLib.cs.meta │ │ ├── NET.meta │ │ └── NET │ │ │ ├── Complex.cs │ │ │ └── Complex.cs.meta │ ├── Internal.meta │ └── Internal │ │ ├── PlotController.cs │ │ ├── PlotController.cs.meta │ │ ├── SongController.cs │ │ ├── SongController.cs.meta │ │ ├── SpectralFluxAnalyzer.cs │ │ └── SpectralFluxAnalyzer.cs.meta ├── Materials.meta ├── Materials │ ├── BrightBlue.mat │ ├── BrightBlue.mat.meta │ ├── BrightGreen.mat │ ├── BrightGreen.mat.meta │ ├── BrightRed.mat │ ├── BrightRed.mat.meta │ ├── Grey.mat │ └── Grey.mat.meta ├── PlotDemo.unity ├── PlotDemo.unity.meta ├── Resources.meta └── Resources │ ├── Point.prefab │ └── Point.prefab.meta ├── LICENSE ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── NetworkManager.asset ├── Physics2DSettings.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset └── UnityConnectSettings.asset ├── README.md └── UnityPackageManager └── manifest.json /.gitignore: -------------------------------------------------------------------------------- 1 | /[Ll]ibrary/ 2 | /[Tt]emp/ 3 | /[Oo]bj/ 4 | /[Bb]uild/ 5 | /[Bb]uilds/ 6 | /Assets/AssetStoreTools* 7 | 8 | # Visual Studio 2015 cache directory 9 | /.vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | 26 | # Unity3D generated meta files 27 | *.pidb.meta 28 | 29 | # Unity3D Generated File On Crash Reports 30 | sysinfo.txt 31 | 32 | # Builds 33 | *.apk 34 | *.unitypackage 35 | -------------------------------------------------------------------------------- /Assets/Audio.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a1f92f7faaead284aa4b5a1be1ccb0e5 3 | folderAsset: yes 4 | timeCreated: 1518749025 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Audio/Chamber of Secrets for 1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesse-scam/algorithmic-beat-mapping-unity/3c50c75e4d39bd6d1e68be7fedf22cf7a9ef8d3e/Assets/Audio/Chamber of Secrets for 1.wav -------------------------------------------------------------------------------- /Assets/Audio/Chamber of Secrets for 1.wav.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 011903a47b70002479ab7619fb564f5c 3 | timeCreated: 1518750029 4 | licenseType: Free 5 | AudioImporter: 6 | externalObjects: {} 7 | serializedVersion: 6 8 | defaultSettings: 9 | loadType: 0 10 | sampleRateSetting: 0 11 | sampleRateOverride: 44100 12 | compressionFormat: 1 13 | quality: 1 14 | conversionMode: 0 15 | platformSettingOverrides: {} 16 | forceToMono: 0 17 | normalize: 1 18 | preloadAudioData: 1 19 | loadInBackground: 0 20 | ambisonic: 0 21 | 3D: 1 22 | userData: 23 | assetBundleName: 24 | assetBundleVariant: 25 | -------------------------------------------------------------------------------- /Assets/Lib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b4af3ffa397be14da24c6db32d18916 3 | folderAsset: yes 4 | timeCreated: 1518748071 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Lib/External.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5a92943e4f50e2a4887dab0c8c0aa10f 3 | folderAsset: yes 4 | timeCreated: 1518748091 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Lib/External/DSPLib.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ed9051149927b246b302b0fec2d0c71 3 | folderAsset: yes 4 | timeCreated: 1518748189 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Lib/External/DSPLib/DSPLib.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Numerics; 3 | using System.Diagnostics; 4 | 5 | 6 | // =====[ Revision History ]========================================== 7 | // 17Jun16 - 1.0 - First release - Steve Hageman 8 | // 20Jun16 - 1.01 - Made some variable terms consistent - Steve Hageman 9 | // 16Jul16 - 1.02 - Calculated sign of DFT phase was not consistent with that of the FFT. ABS() of phase was right. 10 | // FFT with zero padding did not correctly clean up first runs results. 11 | // Added UnwrapPhaseDegrees() and UnwrapPhaseRadians() to Analysis Class. 12 | // 04Jul17 - 1.03 - Added zero or negative check to all Log10 operations. 13 | // 15Oct17 - 1.03.1 - Slight interoperability correction to V1.03, same results, different design pattern. 14 | // 15 | 16 | 17 | namespace DSPLib 18 | { 19 | 20 | #region =====[ DFT Core Class ]====================================================== 21 | 22 | /** 23 | * Performs a complex DFT w/Optimizations for .NET >= 4. 24 | * 25 | * Released under the MIT License 26 | * 27 | * DFT Core Functions Copyright (c) 2016 Steven C. Hageman 28 | * 29 | * Permission is hereby granted, free of charge, to any person obtaining a copy 30 | * of this software and associated documentation files (the "Software"), to 31 | * deal in the Software without restriction, including without limitation the 32 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 33 | * sell copies of the Software, and to permit persons to whom the Software is 34 | * furnished to do so, subject to the following conditions: 35 | * 36 | * The above copyright notice and this permission notice shall be included in 37 | * all copies or substantial portions of the Software. 38 | * 39 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 43 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 44 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 45 | * IN THE SOFTWARE. 46 | */ 47 | 48 | /// 49 | /// DFT Base Class 50 | /// 51 | public class DFT 52 | { 53 | /// 54 | /// DFT Class 55 | /// 56 | public DFT() { } 57 | 58 | #region Properties 59 | 60 | private double mDFTScale; // DFT ONLY Scale Factor 61 | private UInt32 mLengthTotal; // mN + mZp 62 | private UInt32 mLengthHalf; // (mN + mZp) / 2 63 | 64 | private double[,] mCosTerm; // Caching of multiplication terms to save time 65 | private double[,] mSinTerm; // on smaller DFT's 66 | private bool mOutOfMemory; // True = Caching ran out of memory. 67 | 68 | 69 | /// 70 | /// Read only Boolean property. True meas the currently defined DFT is using cached memory to speed up calculations. 71 | /// 72 | public bool IsUsingCached 73 | { 74 | private set { } 75 | get { return !mOutOfMemory; } 76 | } 77 | 78 | #endregion 79 | 80 | #region Core DFT Routines 81 | 82 | /// 83 | /// Pre-Initializes the DFT. 84 | /// Must call first and this anytime the FFT setup changes. 85 | /// 86 | /// 87 | /// 88 | /// True will force the DFT to not use pre-calculated caching. 89 | public void Initialize(UInt32 inputDataLength, UInt32 zeroPaddingLength = 0, bool forceNoCache = false) 90 | { 91 | // Save the sizes for later 92 | mLengthTotal = inputDataLength + zeroPaddingLength; 93 | mLengthHalf = (mLengthTotal / 2) + 1; 94 | 95 | // Set the overall scale factor for all the terms 96 | mDFTScale = Math.Sqrt(2) / (double)(inputDataLength + zeroPaddingLength); // Natural DFT Scale Factor // Window Scale Factor 97 | mDFTScale *= ((double)(inputDataLength + zeroPaddingLength)) / (double)inputDataLength; // Account For Zero Padding // Zero Padding Scale Factor 98 | 99 | 100 | if (forceNoCache == true) 101 | { 102 | // If optional No Cache - just flag that the cache failed 103 | // then the routines will use the brute force DFT methods. 104 | mOutOfMemory = true; 105 | return; 106 | } 107 | 108 | // Try to make pre-calculated sin/cos arrays. If not enough memory, then 109 | // use a brute force DFT. 110 | // Note: pre-calculation speeds the DFT up by about 5X (on a core i7) 111 | mOutOfMemory = false; 112 | try 113 | { 114 | mCosTerm = new double[mLengthTotal, mLengthTotal]; 115 | mSinTerm = new double[mLengthTotal, mLengthTotal]; 116 | 117 | double scaleFactor = 2.0 * Math.PI / mLengthTotal; 118 | 119 | //Parallel.For(0, mLengthHalf, (j) => 120 | for (int j = 0; j < mLengthHalf; j++) 121 | { 122 | double a = j * scaleFactor; 123 | for (int k = 0; k < mLengthTotal; k++) 124 | { 125 | mCosTerm[j, k] = Math.Cos(a * k) * mDFTScale; 126 | mSinTerm[j, k] = Math.Sin(a * k) * mDFTScale; 127 | } 128 | } 129 | } 130 | catch (OutOfMemoryException) 131 | { 132 | // Could not allocate enough room for the cache terms 133 | // So, will use brute force DFT 134 | mOutOfMemory = true; 135 | } 136 | } 137 | 138 | 139 | /// 140 | /// Execute the DFT. 141 | /// 142 | /// 143 | /// Complex[] FFT Result 144 | public Complex[] Execute(double[] timeSeries) 145 | { 146 | Debug.Assert(timeSeries.Length <= mLengthTotal, "The input timeSeries length was greater than the total number of points that was initialized. DFT.Exectue()"); 147 | 148 | // Account for zero padding in size of DFT input array 149 | double[] totalInputData = new double[mLengthTotal]; 150 | Array.Copy(timeSeries, totalInputData, timeSeries.Length); 151 | 152 | Complex[] output; 153 | if (mOutOfMemory) 154 | output = Dft(totalInputData); 155 | else 156 | output = DftCached(totalInputData); 157 | 158 | return output; 159 | } 160 | 161 | #region Private DFT Implementation details 162 | 163 | /// 164 | /// A brute force DFT - Uses Task / Parallel pattern 165 | /// 166 | /// 167 | /// Complex[] result 168 | private Complex[] Dft(double[] timeSeries) 169 | { 170 | UInt32 n = mLengthTotal; 171 | UInt32 m = mLengthHalf; 172 | double[] re = new double[m]; 173 | double[] im = new double[m]; 174 | Complex[] result = new Complex[m]; 175 | double sf = 2.0 * Math.PI / n; 176 | 177 | // Parallel.For(0, m, (j) => 178 | for (UInt32 j = 0; j < m; j++) 179 | { 180 | double a = j * sf; 181 | for (UInt32 k = 0; k < n; k++) 182 | { 183 | re[j] += timeSeries[k] * Math.Cos(a * k) * mDFTScale; 184 | im[j] -= timeSeries[k] * Math.Sin(a * k) * mDFTScale; 185 | } 186 | 187 | result[j] = new Complex(re[j], im[j]); 188 | }; 189 | 190 | // DC and Fs/2 Points are scaled differently, since they have only a real part 191 | result[0] = new Complex(result[0].Real / Math.Sqrt(2), 0.0); 192 | result[mLengthHalf - 1] = new Complex(result[mLengthHalf - 1].Real / Math.Sqrt(2), 0.0); 193 | 194 | return result; 195 | } 196 | 197 | /// 198 | /// DFT with Pre-calculated Sin/Cos arrays + Task / Parallel pattern. 199 | /// DFT can only be so big before the computer runs out of memory and has to use 200 | /// the brute force DFT. 201 | /// 202 | /// 203 | /// Complex[] result 204 | private Complex[] DftCached(double[] timeSeries) 205 | { 206 | UInt32 n = mLengthTotal; 207 | UInt32 m = mLengthHalf; 208 | double[] re = new double[m]; 209 | double[] im = new double[m]; 210 | Complex[] result = new Complex[m]; 211 | 212 | //Parallel.For(0, m, (j) => 213 | for (UInt32 j = 0; j < m; j++) 214 | { 215 | for (UInt32 k = 0; k < n; k++) 216 | { 217 | re[j] += timeSeries[k] * mCosTerm[j, k]; 218 | im[j] -= timeSeries[k] * mSinTerm[j, k]; 219 | } 220 | result[j] = new Complex(re[j], im[j]); 221 | }; 222 | 223 | // DC and Fs/2 Points are scaled differently, since they have only a real part 224 | result[0] = new Complex(result[0].Real / Math.Sqrt(2), 0.0); 225 | result[mLengthHalf - 1] = new Complex(result[mLengthHalf - 1].Real / Math.Sqrt(2), 0.0); 226 | 227 | return result; 228 | } 229 | 230 | #endregion 231 | 232 | #endregion 233 | 234 | #region Utility Functions 235 | 236 | /// 237 | /// Return the Frequency Array for the currently defined DFT. 238 | /// Takes into account the total number of points and zero padding points that were defined. 239 | /// 240 | /// 241 | /// 242 | public double[] FrequencySpan(double samplingFrequencyHz) 243 | { 244 | UInt32 points = mLengthHalf; 245 | double[] result = new double[points]; 246 | double stopValue = samplingFrequencyHz / 2.0; 247 | double increment = stopValue / ((double)points - 1.0); 248 | 249 | for (UInt32 i = 0; i < points; i++) 250 | result[i] += increment * i; 251 | 252 | return result; 253 | } 254 | 255 | } 256 | 257 | #endregion 258 | 259 | #endregion 260 | 261 | 262 | #region =====[ FFT Core Class ]====================================================== 263 | 264 | /** 265 | * Performs an in-place complex FFT. 266 | * 267 | * Released under the MIT License 268 | * 269 | * Core FFT class based on, 270 | * Fast C# FFT - Copyright (c) 2010 Gerald T. Beauregard 271 | * 272 | * Changes to: Interface, scaling, zero padding, return values. 273 | * Change to .NET Complex output types and integrated with my DSP Library. 274 | * Note: Complex Number Type requires .NET >= 4.0 275 | * 276 | * These changes as noted above Copyright (c) 2016 Steven C. Hageman 277 | * 278 | * 279 | * Permission is hereby granted, free of charge, to any person obtaining a copy 280 | * of this software and associated documentation files (the "Software"), to 281 | * deal in the Software without restriction, including without limitation the 282 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 283 | * sell copies of the Software, and to permit persons to whom the Software is 284 | * furnished to do so, subject to the following conditions: 285 | * 286 | * The above copyright notice and this permission notice shall be included in 287 | * all copies or substantial portions of the Software. 288 | * 289 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 290 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 291 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 292 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 293 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 294 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 295 | * IN THE SOFTWARE. 296 | */ 297 | 298 | 299 | /// 300 | /// FFT Base Class 301 | /// 302 | public class FFT 303 | { 304 | /// 305 | /// FFT Class 306 | /// 307 | public FFT() { } 308 | 309 | #region Private Properties 310 | 311 | private double mFFTScale = 1.0; 312 | private UInt32 mLogN = 0; // log2 of FFT size 313 | private UInt32 mN = 0; // Time series length 314 | private UInt32 mLengthTotal; // mN + mZp 315 | private UInt32 mLengthHalf; // (mN + mZp) / 2 316 | private FFTElement[] mX; // Vector of linked list elements 317 | 318 | // Element for linked list to store input/output data. 319 | private class FFTElement 320 | { 321 | public double re = 0.0; // Real component 322 | public double im = 0.0; // Imaginary component 323 | public FFTElement next; // Next element in linked list 324 | public UInt32 revTgt; // Target position post bit-reversal 325 | } 326 | 327 | #endregion 328 | 329 | #region FFT Core Functions 330 | 331 | /// 332 | /// Initialize the FFT. Must call first and this anytime the FFT setup changes. 333 | /// 334 | /// 335 | /// 336 | public void Initialize(UInt32 inputDataLength, UInt32 zeroPaddingLength = 0) 337 | { 338 | mN = inputDataLength; 339 | 340 | // Find the power of two for the total FFT size up to 2^32 341 | bool foundIt = false; 342 | for (mLogN = 1; mLogN <= 32; mLogN++) 343 | { 344 | double n = Math.Pow(2.0, mLogN); 345 | if ((inputDataLength + zeroPaddingLength) == n) 346 | { 347 | foundIt = true; 348 | break; 349 | } 350 | } 351 | 352 | if (foundIt == false) 353 | throw new ArgumentOutOfRangeException("inputDataLength + zeroPaddingLength was not an even power of 2! FFT cannot continue."); 354 | 355 | // Set global parameters. 356 | mLengthTotal = inputDataLength + zeroPaddingLength; 357 | mLengthHalf = (mLengthTotal / 2) + 1; 358 | 359 | // Set the overall scale factor for all the terms 360 | mFFTScale = Math.Sqrt(2) / (double)(mLengthTotal); // Natural FFT Scale Factor // Window Scale Factor 361 | mFFTScale *= ((double)mLengthTotal) / (double)inputDataLength; // Zero Padding Scale Factor 362 | 363 | // Allocate elements for linked list of complex numbers. 364 | mX = new FFTElement[mLengthTotal]; 365 | for (UInt32 k = 0; k < (mLengthTotal); k++) 366 | mX[k] = new FFTElement(); 367 | 368 | // Set up "next" pointers. 369 | for (UInt32 k = 0; k < (mLengthTotal) - 1; k++) 370 | mX[k].next = mX[k + 1]; 371 | 372 | // Specify target for bit reversal re-ordering. 373 | for (UInt32 k = 0; k < (mLengthTotal); k++) 374 | mX[k].revTgt = BitReverse(k, mLogN); 375 | } 376 | 377 | 378 | /// 379 | /// Executes a FFT of the input time series. 380 | /// 381 | /// 382 | /// Complex[] Spectrum 383 | public Complex[] Execute(double[] timeSeries) 384 | { 385 | UInt32 numFlies = mLengthTotal >> 1; // Number of butterflies per sub-FFT 386 | UInt32 span = mLengthTotal >> 1; // Width of the butterfly 387 | UInt32 spacing = mLengthTotal; // Distance between start of sub-FFTs 388 | UInt32 wIndexStep = 1; // Increment for twiddle table index 389 | 390 | Debug.Assert(timeSeries.Length <= mLengthTotal, "The input timeSeries length was greater than the total number of points that was initialized. FFT.Exectue()"); 391 | 392 | // Copy data into linked complex number objects 393 | FFTElement x = mX[0]; 394 | UInt32 k = 0; 395 | for (UInt32 i = 0; i < mN; i++) 396 | { 397 | x.re = timeSeries[k]; 398 | x.im = 0.0; 399 | x = x.next; 400 | k++; 401 | } 402 | 403 | // If zero padded, clean the 2nd half of the linked list from previous results 404 | if( mN != mLengthTotal) 405 | { 406 | for (UInt32 i = mN; i < mLengthTotal; i++) 407 | { 408 | x.re = 0.0; 409 | x.im = 0.0; 410 | x = x.next; 411 | } 412 | } 413 | 414 | // For each stage of the FFT 415 | for (UInt32 stage = 0; stage < mLogN; stage++) 416 | { 417 | // Compute a multiplier factor for the "twiddle factors". 418 | // The twiddle factors are complex unit vectors spaced at 419 | // regular angular intervals. The angle by which the twiddle 420 | // factor advances depends on the FFT stage. In many FFT 421 | // implementations the twiddle factors are cached, but because 422 | // array lookup is relatively slow in C#, it's just 423 | // as fast to compute them on the fly. 424 | double wAngleInc = wIndexStep * -2.0 * Math.PI / (mLengthTotal); 425 | double wMulRe = Math.Cos(wAngleInc); 426 | double wMulIm = Math.Sin(wAngleInc); 427 | 428 | for (UInt32 start = 0; start < (mLengthTotal); start += spacing) 429 | { 430 | FFTElement xTop = mX[start]; 431 | FFTElement xBot = mX[start + span]; 432 | 433 | double wRe = 1.0; 434 | double wIm = 0.0; 435 | 436 | // For each butterfly in this stage 437 | for (UInt32 flyCount = 0; flyCount < numFlies; ++flyCount) 438 | { 439 | // Get the top & bottom values 440 | double xTopRe = xTop.re; 441 | double xTopIm = xTop.im; 442 | double xBotRe = xBot.re; 443 | double xBotIm = xBot.im; 444 | 445 | // Top branch of butterfly has addition 446 | xTop.re = xTopRe + xBotRe; 447 | xTop.im = xTopIm + xBotIm; 448 | 449 | // Bottom branch of butterfly has subtraction, 450 | // followed by multiplication by twiddle factor 451 | xBotRe = xTopRe - xBotRe; 452 | xBotIm = xTopIm - xBotIm; 453 | xBot.re = xBotRe * wRe - xBotIm * wIm; 454 | xBot.im = xBotRe * wIm + xBotIm * wRe; 455 | 456 | // Advance butterfly to next top & bottom positions 457 | xTop = xTop.next; 458 | xBot = xBot.next; 459 | 460 | // Update the twiddle factor, via complex multiply 461 | // by unit vector with the appropriate angle 462 | // (wRe + j wIm) = (wRe + j wIm) x (wMulRe + j wMulIm) 463 | double tRe = wRe; 464 | wRe = wRe * wMulRe - wIm * wMulIm; 465 | wIm = tRe * wMulIm + wIm * wMulRe; 466 | } 467 | } 468 | 469 | numFlies >>= 1; // Divide by 2 by right shift 470 | span >>= 1; 471 | spacing >>= 1; 472 | wIndexStep <<= 1; // Multiply by 2 by left shift 473 | } 474 | 475 | // The algorithm leaves the result in a scrambled order. 476 | // Unscramble while copying values from the complex 477 | // linked list elements to a complex output vector & properly apply scale factors. 478 | 479 | x = mX[0]; 480 | Complex[] unswizzle = new Complex[mLengthTotal]; 481 | while (x != null) 482 | { 483 | UInt32 target = x.revTgt; 484 | unswizzle[target] = new Complex(x.re * mFFTScale, x.im * mFFTScale); 485 | x = x.next; 486 | } 487 | 488 | // Return 1/2 the FFT result from DC to Fs/2 (The real part of the spectrum) 489 | //UInt32 halfLength = ((mN + mZp) / 2) + 1; 490 | Complex[] result = new Complex[mLengthHalf]; 491 | Array.Copy(unswizzle, result, mLengthHalf); 492 | 493 | // DC and Fs/2 Points are scaled differently, since they have only a real part 494 | result[0] = new Complex(result[0].Real / Math.Sqrt(2), 0.0); 495 | result[mLengthHalf - 1] = new Complex(result[mLengthHalf - 1].Real / Math.Sqrt(2), 0.0); 496 | 497 | return result; 498 | } 499 | 500 | #region Private FFT Routines 501 | 502 | /** 503 | * Do bit reversal of specified number of places of an int 504 | * For example, 1101 bit-reversed is 1011 505 | * 506 | * @param x Number to be bit-reverse. 507 | * @param numBits Number of bits in the number. 508 | */ 509 | private UInt32 BitReverse(UInt32 x, UInt32 numBits) 510 | { 511 | UInt32 y = 0; 512 | for (UInt32 i = 0; i < numBits; i++) 513 | { 514 | y <<= 1; 515 | y |= x & 0x0001; 516 | x >>= 1; 517 | } 518 | return y; 519 | } 520 | 521 | #endregion 522 | 523 | #endregion 524 | 525 | #region Utility Functions 526 | 527 | /// 528 | /// Return the Frequency Array for the currently defined FFT. 529 | /// Takes into account the total number of points and zero padding points that were defined. 530 | /// 531 | /// 532 | /// 533 | public double[] FrequencySpan(double samplingFrequencyHz) 534 | { 535 | UInt32 points = (UInt32)mLengthHalf; 536 | double[] result = new double[points]; 537 | double stopValue = samplingFrequencyHz / 2.0; 538 | double increment = stopValue / ((double)points - 1.0); 539 | 540 | for (Int32 i = 0; i < points; i++) 541 | result[i] += increment * i; 542 | 543 | return result; 544 | } 545 | 546 | #endregion 547 | 548 | } 549 | 550 | #endregion 551 | 552 | 553 | #region =====[ Generation, Conversion, Analysis and Array Manipulations ]============ 554 | 555 | public class DSP 556 | { 557 | /* 558 | * Released under the MIT License 559 | * 560 | * DSP Library for C# - Copyright(c) 2016 Steven C. Hageman. 561 | * 562 | * Permission is hereby granted, free of charge, to any person obtaining a copy 563 | * of this software and associated documentation files (the "Software"), to 564 | * deal in the Software without restriction, including without limitation the 565 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 566 | * sell copies of the Software, and to permit persons to whom the Software is 567 | * furnished to do so, subject to the following conditions: 568 | * 569 | * The above copyright notice and this permission notice shall be included in 570 | * all copies or substantial portions of the Software. 571 | * 572 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 573 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 574 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 575 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 576 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 577 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 578 | * IN THE SOFTWARE. 579 | */ 580 | 581 | 582 | #region Generate Signals & Noise 583 | 584 | public static class Generate 585 | { 586 | /// 587 | /// Generate linearly spaced array. Like the Octave function of the same name. 588 | /// EX: DSP.Generate.LinSpace(1, 10, 10) -> Returns array: 1, 2, 3, 4....10. 589 | /// 590 | /// Any value 591 | /// Any value > startVal 592 | /// Number of points to generate 593 | /// double[] array 594 | public static double[] LinSpace(double startVal, double stopVal, UInt32 points) 595 | { 596 | double[] result = new double[points]; 597 | double increment = (stopVal - startVal) / ((double)points - 1.0); 598 | 599 | for (UInt32 i = 0; i < points; i++) 600 | result[i] = startVal + increment * i; 601 | 602 | return result; 603 | } 604 | 605 | 606 | /// 607 | /// Generates a Sine Wave Tone using Sampling Terms. 608 | /// 609 | /// 610 | /// 611 | /// 612 | /// 613 | /// [Optional] DC Voltage offset 614 | /// [Optional] Phase of signal in degrees 615 | /// double[] array 616 | public static double[] ToneSampling(double amplitudeVrms, double frequencyHz, double samplingFrequencyHz, UInt32 points, double dcV = 0.0, double phaseDeg = 0) 617 | { 618 | double ph_r = phaseDeg * System.Math.PI / 180.0; 619 | double ampPeak = System.Math.Sqrt(2) * amplitudeVrms; 620 | 621 | double[] rval = new double[points]; 622 | for (UInt32 i = 0; i < points; i++) 623 | { 624 | double time = (double)i / samplingFrequencyHz; 625 | rval[i] = System.Math.Sqrt(2) * amplitudeVrms * System.Math.Sin(2.0 * System.Math.PI * time * frequencyHz + ph_r) + dcV; 626 | } 627 | return rval; 628 | } 629 | 630 | 631 | /// 632 | /// Generates a Sine Wave Tone using Number of Cycles Terms. 633 | /// 634 | /// 635 | /// 636 | /// 637 | /// [Optional] DC Voltage offset 638 | /// [Optional] Phase of signal in degrees 639 | /// double[] array 640 | public static double[] ToneCycles(double amplitudeVrms, double cycles, UInt32 points, double dcV = 0.0, double phaseDeg = 0) 641 | { 642 | double ph_r = phaseDeg * System.Math.PI / 180.0; 643 | double ampPeak = System.Math.Sqrt(2) * amplitudeVrms; 644 | 645 | double[] rval = new double[points]; 646 | for (UInt32 i = 0; i < points; i++) 647 | { 648 | rval[i] = ampPeak * System.Math.Sin((2.0 * System.Math.PI * (double)i / (double)points * cycles) + ph_r) + dcV; 649 | } 650 | return rval; 651 | } 652 | 653 | 654 | /// 655 | /// Generates a normal distribution noise signal of the specified power spectral density (Vrms / rt-Hz). 656 | /// 657 | /// 658 | /// 659 | /// 660 | /// double[] array 661 | public static double[] NoisePsd(double amplitudePsd, double samplingFrequencyHz, UInt32 points) 662 | { 663 | // Calculate what the noise amplitude needs to be in Vrms/rt_Hz 664 | double arms = amplitudePsd * System.Math.Sqrt(samplingFrequencyHz / 2.0); 665 | 666 | // Make an n length noise vector 667 | double[] rval = NoiseRms(arms, points); 668 | 669 | return rval; 670 | } 671 | 672 | 673 | 674 | /// 675 | /// Generates a normal distribution noise signal of the specified Volts RMS. 676 | /// 677 | /// 678 | /// 679 | /// 680 | /// double[] array 681 | public static double[] NoiseRms(double amplitudeVrms, UInt32 points, double dcV = 0.0) 682 | { 683 | double[] rval = new double[points]; 684 | 685 | // Make an n length noise vector 686 | rval = Noise(points, amplitudeVrms); 687 | 688 | rval = DSPLib.DSP.Math.Add(rval, dcV); 689 | 690 | return rval; 691 | } 692 | 693 | #region Private - Random Number Generator Core 694 | 695 | //=====[ Gaussian Noise ]===== 696 | 697 | private static Random mRandom = new Random(); // Class level variable 698 | 699 | private static double[] Noise(UInt32 size, double scaling_vrms) 700 | { 701 | 702 | // Based on - Polar method (Marsaglia 1962) 703 | 704 | // Scaling used, 705 | // * For DFT Size => "Math.Sqrt(size)" 706 | // * The Sqrt(2) is a scaling factor to get the 707 | // output spectral power to be what the desired "scaling_vrms" 708 | // was as requested. The scaling will produce a "scaling_vrms" 709 | // value that is correct for Vrms/Rt(Hz) in the frequency domain 710 | // of a "1/N" scaled DFT or FFT. 711 | // Most DFT / FFT's are 1/N scaled - check your documentation to be sure... 712 | 713 | double output_scale = scaling_vrms; 714 | 715 | double[] data = new double[size]; 716 | double sum = 0; 717 | 718 | for (UInt32 n = 0; n < size; n++) 719 | { 720 | double s; 721 | double v1; 722 | do 723 | { 724 | v1 = 2.0 * mRandom.NextDouble() - 1.0; 725 | double v2 = 2.0 * mRandom.NextDouble() - 1.0; 726 | 727 | s = v1 * v1 + v2 * v2; 728 | } while (s >= 1.0); 729 | 730 | if (s == 0.0) 731 | data[n] = 0.0; 732 | else 733 | data[n] = (v1 * System.Math.Sqrt(-2.0 * System.Math.Log(s) / s)) * output_scale; 734 | 735 | sum += data[n]; 736 | } 737 | 738 | // Remove the average value 739 | double average = sum / size; 740 | for (UInt32 n = 0; n < size; n++) 741 | { 742 | data[n] -= average; 743 | } 744 | 745 | // Return the Gaussian noise 746 | return data; 747 | } 748 | 749 | #endregion 750 | } 751 | 752 | #endregion 753 | 754 | 755 | #region Windows Functions & Scaling Functions 756 | 757 | /** 758 | * 759 | * Many of the windows functions are based on the article, 760 | * 761 | * Spectrum and spectral density estimation by the Discrete Fourier 762 | * transform (DFT), including a comprehensive list of window 763 | * functions and some new flat-top windows. 764 | * 765 | * G. Heinzel, A. Rudiger and R. Schilling, 766 | * Max-Planck-Institut fur Gravitationsphysik 767 | * 768 | * February 15, 2002 769 | * 770 | **/ 771 | 772 | public static class Window 773 | { 774 | /// 775 | /// ENUM Types for included Windows. 776 | /// 777 | public enum Type 778 | { 779 | None, 780 | Rectangular, 781 | Welch, 782 | Bartlett, 783 | Hanning, 784 | Hann, 785 | Hamming, 786 | Nutall3, 787 | Nutall4, 788 | Nutall3A, 789 | Nutall3B, 790 | Nutall4A, 791 | BH92, 792 | Nutall4B, 793 | 794 | SFT3F, 795 | SFT3M, 796 | FTNI, 797 | SFT4F, 798 | SFT5F, 799 | SFT4M, 800 | FTHP, 801 | HFT70, 802 | FTSRS, 803 | SFT5M, 804 | HFT90D, 805 | HFT95, 806 | HFT116D, 807 | HFT144D, 808 | HFT169D, 809 | HFT196D, 810 | HFT223D, 811 | HFT248D 812 | } 813 | 814 | #region Window Scale Factor 815 | 816 | public static class ScaleFactor 817 | { 818 | /// 819 | /// Calculate Signal scale factor from window coefficient array. 820 | /// Designed to be applied to the "Magnitude" result. 821 | /// 822 | /// 823 | /// double scaleFactor 824 | public static double Signal(double[] windowCoefficients) 825 | { 826 | double s1 = 0; 827 | foreach (double coeff in windowCoefficients) 828 | { 829 | s1 += coeff; 830 | } 831 | 832 | s1 = s1 / windowCoefficients.Length; 833 | 834 | return 1.0 / s1; 835 | } 836 | 837 | 838 | /// 839 | /// Calculate Noise scale factor from window coefficient array. 840 | /// Takes into account the bin width in Hz for the final result also. 841 | /// Designed to be applied to the "Magnitude" result. 842 | /// 843 | /// 844 | /// 845 | /// double scaleFactor 846 | public static double Noise(double[] windowCoefficients, double samplingFrequencyHz) 847 | { 848 | double s2 = 0; 849 | foreach (double coeff in windowCoefficients) 850 | { 851 | s2 = s2 + (coeff * coeff); 852 | } 853 | 854 | double n = windowCoefficients.Length; 855 | double fbin = samplingFrequencyHz / n; 856 | 857 | double sf = System.Math.Sqrt(1.0 / ((s2 / n) * fbin)); 858 | 859 | return sf; 860 | } 861 | 862 | 863 | /// 864 | /// Calculate Normalized, Equivalent Noise BandWidth from window coefficient array. 865 | /// 866 | /// 867 | /// double NENBW 868 | public static double NENBW(double[] windowCoefficients) 869 | { 870 | double s1 = 0; 871 | double s2 = 0; 872 | foreach (double coeff in windowCoefficients) 873 | { 874 | s1 = s1 + coeff; 875 | s2 = s2 + (coeff * coeff); 876 | } 877 | 878 | double n = windowCoefficients.Length; 879 | s1 = s1 / n; 880 | 881 | double nenbw = (s2 / (s1 * s1)) / n; 882 | 883 | return nenbw; 884 | } 885 | } 886 | #endregion 887 | 888 | #region Window Coefficient Calculations 889 | 890 | /// 891 | /// Calculates a set of Windows coefficients for a given number of points and a window type to use. 892 | /// 893 | /// 894 | /// 895 | /// double[] array of the calculated window coefficients 896 | public static double[] Coefficients(Type windowName, UInt32 points) 897 | { 898 | double[] winCoeffs = new double[points]; 899 | double N = points; 900 | 901 | switch (windowName) 902 | { 903 | case Window.Type.None: 904 | case Window.Type.Rectangular: 905 | //wc = ones(N,1); 906 | for (UInt32 i = 0; i < points; i++) 907 | winCoeffs[i] = 1.0; 908 | 909 | break; 910 | 911 | case Window.Type.Bartlett: 912 | //n = (0:N-1)'; 913 | //wc = 2/N*(N/2-abs(n-(N-1)/2)); 914 | for (UInt32 i = 0; i < points; i++) 915 | winCoeffs[i] = 2.0 / N * (N / 2.0 - System.Math.Abs(i - (N - 1.0) / 2.0)); 916 | 917 | break; 918 | 919 | case Window.Type.Welch: 920 | //n = (0:N-1)'; 921 | //wc = 1 - ( ((2*n)/N) - 1).^2; 922 | for (UInt32 i = 0; i < points; i++) 923 | winCoeffs[i] = 1.0 - System.Math.Pow(((2.0 * i) / N) - 1.0, 2.0); 924 | break; 925 | 926 | case Window.Type.Hann: 927 | case Window.Type.Hanning: 928 | //wc = (0.5 - 0.5*cos (z)); 929 | winCoeffs = SineExpansion(points, 0.5, -0.5); 930 | break; 931 | 932 | case Window.Type.Hamming: 933 | //wc = (0.54 - 0.46*cos (z)); 934 | winCoeffs = SineExpansion(points, 0.54, -0.46); 935 | break; 936 | 937 | case Window.Type.BH92: // Also known as: Blackman-Harris 938 | //wc = (0.35875 - 0.48829*cos(z) + 0.14128*cos(2*z) - 0.01168*cos(3*z)); 939 | winCoeffs = SineExpansion(points, 0.35875, -0.48829, 0.14128, -0.01168); 940 | break; 941 | 942 | case Window.Type.Nutall3: 943 | //c0 = 0.375; c1 = -0.5; c2 = 0.125; 944 | //wc = c0 + c1*cos(z) + c2*cos(2*z); 945 | winCoeffs = SineExpansion(points, 0.375, -0.5, 0.125); 946 | break; 947 | 948 | case Window.Type.Nutall3A: 949 | //c0 = 0.40897; c1 = -0.5; c2 = 0.09103; 950 | //wc = c0 + c1*cos(z) + c2*cos(2*z); 951 | winCoeffs = SineExpansion(points, 0.40897, -0.5, 0.09103); 952 | break; 953 | 954 | case Window.Type.Nutall3B: 955 | //c0 = 0.4243801; c1 = -0.4973406; c2 = 0.0782793; 956 | //wc = c0 + c1*cos(z) + c2*cos(2*z); 957 | winCoeffs = SineExpansion(points, 0.4243801, -0.4973406, 0.0782793); 958 | break; 959 | 960 | case Window.Type.Nutall4: 961 | //c0 = 0.3125; c1 = -0.46875; c2 = 0.1875; c3 = -0.03125; 962 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z); 963 | winCoeffs = SineExpansion(points, 0.3125, -0.46875, 0.1875, -0.03125); 964 | break; 965 | 966 | case Window.Type.Nutall4A: 967 | //c0 = 0.338946; c1 = -0.481973; c2 = 0.161054; c3 = -0.018027; 968 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z); 969 | winCoeffs = SineExpansion(points, 0.338946, -0.481973, 0.161054, -0.018027); 970 | break; 971 | 972 | case Window.Type.Nutall4B: 973 | //c0 = 0.355768; c1 = -0.487396; c2 = 0.144232; c3 = -0.012604; 974 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z); 975 | winCoeffs = SineExpansion(points, 0.355768, -0.487396, 0.144232, -0.012604); 976 | break; 977 | 978 | case Window.Type.SFT3F: 979 | //c0 = 0.26526; c1 = -0.5; c2 = 0.23474; 980 | //wc = c0 + c1*cos(z) + c2*cos(2*z); 981 | winCoeffs = SineExpansion(points, 0.26526, -0.5, 0.23474); 982 | break; 983 | 984 | case Window.Type.SFT4F: 985 | //c0 = 0.21706; c1 = -0.42103; c2 = 0.28294; c3 = -0.07897; 986 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z); 987 | winCoeffs = SineExpansion(points, 0.21706, -0.42103, 0.28294, -0.07897); 988 | break; 989 | 990 | case Window.Type.SFT5F: 991 | //c0 = 0.1881; c1 = -0.36923; c2 = 0.28702; c3 = -0.13077; c4 = 0.02488; 992 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z) + c4*cos(4*z); 993 | winCoeffs = SineExpansion(points, 0.1881, -0.36923, 0.28702, -0.13077, 0.02488); 994 | break; 995 | 996 | case Window.Type.SFT3M: 997 | //c0 = 0.28235; c1 = -0.52105; c2 = 0.19659; 998 | //wc = c0 + c1*cos(z) + c2*cos(2*z); 999 | winCoeffs = SineExpansion(points, 0.28235, -0.52105, 0.19659); 1000 | break; 1001 | 1002 | case Window.Type.SFT4M: 1003 | //c0 = 0.241906; c1 = -0.460841; c2 = 0.255381; c3 = -0.041872; 1004 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z); 1005 | winCoeffs = SineExpansion(points, 0.241906, -0.460841, 0.255381, -0.041872); 1006 | break; 1007 | 1008 | case Window.Type.SFT5M: 1009 | //c0 = 0.209671; c1 = -0.407331; c2 = 0.281225; c3 = -0.092669; c4 = 0.0091036; 1010 | //wc = c0 + c1*cos(z) + c2*cos(2*z) + c3*cos(3*z) + c4*cos(4*z); 1011 | winCoeffs = SineExpansion(points, 0.209671, -0.407331, 0.281225, -0.092669, 0.0091036); 1012 | break; 1013 | 1014 | case Window.Type.FTNI: 1015 | //wc = (0.2810639 - 0.5208972*cos(z) + 0.1980399*cos(2*z)); 1016 | winCoeffs = SineExpansion(points, 0.2810639, -0.5208972, 0.1980399); 1017 | break; 1018 | 1019 | case Window.Type.FTHP: 1020 | //wc = 1.0 - 1.912510941*cos(z) + 1.079173272*cos(2*z) - 0.1832630879*cos(3*z); 1021 | winCoeffs = SineExpansion(points, 1.0, -1.912510941, 1.079173272, -0.1832630879); 1022 | break; 1023 | 1024 | case Window.Type.HFT70: 1025 | //wc = 1 - 1.90796*cos(z) + 1.07349*cos(2*z) - 0.18199*cos(3*z); 1026 | winCoeffs = SineExpansion(points, 1, -1.90796, 1.07349, -0.18199); 1027 | break; 1028 | 1029 | case Window.Type.FTSRS: 1030 | //wc = 1.0 - 1.93*cos(z) + 1.29*cos(2*z) - 0.388*cos(3*z) + 0.028*cos(4*z); 1031 | winCoeffs = SineExpansion(points, 1.0, -1.93, 1.29, -0.388, 0.028); 1032 | break; 1033 | 1034 | case Window.Type.HFT90D: 1035 | //wc = 1 - 1.942604*cos(z) + 1.340318*cos(2*z) - 0.440811*cos(3*z) + 0.043097*cos(4*z); 1036 | winCoeffs = SineExpansion(points, 1.0, -1.942604, 1.340318, -0.440811, 0.043097); 1037 | break; 1038 | 1039 | case Window.Type.HFT95: 1040 | //wc = 1 - 1.9383379*cos(z) + 1.3045202*cos(2*z) - 0.4028270*cos(3*z) + 0.0350665*cos(4*z); 1041 | winCoeffs = SineExpansion(points, 1, -1.9383379, 1.3045202, -0.4028270, 0.0350665); 1042 | break; 1043 | 1044 | case Window.Type.HFT116D: 1045 | //wc = 1 - 1.9575375*cos(z) + 1.4780705*cos(2*z) - 0.6367431*cos(3*z) + 0.1228389*cos(4*z) - 0.0066288*cos(5*z); 1046 | winCoeffs = SineExpansion(points, 1.0, -1.9575375, 1.4780705, -0.6367431, 0.1228389, -0.0066288); 1047 | break; 1048 | 1049 | case Window.Type.HFT144D: 1050 | //wc = 1 - 1.96760033*cos(z) + 1.57983607*cos(2*z) - 0.81123644*cos(3*z) + 0.22583558*cos(4*z) - 0.02773848*cos(5*z) + 0.00090360*cos(6*z); 1051 | winCoeffs = SineExpansion(points, 1.0, -1.96760033, 1.57983607, -0.81123644, 0.22583558, -0.02773848, 0.00090360); 1052 | break; 1053 | 1054 | case Window.Type.HFT169D: 1055 | //wc = 1 - 1.97441842*cos(z) + 1.65409888*cos(2*z) - 0.95788186*cos(3*z) + 0.33673420*cos(4*z) - 0.06364621*cos(5*z) + 0.00521942*cos(6*z) - 0.00010599*cos(7*z); 1056 | winCoeffs = SineExpansion(points, 1.0, -1.97441842, 1.65409888, -0.95788186, 0.33673420, -0.06364621, 0.00521942, -0.00010599); 1057 | break; 1058 | 1059 | case Window.Type.HFT196D: 1060 | //wc = 1 - 1.979280420*cos(z) + 1.710288951*cos(2*z) - 1.081629853*cos(3*z)+ 0.448734314*cos(4*z) - 0.112376628*cos(5*z) + 0.015122992*cos(6*z) - 0.000871252*cos(7*z) + 0.000011896*cos(8*z); 1061 | winCoeffs = SineExpansion(points, 1.0, -1.979280420, 1.710288951, -1.081629853, 0.448734314, -0.112376628, 0.015122992, -0.000871252, 0.000011896); 1062 | break; 1063 | 1064 | case Window.Type.HFT223D: 1065 | //wc = 1 - 1.98298997309*cos(z) + 1.75556083063*cos(2*z) - 1.19037717712*cos(3*z) + 0.56155440797*cos(4*z) - 0.17296769663*cos(5*z) + 0.03233247087*cos(6*z) - 0.00324954578*cos(7*z) + 0.00013801040*cos(8*z) - 0.00000132725*cos(9*z); 1066 | winCoeffs = SineExpansion(points, 1.0, -1.98298997309, 1.75556083063, -1.19037717712, 0.56155440797, -0.17296769663, 0.03233247087, -0.00324954578, 0.00013801040, -0.00000132725); 1067 | break; 1068 | 1069 | case Window.Type.HFT248D: 1070 | //wc = 1 - 1.985844164102*cos(z) + 1.791176438506*cos(2*z) - 1.282075284005*cos(3*z) + 0.667777530266*cos(4*z) - 0.240160796576*cos(5*z) + 0.056656381764*cos(6*z) - 0.008134974479*cos(7*z) + 0.000624544650*cos(8*z) - 0.000019808998*cos(9*z) + 0.000000132974*cos(10*z); 1071 | winCoeffs = SineExpansion(points, 1, -1.985844164102, 1.791176438506, -1.282075284005, 0.667777530266, -0.240160796576, 0.056656381764, -0.008134974479, 0.000624544650, -0.000019808998, 0.000000132974); 1072 | break; 1073 | 1074 | default: 1075 | //throw new NotImplementedException("Window type fell through to 'Default'."); 1076 | break; 1077 | } 1078 | 1079 | return winCoeffs; 1080 | } 1081 | 1082 | private static double[] SineExpansion(UInt32 points, double c0, double c1 = 0.0, double c2 = 0.0, double c3 = 0.0, double c4 = 0.0, double c5 = 0.0, double c6 = 0.0, double c7 = 0.0, double c8 = 0.0, double c9 = 0.0, double c10 = 0.0) 1083 | { 1084 | // z = 2 * pi * (0:N-1)' / N; // Cosine Vector 1085 | double[] z = new double[points]; 1086 | for (UInt32 i = 0; i < points; i++) 1087 | z[i] = 2.0 * System.Math.PI * i / points; 1088 | 1089 | double[] winCoeffs = new double[points]; 1090 | 1091 | for (UInt32 i = 0; i < points; i++) 1092 | { 1093 | double wc = c0; 1094 | wc += c1 * System.Math.Cos(z[i]); 1095 | wc += c2 * System.Math.Cos(2.0 * z[i]); 1096 | wc += c3 * System.Math.Cos(3.0 * z[i]); 1097 | wc += c4 * System.Math.Cos(4.0 * z[i]); 1098 | wc += c5 * System.Math.Cos(5.0 * z[i]); 1099 | wc += c6 * System.Math.Cos(6.0 * z[i]); 1100 | wc += c7 * System.Math.Cos(7.0 * z[i]); 1101 | wc += c8 * System.Math.Cos(8.0 * z[i]); 1102 | wc += c9 * System.Math.Cos(9.0 * z[i]); 1103 | wc += c10 * System.Math.Cos(10.0 * z[i]); 1104 | 1105 | winCoeffs[i] = wc; 1106 | } 1107 | 1108 | return winCoeffs; 1109 | } 1110 | 1111 | #endregion 1112 | 1113 | } 1114 | 1115 | #endregion 1116 | 1117 | 1118 | #region Convert Magnitude format to user friendly formats 1119 | 1120 | /// 1121 | /// DFT / FFT Format Conversion Functions 1122 | /// 1123 | public static class ConvertMagnitude 1124 | { 1125 | /// 1126 | /// Convert Magnitude FT Result to: Magnitude Squared Format 1127 | /// 1128 | /// 1129 | /// 1130 | public static double[] ToMagnitudeSquared(double[] magnitude) 1131 | { 1132 | UInt32 np = (UInt32)magnitude.Length; 1133 | double[] mag2 = new double[np]; 1134 | for (UInt32 i = 0; i < np; i++) 1135 | { 1136 | mag2[i] = magnitude[i] * magnitude[i]; 1137 | } 1138 | 1139 | return mag2; 1140 | } 1141 | 1142 | 1143 | /// 1144 | /// Convert Magnitude FT Result to: Magnitude dBVolts 1145 | /// 1146 | /// 1147 | /// double[] array 1148 | public static double[] ToMagnitudeDBV(double[] magnitude) 1149 | { 1150 | UInt32 np = (UInt32)magnitude.Length; 1151 | double[] magDBV = new double[np]; 1152 | for (UInt32 i = 0; i < np; i++) 1153 | { 1154 | double magVal = magnitude[i]; 1155 | if(magVal <= 0.0) 1156 | magVal = double.Epsilon; 1157 | 1158 | magDBV[i] = 20 * System.Math.Log10(magVal); 1159 | } 1160 | 1161 | return magDBV; 1162 | } 1163 | 1164 | } 1165 | 1166 | #endregion 1167 | 1168 | 1169 | #region Convert Magnitude Squared format to user friendly formats 1170 | 1171 | /// 1172 | /// DFT / FFT Format Conversion Functions 1173 | /// 1174 | public static class ConvertMagnitudeSquared 1175 | { 1176 | 1177 | /// 1178 | /// Convert Magnitude Squared FFT Result to: Magnitude Vrms 1179 | /// 1180 | /// 1181 | /// double[] array 1182 | public static double[] ToMagnitude(double[] magSquared) 1183 | { 1184 | UInt32 np = (UInt32)magSquared.Length; 1185 | double[] mag = new double[np]; 1186 | for (UInt32 i = 0; i < np; i++) 1187 | { 1188 | mag[i] = System.Math.Sqrt(magSquared[i]); 1189 | } 1190 | 1191 | return mag; 1192 | } 1193 | 1194 | /// 1195 | /// Convert Magnitude Squared FFT Result to: Magnitude dBVolts 1196 | /// 1197 | /// 1198 | /// double[] array 1199 | public static double[] ToMagnitudeDBV(double[] magSquared) 1200 | { 1201 | UInt32 np = (UInt32)magSquared.Length; 1202 | double[] magDBV = new double[np]; 1203 | for (UInt32 i = 0; i < np; i++) 1204 | { 1205 | double magSqVal = magSquared[i]; 1206 | if (magSqVal <= 0.0) 1207 | magSqVal = double.Epsilon; 1208 | 1209 | magDBV[i] = 10 * System.Math.Log10(magSqVal); 1210 | } 1211 | 1212 | return magDBV; 1213 | } 1214 | } 1215 | 1216 | #endregion 1217 | 1218 | 1219 | #region Convert Complex format to user friendly formats 1220 | 1221 | /// 1222 | /// DFT / FFT Format Conversion Functions. 1223 | /// 1224 | public static class ConvertComplex 1225 | { 1226 | /// 1227 | /// Convert Complex DFT/FFT Result to: Magnitude Squared V^2 rms 1228 | /// 1229 | /// 1230 | /// double[] MagSquared Format 1231 | public static double[] ToMagnitudeSquared(Complex[] rawFFT) 1232 | { 1233 | UInt32 np = (UInt32)rawFFT.Length; 1234 | double[] magSquared = new double[np]; 1235 | for (UInt32 i = 0; i < np; i++) 1236 | { 1237 | double mag = rawFFT[i].Magnitude; 1238 | magSquared[i] = mag * mag; 1239 | } 1240 | 1241 | return magSquared; 1242 | } 1243 | 1244 | 1245 | /// 1246 | /// Convert Complex DFT/FFT Result to: Magnitude Vrms 1247 | /// 1248 | /// 1249 | /// double[] Magnitude Format (Vrms) 1250 | public static double[] ToMagnitude(Complex[] rawFFT) 1251 | { 1252 | UInt32 np = (UInt32)rawFFT.Length; 1253 | double[] mag = new double[np]; 1254 | for (UInt32 i = 0; i < np; i++) 1255 | { 1256 | mag[i] = rawFFT[i].Magnitude; 1257 | } 1258 | 1259 | return mag; 1260 | } 1261 | 1262 | 1263 | /// 1264 | /// Convert Complex DFT/FFT Result to: Log Magnitude dBV 1265 | /// 1266 | /// Complex[] input array"> 1267 | /// double[] Magnitude Format (dBV) 1268 | public static double[] ToMagnitudeDBV(Complex[] rawFFT) 1269 | { 1270 | UInt32 np = (UInt32)rawFFT.Length; 1271 | double[] mag = new double[np]; 1272 | for (UInt32 i = 0; i < np; i++) 1273 | { 1274 | double magVal = rawFFT[i].Magnitude; 1275 | 1276 | if (magVal <= 0.0) 1277 | magVal = double.Epsilon; 1278 | 1279 | mag[i] = 20 * System.Math.Log10(magVal); 1280 | } 1281 | 1282 | return mag; 1283 | } 1284 | 1285 | 1286 | /// 1287 | /// Convert Complex DFT/FFT Result to: Phase in Degrees 1288 | /// 1289 | /// Complex[] input array"> 1290 | /// double[] Phase (Degrees) 1291 | public static double[] ToPhaseDegrees(Complex[] rawFFT) 1292 | { 1293 | double sf = 180.0 / System.Math.PI; // Degrees per Radian scale factor 1294 | 1295 | UInt32 np = (UInt32)rawFFT.Length; 1296 | double[] phase = new double[np]; 1297 | for (UInt32 i = 0; i < np; i++) 1298 | { 1299 | phase[i] = rawFFT[i].Phase * sf; 1300 | } 1301 | 1302 | return phase; 1303 | } 1304 | 1305 | 1306 | /// 1307 | /// Convert Complex DFT/FFT Result to: Phase in Radians 1308 | /// 1309 | /// Complex[] input array"> 1310 | /// double[] Phase (Degrees) 1311 | public static double[] ToPhaseRadians(Complex[] rawFFT) 1312 | { 1313 | UInt32 np = (UInt32)rawFFT.Length; 1314 | double[] phase = new double[np]; 1315 | for (UInt32 i = 0; i < np; i++) 1316 | { 1317 | phase[i] = rawFFT[i].Phase; 1318 | } 1319 | 1320 | return phase; 1321 | } 1322 | } 1323 | #endregion 1324 | 1325 | 1326 | #region Analyze Spectrum Data 1327 | 1328 | /// 1329 | /// DFT / FFT Output Analysis Functions 1330 | /// 1331 | public static class Analyze 1332 | { 1333 | /// 1334 | /// Find the RMS value of a[]. 1335 | /// 1336 | /// = of N data points, 0 based. 1337 | /// = Bin to start the counting at (0 based)."> 1338 | /// = Bin FROM END to stop counting at (Max = N - 1)."> 1339 | /// RMS value of input array between start and stop bins. 1340 | public static double FindRms(double[] a, UInt32 startBin = 10, UInt32 stopBin = 10) 1341 | { 1342 | double sum2 = 0.0; 1343 | UInt32 actualSumCount = 0; 1344 | UInt32 n = (UInt32)a.Length; 1345 | for (UInt32 i = 0; i < n; i++) 1346 | { 1347 | if (i <= startBin - 1) 1348 | continue; 1349 | if (i > (n - 1) - (stopBin)) 1350 | continue; 1351 | 1352 | sum2 += a[i] * a[i]; 1353 | actualSumCount++; 1354 | } 1355 | 1356 | double avg2 = sum2 / actualSumCount; 1357 | double rms = System.Math.Sqrt(avg2); 1358 | 1359 | return rms; 1360 | } 1361 | 1362 | /// 1363 | /// Finds the mean of the input array. 1364 | /// 1365 | /// = of N data points, 0 based. 1366 | /// = Bin to start the counting at (0 based)."> 1367 | /// = Bin FROM END to stop counting at (Max = N - 1)."> 1368 | /// Mean value of input array between start and stop bins. 1369 | public static double FindMean(double[] inData, UInt32 startBin = 10, UInt32 stopBin = 10) 1370 | { 1371 | double sum = 0; 1372 | double n = inData.Length; 1373 | UInt32 actualSumCount = 0; 1374 | 1375 | for (UInt32 i = 0; i < n; i++) 1376 | { 1377 | if (i <= startBin - 1) 1378 | continue; 1379 | if (i > (n - 1) - (stopBin)) 1380 | continue; 1381 | 1382 | sum = sum + inData[i]; 1383 | actualSumCount++; 1384 | } 1385 | return sum / actualSumCount; 1386 | } 1387 | 1388 | 1389 | /// 1390 | /// Finds the maximum value in an array. 1391 | /// 1392 | /// 1393 | /// Maximum value of input array 1394 | public static double FindMaxAmplitude(double[] inData) 1395 | { 1396 | double n = inData.Length; 1397 | double maxVal = -1e300; 1398 | 1399 | for (UInt32 i = 0; i < n; i++) 1400 | { 1401 | if (inData[i] > maxVal) 1402 | { 1403 | maxVal = inData[i]; 1404 | } 1405 | } 1406 | 1407 | return maxVal; 1408 | } 1409 | 1410 | 1411 | /// 1412 | /// Finds the position in the inData array where the maximum value happens. 1413 | /// 1414 | /// 1415 | /// Position of maximum value in input array 1416 | public static UInt32 FindMaxPosition(double[] inData) 1417 | { 1418 | double n = inData.Length; 1419 | double maxVal = -1e300; 1420 | UInt32 maxIndex = 0; 1421 | 1422 | for (UInt32 i = 0; i < n; i++) 1423 | { 1424 | if (inData[i] > maxVal) 1425 | { 1426 | maxIndex = i; 1427 | maxVal = inData[i]; 1428 | } 1429 | } 1430 | 1431 | return maxIndex; 1432 | } 1433 | 1434 | /// 1435 | /// Finds the maximum frequency from the given inData and fSpan arrays. 1436 | /// 1437 | /// 1438 | /// 1439 | /// Maximum frequency from input arrays 1440 | public static double FindMaxFrequency(double[] inData, double[] fSpan) 1441 | { 1442 | double n = inData.Length; 1443 | double maxVal = -1e300; 1444 | UInt32 maxIndex = 0; 1445 | 1446 | for (UInt32 i = 0; i < n; i++) 1447 | { 1448 | if (inData[i] > maxVal) 1449 | { 1450 | maxIndex = i; 1451 | maxVal = inData[i]; 1452 | } 1453 | } 1454 | 1455 | return fSpan[maxIndex]; 1456 | } 1457 | 1458 | 1459 | /// 1460 | /// Unwraps the phase so that it is continuous, without jumps. 1461 | /// 1462 | /// Array of Phase Data from FT in Degrees 1463 | /// Continuous Phase data 1464 | public static double[] UnwrapPhaseDegrees(double[] inPhaseDeg) 1465 | { 1466 | UInt32 N = (UInt32)inPhaseDeg.Length; 1467 | double[] unwrappedPhase = new double[N]; 1468 | 1469 | double[] tempInData = new double[N]; 1470 | inPhaseDeg.CopyTo(tempInData, 0); 1471 | 1472 | // First point is unchanged 1473 | unwrappedPhase[0] = tempInData[0]; 1474 | 1475 | for (UInt32 i = 1; i < N; i++) 1476 | { 1477 | double delta = System.Math.Abs(tempInData[i - 1] - tempInData[i]); 1478 | if (delta >= 180) 1479 | { 1480 | // Phase jump! 1481 | if (tempInData[i - 1] < 0.0) 1482 | { 1483 | for (UInt32 j = i; j < N; j++) 1484 | tempInData[j] += -360; 1485 | } 1486 | else 1487 | { 1488 | for (UInt32 j = i; j < N; j++) 1489 | tempInData[j] += 360; 1490 | } 1491 | } 1492 | unwrappedPhase[i] = tempInData[i]; 1493 | } 1494 | return unwrappedPhase; 1495 | } 1496 | 1497 | 1498 | /// 1499 | /// Unwraps the phase so that it is continuous, without jumps. 1500 | /// 1501 | /// Array of Phase Data from FT in Radians 1502 | /// Continuous Phase data 1503 | public static double[] UnwrapPhaseRadians(double[] inPhaseRad) 1504 | { 1505 | double pi = System.Math.PI; 1506 | double twoPi = System.Math.PI * 2.0; 1507 | 1508 | UInt32 N = (UInt32)inPhaseRad.Length; 1509 | 1510 | double[] tempInData = new double[N]; 1511 | inPhaseRad.CopyTo(tempInData, 0); 1512 | 1513 | double[] unwrappedPhase = new double[N]; 1514 | 1515 | // First point is unchanged 1516 | unwrappedPhase[0] = tempInData[0]; 1517 | 1518 | for (UInt32 i = 1; i < N; i++) 1519 | { 1520 | double delta = System.Math.Abs(tempInData[i - 1] - tempInData[i]); 1521 | if (delta >= pi) 1522 | { 1523 | // Phase jump! 1524 | if (tempInData[i - 1] < 0.0) 1525 | { 1526 | for (UInt32 j = i; j < N; j++) 1527 | tempInData[j] += -twoPi; 1528 | } 1529 | else 1530 | { 1531 | for (UInt32 j = i; j < N; j++) 1532 | tempInData[j] += twoPi; 1533 | } 1534 | } 1535 | unwrappedPhase[i] = tempInData[i]; 1536 | } 1537 | return unwrappedPhase; 1538 | } 1539 | } 1540 | 1541 | #endregion 1542 | 1543 | 1544 | #region Double[] Array Math Operators 1545 | 1546 | /// 1547 | /// Double[] Array Math Operations (All Static) 1548 | /// 1549 | public static class Math 1550 | { 1551 | 1552 | /// 1553 | /// result[] = a[] * b[] 1554 | /// 1555 | public static Double[] Multiply(Double[] a, Double[] b) 1556 | { 1557 | Debug.Assert(a.Length == b.Length, "Length of arrays a[] and b[] must match."); 1558 | 1559 | double[] result = new double[a.Length]; 1560 | for (UInt32 i = 0; i < a.Length; i++) 1561 | result[i] = a[i] * b[i]; 1562 | 1563 | return result; 1564 | } 1565 | 1566 | /// 1567 | /// result[] = a[] * b 1568 | /// 1569 | public static Double[] Multiply(Double[] a, Double b) 1570 | { 1571 | double[] result = new double[a.Length]; 1572 | for (UInt32 i = 0; i < a.Length; i++) 1573 | result[i] = a[i] * b; 1574 | 1575 | return result; 1576 | } 1577 | 1578 | /// 1579 | /// result[] = a[] + b[] 1580 | /// 1581 | public static Double[] Add(Double[] a, Double[] b) 1582 | { 1583 | Debug.Assert(a.Length == b.Length, "Length of arrays a[] and b[] must match."); 1584 | 1585 | double[] result = new double[a.Length]; 1586 | for (UInt32 i = 0; i < a.Length; i++) 1587 | result[i] = a[i] + b[i]; 1588 | 1589 | return result; 1590 | } 1591 | 1592 | /// 1593 | /// result[] = a[] + b 1594 | /// 1595 | public static Double[] Add(Double[] a, Double b) 1596 | { 1597 | double[] result = new double[a.Length]; 1598 | for (UInt32 i = 0; i < a.Length; i++) 1599 | result[i] = a[i] + b; 1600 | 1601 | return result; 1602 | } 1603 | 1604 | /// 1605 | /// result[] = a[] - b[] 1606 | /// 1607 | public static Double[] Subtract(Double[] a, Double[] b) 1608 | { 1609 | Debug.Assert(a.Length == b.Length, "Length of arrays a[] and b[] must match."); 1610 | 1611 | double[] result = new double[a.Length]; 1612 | for (UInt32 i = 0; i < a.Length; i++) 1613 | result[i] = a[i] - b[i]; 1614 | 1615 | return result; 1616 | } 1617 | 1618 | /// 1619 | /// result[] = a[] - b 1620 | /// 1621 | public static Double[] Subtract(Double[] a, Double b) 1622 | { 1623 | double[] result = new double[a.Length]; 1624 | for (UInt32 i = 0; i < a.Length; i++) 1625 | result[i] = a[i] - b; 1626 | 1627 | return result; 1628 | } 1629 | 1630 | /// 1631 | /// result[] = a[] / b[] 1632 | /// 1633 | public static Double[] Divide(Double[] a, Double[] b) 1634 | { 1635 | Debug.Assert(a.Length == b.Length, "Length of arrays a[] and b[] must match."); 1636 | 1637 | double[] result = new double[a.Length]; 1638 | for (UInt32 i = 0; i < a.Length; i++) 1639 | result[i] = a[i] / b[i]; 1640 | 1641 | return result; 1642 | } 1643 | 1644 | /// 1645 | /// result[] = a[] / b 1646 | /// 1647 | public static Double[] Divide(Double[] a, Double b) 1648 | { 1649 | double[] result = new double[a.Length]; 1650 | for (UInt32 i = 0; i < a.Length; i++) 1651 | result[i] = a[i] / b; 1652 | 1653 | return result; 1654 | } 1655 | 1656 | /// 1657 | /// Square root of a[]. 1658 | /// 1659 | public static double[] Sqrt(double[] a) 1660 | { 1661 | double[] result = new double[a.Length]; 1662 | for (UInt32 i = 0; i < a.Length; i++) 1663 | result[i] = System.Math.Sqrt(a[i]); 1664 | 1665 | return result; 1666 | } 1667 | 1668 | /// 1669 | /// Squares a[]. 1670 | /// 1671 | public static double[] Square(double[] a) 1672 | { 1673 | double[] result = new double[a.Length]; 1674 | for (UInt32 i = 0; i < a.Length; i++) 1675 | result[i] = a[i] * a[i]; 1676 | 1677 | return result; 1678 | } 1679 | 1680 | /// 1681 | /// Log10 a[]. 1682 | /// 1683 | public static double[] Log10(double[] a) 1684 | { 1685 | double[] result = new double[a.Length]; 1686 | for (UInt32 i = 0; i < a.Length; i++) 1687 | { 1688 | double val = a[i]; 1689 | if (val <= 0.0) 1690 | val = double.Epsilon; 1691 | 1692 | result[i] = System.Math.Log10(val); 1693 | } 1694 | 1695 | return result; 1696 | } 1697 | 1698 | /// 1699 | /// Removes mean value from a[]. 1700 | /// 1701 | public static double[] RemoveMean(double[] a) 1702 | { 1703 | double sum = 0.0; 1704 | for (UInt32 i = 0; i < a.Length; i++) 1705 | sum += a[i]; 1706 | 1707 | double mean = sum / a.Length; 1708 | 1709 | return (DSP.Math.Subtract(a, mean)); 1710 | } 1711 | 1712 | } 1713 | 1714 | #endregion 1715 | 1716 | } 1717 | #endregion 1718 | 1719 | } 1720 | -------------------------------------------------------------------------------- /Assets/Lib/External/DSPLib/DSPLib.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 95048fd35b538a24fbd58426be38ab62 3 | timeCreated: 1517975641 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Lib/External/NET.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2247b819b8133bb4697e7c3bb61995cb 3 | folderAsset: yes 4 | timeCreated: 1518748189 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Lib/External/NET/Complex.cs: -------------------------------------------------------------------------------- 1 | // ==++== 2 | // 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | // 5 | // ==--== 6 | /*========================================================================= 7 | ** 8 | ** Class: Complex 9 | ** 10 | ** 11 | ** Purpose: 12 | ** This feature is intended to create Complex Number as a type 13 | ** that can be a part of the .NET framework (base class libraries). 14 | ** A complex number z is a number of the form z = x + yi, where x and y 15 | ** are real numbers, and i is the imaginary unit, with the property i2= -1. 16 | ** 17 | ** 18 | ===========================================================================*/ 19 | 20 | using System; 21 | using System.Globalization; 22 | using System.Diagnostics.CodeAnalysis; 23 | 24 | namespace System.Numerics { 25 | 26 | #if !SILVERLIGHT 27 | [Serializable] 28 | #endif // !SILVERLIGHT 29 | public struct Complex : IEquatable, IFormattable { 30 | 31 | // --------------SECTION: Private Data members ----------- // 32 | 33 | private Double m_real; 34 | private Double m_imaginary; 35 | 36 | // ---------------SECTION: Necessary Constants ----------- // 37 | 38 | private const Double LOG_10_INV = 0.43429448190325; 39 | 40 | 41 | // --------------SECTION: Public Properties -------------- // 42 | 43 | public Double Real { 44 | get { 45 | return m_real; 46 | } 47 | } 48 | 49 | public Double Imaginary { 50 | get { 51 | return m_imaginary; 52 | } 53 | } 54 | 55 | public Double Magnitude { 56 | get { 57 | return Complex.Abs(this); 58 | } 59 | } 60 | 61 | public Double Phase { 62 | get { 63 | return Math.Atan2(m_imaginary, m_real); 64 | } 65 | } 66 | 67 | // --------------SECTION: Attributes -------------- // 68 | 69 | public static readonly Complex Zero = new Complex(0.0, 0.0); 70 | public static readonly Complex One = new Complex(1.0, 0.0); 71 | public static readonly Complex ImaginaryOne = new Complex(0.0, 1.0); 72 | 73 | // --------------SECTION: Constructors and factory methods -------------- // 74 | 75 | public Complex(Double real, Double imaginary) /* Constructor to create a complex number with rectangular co-ordinates */ 76 | { 77 | this.m_real = real; 78 | this.m_imaginary = imaginary; 79 | } 80 | 81 | public static Complex FromPolarCoordinates(Double magnitude, Double phase) /* Factory method to take polar inputs and create a Complex object */ 82 | { 83 | return new Complex((magnitude * Math.Cos(phase)), (magnitude * Math.Sin(phase))); 84 | } 85 | 86 | public static Complex Negate(Complex value) { 87 | return -value; 88 | } 89 | 90 | public static Complex Add(Complex left, Complex right) { 91 | return left + right; 92 | } 93 | 94 | public static Complex Subtract(Complex left, Complex right) { 95 | return left - right; 96 | } 97 | 98 | public static Complex Multiply(Complex left, Complex right) { 99 | return left * right; 100 | } 101 | 102 | public static Complex Divide(Complex dividend, Complex divisor) { 103 | return dividend / divisor; 104 | } 105 | 106 | // --------------SECTION: Arithmetic Operator(unary) Overloading -------------- // 107 | public static Complex operator -(Complex value) /* Unary negation of a complex number */ 108 | { 109 | 110 | return (new Complex((-value.m_real), (-value.m_imaginary))); 111 | } 112 | 113 | // --------------SECTION: Arithmetic Operator(binary) Overloading -------------- // 114 | public static Complex operator +(Complex left, Complex right) { 115 | return (new Complex((left.m_real + right.m_real), (left.m_imaginary + right.m_imaginary))); 116 | 117 | } 118 | 119 | public static Complex operator -(Complex left, Complex right) { 120 | return (new Complex((left.m_real - right.m_real), (left.m_imaginary - right.m_imaginary))); 121 | } 122 | 123 | public static Complex operator *(Complex left, Complex right) { 124 | // Multiplication: (a + bi)(c + di) = (ac -bd) + (bc + ad)i 125 | Double result_Realpart = (left.m_real * right.m_real) - (left.m_imaginary * right.m_imaginary); 126 | Double result_Imaginarypart = (left.m_imaginary * right.m_real) + (left.m_real * right.m_imaginary); 127 | return (new Complex(result_Realpart, result_Imaginarypart)); 128 | } 129 | 130 | public static Complex operator /(Complex left, Complex right) { 131 | // Division : Smith's formula. 132 | double a = left.m_real; 133 | double b = left.m_imaginary; 134 | double c = right.m_real; 135 | double d = right.m_imaginary; 136 | 137 | if (Math.Abs(d) < Math.Abs(c)) { 138 | double doc = d / c; 139 | return new Complex((a + b * doc) / (c + d * doc), (b - a * doc) / (c + d * doc)); 140 | } else { 141 | double cod = c / d; 142 | return new Complex((b + a * cod) / (d + c * cod), (-a + b * cod) / (d + c * cod)); 143 | } 144 | } 145 | 146 | 147 | // --------------SECTION: Other arithmetic operations -------------- // 148 | 149 | public static Double Abs(Complex value) { 150 | 151 | if(Double.IsInfinity(value.m_real) || Double.IsInfinity(value.m_imaginary)) { 152 | return double.PositiveInfinity; 153 | } 154 | 155 | // |value| == sqrt(a^2 + b^2) 156 | // sqrt(a^2 + b^2) == a/a * sqrt(a^2 + b^2) = a * sqrt(a^2/a^2 + b^2/a^2) 157 | // Using the above we can factor out the square of the larger component to dodge overflow. 158 | 159 | 160 | double c = Math.Abs(value.m_real); 161 | double d = Math.Abs(value.m_imaginary); 162 | 163 | if (c > d) { 164 | double r = d / c; 165 | return c * Math.Sqrt(1.0 + r * r); 166 | } else if (d == 0.0) { 167 | return c; // c is either 0.0 or NaN 168 | } else { 169 | double r = c / d; 170 | return d * Math.Sqrt(1.0 + r * r); 171 | } 172 | } 173 | public static Complex Conjugate(Complex value) { 174 | // Conjugate of a Complex number: the conjugate of x+i*y is x-i*y 175 | 176 | return (new Complex(value.m_real, (-value.m_imaginary))); 177 | 178 | } 179 | public static Complex Reciprocal(Complex value) { 180 | // Reciprocal of a Complex number : the reciprocal of x+i*y is 1/(x+i*y) 181 | if ((value.m_real == 0) && (value.m_imaginary == 0)) { 182 | return Complex.Zero; 183 | } 184 | 185 | return Complex.One / value; 186 | } 187 | 188 | // --------------SECTION: Comparison Operator(binary) Overloading -------------- // 189 | 190 | public static bool operator ==(Complex left, Complex right) { 191 | return ((left.m_real == right.m_real) && (left.m_imaginary == right.m_imaginary)); 192 | 193 | 194 | } 195 | public static bool operator !=(Complex left, Complex right) { 196 | return ((left.m_real != right.m_real) || (left.m_imaginary != right.m_imaginary)); 197 | 198 | } 199 | 200 | // --------------SECTION: Comparison operations (methods implementing IEquatable,IComparable) -------------- // 201 | 202 | public override bool Equals(object obj) { 203 | if (!(obj is Complex)) return false; 204 | return this == ((Complex)obj); 205 | } 206 | public bool Equals(Complex value) { 207 | return ((this.m_real.Equals(value.m_real)) && (this.m_imaginary.Equals(value.m_imaginary))); 208 | 209 | } 210 | 211 | // --------------SECTION: Type-casting basic numeric data-types to ComplexNumber -------------- // 212 | 213 | public static implicit operator Complex(Int16 value) { 214 | return (new Complex(value, 0.0)); 215 | } 216 | public static implicit operator Complex(Int32 value) { 217 | return (new Complex(value, 0.0)); 218 | } 219 | public static implicit operator Complex(Int64 value) { 220 | return (new Complex(value, 0.0)); 221 | } 222 | [CLSCompliant(false)] 223 | public static implicit operator Complex(UInt16 value) { 224 | return (new Complex(value, 0.0)); 225 | } 226 | [CLSCompliant(false)] 227 | public static implicit operator Complex(UInt32 value) { 228 | return (new Complex(value, 0.0)); 229 | } 230 | [CLSCompliant(false)] 231 | public static implicit operator Complex(UInt64 value) { 232 | return (new Complex(value, 0.0)); 233 | } 234 | [CLSCompliant(false)] 235 | public static implicit operator Complex(SByte value) { 236 | return (new Complex(value, 0.0)); 237 | } 238 | public static implicit operator Complex(Byte value) { 239 | return (new Complex(value, 0.0)); 240 | } 241 | public static implicit operator Complex(Single value) { 242 | return (new Complex(value, 0.0)); 243 | } 244 | public static implicit operator Complex(Double value) { 245 | return (new Complex(value, 0.0)); 246 | } 247 | public static explicit operator Complex(Decimal value) { 248 | return (new Complex((Double)value, 0.0)); 249 | } 250 | 251 | 252 | // --------------SECTION: Formattig/Parsing options -------------- // 253 | 254 | public override String ToString() { 255 | return (String.Format(CultureInfo.CurrentCulture, "({0}, {1})", this.m_real, this.m_imaginary)); 256 | } 257 | 258 | public String ToString(String format) { 259 | return (String.Format(CultureInfo.CurrentCulture, "({0}, {1})", this.m_real.ToString(format, CultureInfo.CurrentCulture), this.m_imaginary.ToString(format, CultureInfo.CurrentCulture))); 260 | } 261 | 262 | public String ToString(IFormatProvider provider) { 263 | return (String.Format(provider, "({0}, {1})", this.m_real, this.m_imaginary)); 264 | } 265 | 266 | public String ToString(String format, IFormatProvider provider) { 267 | return (String.Format(provider, "({0}, {1})", this.m_real.ToString(format, provider), this.m_imaginary.ToString(format, provider))); 268 | } 269 | 270 | 271 | public override Int32 GetHashCode() { 272 | Int32 n1 = 99999997; 273 | Int32 hash_real = this.m_real.GetHashCode() % n1; 274 | Int32 hash_imaginary = this.m_imaginary.GetHashCode(); 275 | Int32 final_hashcode = hash_real ^ hash_imaginary; 276 | return (final_hashcode); 277 | } 278 | 279 | 280 | 281 | // --------------SECTION: Trigonometric operations (methods implementing ITrigonometric) -------------- // 282 | 283 | public static Complex Sin(Complex value) { 284 | double a = value.m_real; 285 | double b = value.m_imaginary; 286 | return new Complex(Math.Sin(a) * Math.Cosh(b), Math.Cos(a) * Math.Sinh(b)); 287 | } 288 | 289 | [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sinh", Justification = "Microsoft: Existing Name")] 290 | public static Complex Sinh(Complex value) /* Hyperbolic sin */ 291 | { 292 | double a = value.m_real; 293 | double b = value.m_imaginary; 294 | return new Complex(Math.Sinh(a) * Math.Cos(b), Math.Cosh(a) * Math.Sin(b)); 295 | 296 | } 297 | public static Complex Asin(Complex value) /* Arcsin */ 298 | { 299 | return (-ImaginaryOne) * Log(ImaginaryOne * value + Sqrt(One - value * value)); 300 | } 301 | 302 | public static Complex Cos(Complex value) { 303 | double a = value.m_real; 304 | double b = value.m_imaginary; 305 | return new Complex(Math.Cos(a) * Math.Cosh(b), - (Math.Sin(a) * Math.Sinh(b))); 306 | } 307 | 308 | [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cosh", Justification = "Microsoft: Existing Name")] 309 | public static Complex Cosh(Complex value) /* Hyperbolic cos */ 310 | { 311 | double a = value.m_real; 312 | double b = value.m_imaginary; 313 | return new Complex(Math.Cosh(a) * Math.Cos(b), Math.Sinh(a) * Math.Sin(b)); 314 | } 315 | public static Complex Acos(Complex value) /* Arccos */ 316 | { 317 | return (-ImaginaryOne) * Log(value + ImaginaryOne*Sqrt(One - (value * value))); 318 | 319 | } 320 | public static Complex Tan(Complex value) { 321 | return (Sin(value) / Cos(value)); 322 | } 323 | 324 | [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Tanh", Justification = "Microsoft: Existing Name")] 325 | public static Complex Tanh(Complex value) /* Hyperbolic tan */ 326 | { 327 | return (Sinh(value) / Cosh(value)); 328 | } 329 | public static Complex Atan(Complex value) /* Arctan */ 330 | { 331 | Complex Two = new Complex(2.0, 0.0); 332 | return (ImaginaryOne / Two) * (Log(One - ImaginaryOne * value) - Log(One + ImaginaryOne * value)); 333 | } 334 | 335 | // --------------SECTION: Other numerical functions -------------- // 336 | 337 | public static Complex Log(Complex value) /* Log of the complex number value to the base of 'e' */ 338 | { 339 | return (new Complex((Math.Log(Abs(value))), (Math.Atan2(value.m_imaginary, value.m_real)))); 340 | 341 | } 342 | public static Complex Log(Complex value, Double baseValue) /* Log of the complex number to a the base of a double */ 343 | { 344 | return (Log(value) / Log(baseValue)); 345 | } 346 | public static Complex Log10(Complex value) /* Log to the base of 10 of the complex number */ 347 | { 348 | 349 | Complex temp_log = Log(value); 350 | return (Scale(temp_log, (Double)LOG_10_INV)); 351 | 352 | } 353 | public static Complex Exp(Complex value) /* The complex number raised to e */ 354 | { 355 | Double temp_factor = Math.Exp(value.m_real); 356 | Double result_re = temp_factor * Math.Cos(value.m_imaginary); 357 | Double result_im = temp_factor * Math.Sin(value.m_imaginary); 358 | return (new Complex(result_re, result_im)); 359 | } 360 | 361 | [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sqrt", Justification = "Microsoft: Existing Name")] 362 | public static Complex Sqrt(Complex value) /* Square root ot the complex number */ 363 | { 364 | return Complex.FromPolarCoordinates(Math.Sqrt(value.Magnitude), value.Phase / 2.0); 365 | } 366 | 367 | public static Complex Pow(Complex value, Complex power) /* A complex number raised to another complex number */ 368 | { 369 | 370 | if (power == Complex.Zero) { 371 | return Complex.One; 372 | } 373 | 374 | if (value == Complex.Zero) { 375 | return Complex.Zero; 376 | } 377 | 378 | double a = value.m_real; 379 | double b = value.m_imaginary; 380 | double c = power.m_real; 381 | double d = power.m_imaginary; 382 | 383 | double rho = Complex.Abs(value); 384 | double theta = Math.Atan2(b, a); 385 | double newRho = c * theta + d * Math.Log(rho); 386 | 387 | double t = Math.Pow(rho, c) * Math.Pow(Math.E, -d * theta); 388 | 389 | return new Complex(t * Math.Cos(newRho), t * Math.Sin(newRho)); 390 | } 391 | 392 | public static Complex Pow(Complex value, Double power) // A complex number raised to a real number 393 | { 394 | return Pow(value, new Complex(power, 0)); 395 | } 396 | 397 | 398 | 399 | //--------------- SECTION: Private member functions for internal use -----------------------------------// 400 | 401 | private static Complex Scale(Complex value, Double factor) { 402 | 403 | Double result_re = factor * value.m_real; 404 | Double result_im = factor * value.m_imaginary; 405 | return (new Complex(result_re, result_im)); 406 | } 407 | 408 | } 409 | } -------------------------------------------------------------------------------- /Assets/Lib/External/NET/Complex.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b4e33b273eddfee44aa805d9d802c74a 3 | timeCreated: 1517975631 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Lib/Internal.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 77e2d0acf17e1db4fbab282f86a84b44 3 | folderAsset: yes 4 | timeCreated: 1518748087 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Lib/Internal/PlotController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | public class PlotController : MonoBehaviour { 6 | 7 | public List plotPoints; 8 | private Material highlightMaterial; 9 | public int displayWindowSize = 300; 10 | 11 | // Use this for initialization 12 | void Start () { 13 | plotPoints = new List (); 14 | 15 | float localWidth = transform.Find("Point/BasePoint").localScale.x; 16 | // -n/2...0...n/2 17 | for (int i = 0; i < displayWindowSize; i++) { 18 | //Instantiate point 19 | Transform t = (Instantiate(Resources.Load("Point"), transform) as GameObject).transform; 20 | 21 | // Set position 22 | float pointX = (displayWindowSize / 2) * -1 * localWidth + i * localWidth; 23 | t.localPosition = new Vector3(pointX, t.localPosition.y, t.localPosition.z); 24 | 25 | plotPoints.Add (t); 26 | } 27 | } 28 | 29 | public void updatePlot(List pointInfo, int curIndex = -1) { 30 | if (plotPoints.Count < displayWindowSize - 1) 31 | return; 32 | 33 | int numPlotted = 0; 34 | int windowStart = 0; 35 | int windowEnd = 0; 36 | 37 | if (curIndex > 0) { 38 | windowStart = Mathf.Max (0, curIndex - displayWindowSize / 2); 39 | windowEnd = Mathf.Min (curIndex + displayWindowSize / 2, pointInfo.Count - 1); 40 | } else { 41 | windowStart = Mathf.Max (0, pointInfo.Count - displayWindowSize - 1); 42 | windowEnd = Mathf.Min (windowStart + displayWindowSize, pointInfo.Count); 43 | } 44 | 45 | for (int i = windowStart; i < windowEnd; i++) { 46 | int plotIndex = numPlotted; 47 | numPlotted++; 48 | 49 | Transform fluxPoint = plotPoints [plotIndex].Find ("FluxPoint"); 50 | Transform threshPoint = plotPoints [plotIndex].Find ("ThreshPoint"); 51 | Transform peakPoint = plotPoints [plotIndex].Find ("PeakPoint"); 52 | 53 | 54 | if (pointInfo[i].isPeak) { 55 | setPointHeight (peakPoint, pointInfo [i].spectralFlux); 56 | setPointHeight (fluxPoint, 0f); 57 | } else { 58 | setPointHeight (fluxPoint, pointInfo [i].spectralFlux); 59 | setPointHeight (peakPoint, 0f); 60 | } 61 | setPointHeight (threshPoint, pointInfo [i].threshold); 62 | } 63 | } 64 | 65 | public void setPointHeight(Transform point, float height) { 66 | float displayMultiplier = 0.06f; 67 | 68 | point.localPosition = new Vector3(point.localPosition.x, height * displayMultiplier, point.localPosition.z); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Assets/Lib/Internal/PlotController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4c4537fa49e29be49a11e10e73efd93c 3 | timeCreated: 1518748189 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Lib/Internal/SongController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Threading; 5 | using UnityEngine; 6 | 7 | using System.Numerics; 8 | using DSPLib; 9 | 10 | 11 | public class SongController : MonoBehaviour { 12 | 13 | float[] realTimeSpectrum; 14 | SpectralFluxAnalyzer realTimeSpectralFluxAnalyzer; 15 | PlotController realTimePlotController; 16 | 17 | int numChannels; 18 | int numTotalSamples; 19 | int sampleRate; 20 | float clipLength; 21 | float[] multiChannelSamples; 22 | SpectralFluxAnalyzer preProcessedSpectralFluxAnalyzer; 23 | PlotController preProcessedPlotController; 24 | 25 | AudioSource audioSource; 26 | 27 | public bool realTimeSamples = true; 28 | public bool preProcessSamples = false; 29 | 30 | void Start() { 31 | audioSource = GetComponent (); 32 | 33 | // Process audio as it plays 34 | if (realTimeSamples) { 35 | realTimeSpectrum = new float[1024]; 36 | realTimeSpectralFluxAnalyzer = new SpectralFluxAnalyzer (); 37 | realTimePlotController = GameObject.Find ("RealtimePlot").GetComponent (); 38 | 39 | this.sampleRate = AudioSettings.outputSampleRate; 40 | } 41 | 42 | // Preprocess entire audio file upfront 43 | if (preProcessSamples) { 44 | preProcessedSpectralFluxAnalyzer = new SpectralFluxAnalyzer (); 45 | preProcessedPlotController = GameObject.Find ("PreprocessedPlot").GetComponent (); 46 | 47 | // Need all audio samples. If in stereo, samples will return with left and right channels interweaved 48 | // [L,R,L,R,L,R] 49 | multiChannelSamples = new float[audioSource.clip.samples * audioSource.clip.channels]; 50 | numChannels = audioSource.clip.channels; 51 | numTotalSamples = audioSource.clip.samples; 52 | clipLength = audioSource.clip.length; 53 | 54 | // We are not evaluating the audio as it is being played by Unity, so we need the clip's sampling rate 55 | this.sampleRate = audioSource.clip.frequency; 56 | 57 | audioSource.clip.GetData(multiChannelSamples, 0); 58 | Debug.Log ("GetData done"); 59 | 60 | Thread bgThread = new Thread (this.getFullSpectrumThreaded); 61 | 62 | Debug.Log ("Starting Background Thread"); 63 | bgThread.Start (); 64 | } 65 | } 66 | 67 | void Update() { 68 | // Real-time 69 | if (realTimeSamples) { 70 | audioSource.GetSpectrumData (realTimeSpectrum, 0, FFTWindow.BlackmanHarris); 71 | realTimeSpectralFluxAnalyzer.analyzeSpectrum (realTimeSpectrum, audioSource.time); 72 | realTimePlotController.updatePlot (realTimeSpectralFluxAnalyzer.spectralFluxSamples); 73 | } 74 | 75 | // Preprocessed 76 | if (preProcessSamples) { 77 | int indexToPlot = getIndexFromTime (audioSource.time) / 1024; 78 | preProcessedPlotController.updatePlot (preProcessedSpectralFluxAnalyzer.spectralFluxSamples, indexToPlot); 79 | } 80 | } 81 | 82 | public int getIndexFromTime(float curTime) { 83 | float lengthPerSample = this.clipLength / (float)this.numTotalSamples; 84 | 85 | return Mathf.FloorToInt (curTime / lengthPerSample); 86 | } 87 | 88 | public float getTimeFromIndex(int index) { 89 | return ((1f / (float)this.sampleRate) * index); 90 | } 91 | 92 | public void getFullSpectrumThreaded() { 93 | try { 94 | // We only need to retain the samples for combined channels over the time domain 95 | float[] preProcessedSamples = new float[this.numTotalSamples]; 96 | 97 | int numProcessed = 0; 98 | float combinedChannelAverage = 0f; 99 | for (int i = 0; i < multiChannelSamples.Length; i++) { 100 | combinedChannelAverage += multiChannelSamples [i]; 101 | 102 | // Each time we have processed all channels samples for a point in time, we will store the average of the channels combined 103 | if ((i + 1) % this.numChannels == 0) { 104 | preProcessedSamples[numProcessed] = combinedChannelAverage / this.numChannels; 105 | numProcessed++; 106 | combinedChannelAverage = 0f; 107 | } 108 | } 109 | 110 | Debug.Log ("Combine Channels done"); 111 | Debug.Log (preProcessedSamples.Length); 112 | 113 | // Once we have our audio sample data prepared, we can execute an FFT to return the spectrum data over the time domain 114 | int spectrumSampleSize = 1024; 115 | int iterations = preProcessedSamples.Length / spectrumSampleSize; 116 | 117 | FFT fft = new FFT (); 118 | fft.Initialize ((UInt32)spectrumSampleSize); 119 | 120 | Debug.Log (string.Format("Processing {0} time domain samples for FFT", iterations)); 121 | double[] sampleChunk = new double[spectrumSampleSize]; 122 | for (int i = 0; i < iterations; i++) { 123 | // Grab the current 1024 chunk of audio sample data 124 | Array.Copy (preProcessedSamples, i * spectrumSampleSize, sampleChunk, 0, spectrumSampleSize); 125 | 126 | // Apply our chosen FFT Window 127 | double[] windowCoefs = DSP.Window.Coefficients (DSP.Window.Type.Hanning, (uint)spectrumSampleSize); 128 | double[] scaledSpectrumChunk = DSP.Math.Multiply (sampleChunk, windowCoefs); 129 | double scaleFactor = DSP.Window.ScaleFactor.Signal (windowCoefs); 130 | 131 | // Perform the FFT and convert output (complex numbers) to Magnitude 132 | Complex[] fftSpectrum = fft.Execute (scaledSpectrumChunk); 133 | double[] scaledFFTSpectrum = DSPLib.DSP.ConvertComplex.ToMagnitude (fftSpectrum); 134 | scaledFFTSpectrum = DSP.Math.Multiply (scaledFFTSpectrum, scaleFactor); 135 | 136 | // These 1024 magnitude values correspond (roughly) to a single point in the audio timeline 137 | float curSongTime = getTimeFromIndex(i) * spectrumSampleSize; 138 | 139 | // Send our magnitude data off to our Spectral Flux Analyzer to be analyzed for peaks 140 | preProcessedSpectralFluxAnalyzer.analyzeSpectrum (Array.ConvertAll (scaledFFTSpectrum, x => (float)x), curSongTime); 141 | } 142 | 143 | Debug.Log ("Spectrum Analysis done"); 144 | Debug.Log ("Background Thread Completed"); 145 | 146 | } catch (Exception e) { 147 | // Catch exceptions here since the background thread won't always surface the exception to the main thread 148 | Debug.Log (e.ToString ()); 149 | } 150 | } 151 | } -------------------------------------------------------------------------------- /Assets/Lib/Internal/SongController.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ed2c36dc1422cb41a642438927225ad 3 | timeCreated: 1518748189 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Lib/Internal/SpectralFluxAnalyzer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | public class SpectralFluxInfo { 7 | public float time; 8 | public float spectralFlux; 9 | public float threshold; 10 | public float prunedSpectralFlux; 11 | public bool isPeak; 12 | } 13 | 14 | public class SpectralFluxAnalyzer { 15 | int numSamples = 1024; 16 | 17 | // Sensitivity multiplier to scale the average threshold. 18 | // In this case, if a rectified spectral flux sample is > 1.5 times the average, it is a peak 19 | float thresholdMultiplier = 1.5f; 20 | 21 | // Number of samples to average in our window 22 | int thresholdWindowSize = 50; 23 | 24 | public List spectralFluxSamples; 25 | 26 | float[] curSpectrum; 27 | float[] prevSpectrum; 28 | 29 | int indexToProcess; 30 | 31 | public SpectralFluxAnalyzer () { 32 | spectralFluxSamples = new List (); 33 | 34 | // Start processing from middle of first window and increment by 1 from there 35 | indexToProcess = thresholdWindowSize / 2; 36 | 37 | curSpectrum = new float[numSamples]; 38 | prevSpectrum = new float[numSamples]; 39 | } 40 | 41 | public void setCurSpectrum(float[] spectrum) { 42 | curSpectrum.CopyTo (prevSpectrum, 0); 43 | spectrum.CopyTo (curSpectrum, 0); 44 | } 45 | 46 | public void analyzeSpectrum(float[] spectrum, float time) { 47 | // Set spectrum 48 | setCurSpectrum(spectrum); 49 | 50 | // Get current spectral flux from spectrum 51 | SpectralFluxInfo curInfo = new SpectralFluxInfo(); 52 | curInfo.time = time; 53 | curInfo.spectralFlux = calculateRectifiedSpectralFlux (); 54 | spectralFluxSamples.Add (curInfo); 55 | 56 | // We have enough samples to detect a peak 57 | if (spectralFluxSamples.Count >= thresholdWindowSize) { 58 | // Get Flux threshold of time window surrounding index to process 59 | spectralFluxSamples[indexToProcess].threshold = getFluxThreshold (indexToProcess); 60 | 61 | // Only keep amp amount above threshold to allow peak filtering 62 | spectralFluxSamples[indexToProcess].prunedSpectralFlux = getPrunedSpectralFlux(indexToProcess); 63 | 64 | // Now that we are processed at n, n-1 has neighbors (n-2, n) to determine peak 65 | int indexToDetectPeak = indexToProcess - 1; 66 | 67 | bool curPeak = isPeak (indexToDetectPeak); 68 | 69 | if (curPeak) { 70 | spectralFluxSamples [indexToDetectPeak].isPeak = true; 71 | } 72 | indexToProcess++; 73 | } 74 | else { 75 | Debug.Log(string.Format("Not ready yet. At spectral flux sample size of {0} growing to {1}", spectralFluxSamples.Count, thresholdWindowSize)); 76 | } 77 | } 78 | 79 | float calculateRectifiedSpectralFlux() { 80 | float sum = 0f; 81 | 82 | // Aggregate positive changes in spectrum data 83 | for (int i = 0; i < numSamples; i++) { 84 | sum += Mathf.Max (0f, curSpectrum [i] - prevSpectrum [i]); 85 | } 86 | return sum; 87 | } 88 | 89 | float getFluxThreshold(int spectralFluxIndex) { 90 | // How many samples in the past and future we include in our average 91 | int windowStartIndex = Mathf.Max (0, spectralFluxIndex - thresholdWindowSize / 2); 92 | int windowEndIndex = Mathf.Min (spectralFluxSamples.Count - 1, spectralFluxIndex + thresholdWindowSize / 2); 93 | 94 | // Add up our spectral flux over the window 95 | float sum = 0f; 96 | for (int i = windowStartIndex; i < windowEndIndex; i++) { 97 | sum += spectralFluxSamples [i].spectralFlux; 98 | } 99 | 100 | // Return the average multiplied by our sensitivity multiplier 101 | float avg = sum / (windowEndIndex - windowStartIndex); 102 | return avg * thresholdMultiplier; 103 | } 104 | 105 | float getPrunedSpectralFlux(int spectralFluxIndex) { 106 | return Mathf.Max (0f, spectralFluxSamples [spectralFluxIndex].spectralFlux - spectralFluxSamples [spectralFluxIndex].threshold); 107 | } 108 | 109 | bool isPeak(int spectralFluxIndex) { 110 | if (spectralFluxSamples [spectralFluxIndex].prunedSpectralFlux > spectralFluxSamples [spectralFluxIndex + 1].prunedSpectralFlux && 111 | spectralFluxSamples [spectralFluxIndex].prunedSpectralFlux > spectralFluxSamples [spectralFluxIndex - 1].prunedSpectralFlux) { 112 | return true; 113 | } else { 114 | return false; 115 | } 116 | } 117 | 118 | void logSample(int indexToLog) { 119 | int windowStart = Mathf.Max (0, indexToLog - thresholdWindowSize / 2); 120 | int windowEnd = Mathf.Min (spectralFluxSamples.Count - 1, indexToLog + thresholdWindowSize / 2); 121 | Debug.Log (string.Format ( 122 | "Peak detected at song time {0} with pruned flux of {1} ({2} over thresh of {3}).\n" + 123 | "Thresh calculated on time window of {4}-{5} ({6} seconds) containing {7} samples.", 124 | spectralFluxSamples [indexToLog].time, 125 | spectralFluxSamples [indexToLog].prunedSpectralFlux, 126 | spectralFluxSamples [indexToLog].spectralFlux, 127 | spectralFluxSamples [indexToLog].threshold, 128 | spectralFluxSamples [windowStart].time, 129 | spectralFluxSamples [windowEnd].time, 130 | spectralFluxSamples [windowEnd].time - spectralFluxSamples [windowStart].time, 131 | windowEnd - windowStart 132 | )); 133 | } 134 | } -------------------------------------------------------------------------------- /Assets/Lib/Internal/SpectralFluxAnalyzer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 30d6286c8f0bce04db4a13fbb5f216b5 3 | timeCreated: 1518748189 4 | licenseType: Free 5 | MonoImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | defaultReferences: [] 9 | executionOrder: 0 10 | icon: {instanceID: 0} 11 | userData: 12 | assetBundleName: 13 | assetBundleVariant: 14 | -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c34b2f10bab30f3469392b43ccf1dda1 3 | folderAsset: yes 4 | timeCreated: 1518748843 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/BrightBlue.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: BrightBlue 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _EMISSION 12 | m_LightmapFlags: 1 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 0, g: 0.459, b: 1, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /Assets/Materials/BrightBlue.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bca9ce34683a7f6499200a7007f39881 3 | timeCreated: 1518748843 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/BrightGreen.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: BrightGreen 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _EMISSION 12 | m_LightmapFlags: 1 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 0, g: 1, b: 0, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /Assets/Materials/BrightGreen.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7c5e91b86fddaeb41965ed926d24d075 3 | timeCreated: 1518748843 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/BrightRed.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: BrightRed 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _EMISSION 12 | m_LightmapFlags: 1 13 | m_EnableInstancingVariants: 0 14 | m_DoubleSidedGI: 0 15 | m_CustomRenderQueue: -1 16 | stringTagMap: {} 17 | disabledShaderPasses: [] 18 | m_SavedProperties: 19 | serializedVersion: 3 20 | m_TexEnvs: 21 | - _BumpMap: 22 | m_Texture: {fileID: 0} 23 | m_Scale: {x: 1, y: 1} 24 | m_Offset: {x: 0, y: 0} 25 | - _DetailAlbedoMap: 26 | m_Texture: {fileID: 0} 27 | m_Scale: {x: 1, y: 1} 28 | m_Offset: {x: 0, y: 0} 29 | - _DetailMask: 30 | m_Texture: {fileID: 0} 31 | m_Scale: {x: 1, y: 1} 32 | m_Offset: {x: 0, y: 0} 33 | - _DetailNormalMap: 34 | m_Texture: {fileID: 0} 35 | m_Scale: {x: 1, y: 1} 36 | m_Offset: {x: 0, y: 0} 37 | - _EmissionMap: 38 | m_Texture: {fileID: 0} 39 | m_Scale: {x: 1, y: 1} 40 | m_Offset: {x: 0, y: 0} 41 | - _MainTex: 42 | m_Texture: {fileID: 0} 43 | m_Scale: {x: 1, y: 1} 44 | m_Offset: {x: 0, y: 0} 45 | - _MetallicGlossMap: 46 | m_Texture: {fileID: 0} 47 | m_Scale: {x: 1, y: 1} 48 | m_Offset: {x: 0, y: 0} 49 | - _OcclusionMap: 50 | m_Texture: {fileID: 0} 51 | m_Scale: {x: 1, y: 1} 52 | m_Offset: {x: 0, y: 0} 53 | - _ParallaxMap: 54 | m_Texture: {fileID: 0} 55 | m_Scale: {x: 1, y: 1} 56 | m_Offset: {x: 0, y: 0} 57 | m_Floats: 58 | - _BumpScale: 1 59 | - _Cutoff: 0.5 60 | - _DetailNormalMapScale: 1 61 | - _DstBlend: 0 62 | - _GlossMapScale: 1 63 | - _Glossiness: 0.5 64 | - _GlossyReflections: 1 65 | - _Metallic: 0 66 | - _Mode: 0 67 | - _OcclusionStrength: 1 68 | - _Parallax: 0.02 69 | - _SmoothnessTextureChannel: 0 70 | - _SpecularHighlights: 1 71 | - _SrcBlend: 1 72 | - _UVSec: 0 73 | - _ZWrite: 1 74 | m_Colors: 75 | - _Color: {r: 1, g: 0, b: 0, a: 1} 76 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 77 | -------------------------------------------------------------------------------- /Assets/Materials/BrightRed.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2bdcde7c59d53f14ba9ee6ff94d6b719 3 | timeCreated: 1518748843 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Materials/Grey.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_PrefabParentObject: {fileID: 0} 8 | m_PrefabInternal: {fileID: 0} 9 | m_Name: Grey 10 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 11 | m_ShaderKeywords: _EMISSION 12 | m_LightmapFlags: 1 13 | m_CustomRenderQueue: -1 14 | stringTagMap: {} 15 | m_SavedProperties: 16 | serializedVersion: 2 17 | m_TexEnvs: 18 | - first: 19 | name: _BumpMap 20 | second: 21 | m_Texture: {fileID: 0} 22 | m_Scale: {x: 1, y: 1} 23 | m_Offset: {x: 0, y: 0} 24 | - first: 25 | name: _DetailAlbedoMap 26 | second: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - first: 31 | name: _DetailMask 32 | second: 33 | m_Texture: {fileID: 0} 34 | m_Scale: {x: 1, y: 1} 35 | m_Offset: {x: 0, y: 0} 36 | - first: 37 | name: _DetailNormalMap 38 | second: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - first: 43 | name: _EmissionMap 44 | second: 45 | m_Texture: {fileID: 0} 46 | m_Scale: {x: 1, y: 1} 47 | m_Offset: {x: 0, y: 0} 48 | - first: 49 | name: _MainTex 50 | second: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - first: 55 | name: _MetallicGlossMap 56 | second: 57 | m_Texture: {fileID: 0} 58 | m_Scale: {x: 1, y: 1} 59 | m_Offset: {x: 0, y: 0} 60 | - first: 61 | name: _OcclusionMap 62 | second: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | - first: 67 | name: _ParallaxMap 68 | second: 69 | m_Texture: {fileID: 0} 70 | m_Scale: {x: 1, y: 1} 71 | m_Offset: {x: 0, y: 0} 72 | m_Floats: 73 | - first: 74 | name: _BumpScale 75 | second: 1 76 | - first: 77 | name: _Cutoff 78 | second: 0.5 79 | - first: 80 | name: _DetailNormalMapScale 81 | second: 1 82 | - first: 83 | name: _DstBlend 84 | second: 0 85 | - first: 86 | name: _GlossMapScale 87 | second: 1 88 | - first: 89 | name: _Glossiness 90 | second: 0.5 91 | - first: 92 | name: _GlossyReflections 93 | second: 1 94 | - first: 95 | name: _Metallic 96 | second: 0 97 | - first: 98 | name: _Mode 99 | second: 0 100 | - first: 101 | name: _OcclusionStrength 102 | second: 1 103 | - first: 104 | name: _Parallax 105 | second: 0.02 106 | - first: 107 | name: _SmoothnessTextureChannel 108 | second: 0 109 | - first: 110 | name: _SpecularHighlights 111 | second: 1 112 | - first: 113 | name: _SrcBlend 114 | second: 1 115 | - first: 116 | name: _UVSec 117 | second: 0 118 | - first: 119 | name: _ZWrite 120 | second: 1 121 | m_Colors: 122 | - first: 123 | name: _Color 124 | second: {r: 0.52205884, g: 0.52205884, b: 0.52205884, a: 1} 125 | - first: 126 | name: _EmissionColor 127 | second: {r: 0, g: 0, b: 0, a: 1} 128 | -------------------------------------------------------------------------------- /Assets/Materials/Grey.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f373dd111dd91340a3f1cd4748b2d77 3 | timeCreated: 1518748843 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/PlotDemo.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 8 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1} 42 | --- !u!157 &3 43 | LightmapSettings: 44 | m_ObjectHideFlags: 0 45 | serializedVersion: 11 46 | m_GIWorkflowMode: 0 47 | m_GISettings: 48 | serializedVersion: 2 49 | m_BounceScale: 1 50 | m_IndirectOutputScale: 1 51 | m_AlbedoBoost: 1 52 | m_TemporalCoherenceThreshold: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 1 56 | m_LightmapEditorSettings: 57 | serializedVersion: 9 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_TextureWidth: 1024 61 | m_TextureHeight: 1024 62 | m_AO: 0 63 | m_AOMaxDistance: 1 64 | m_CompAOExponent: 1 65 | m_CompAOExponentDirect: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVRFilterTypeDirect: 0 81 | m_PVRFilterTypeIndirect: 0 82 | m_PVRFilterTypeAO: 0 83 | m_PVRFilteringMode: 1 84 | m_PVRCulling: 1 85 | m_PVRFilteringGaussRadiusDirect: 1 86 | m_PVRFilteringGaussRadiusIndirect: 5 87 | m_PVRFilteringGaussRadiusAO: 2 88 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 89 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 90 | m_PVRFilteringAtrousPositionSigmaAO: 1 91 | m_ShowResolutionOverlay: 1 92 | m_LightingDataAsset: {fileID: 0} 93 | m_UseShadowmask: 1 94 | --- !u!196 &4 95 | NavMeshSettings: 96 | serializedVersion: 2 97 | m_ObjectHideFlags: 0 98 | m_BuildSettings: 99 | serializedVersion: 2 100 | agentTypeID: 0 101 | agentRadius: 0.5 102 | agentHeight: 2 103 | agentSlope: 45 104 | agentClimb: 0.4 105 | ledgeDropHeight: 0 106 | maxJumpAcrossDistance: 0 107 | minRegionArea: 2 108 | manualCellSize: 0 109 | cellSize: 0.16666667 110 | manualTileSize: 0 111 | tileSize: 256 112 | accuratePlacement: 0 113 | debug: 114 | m_Flags: 0 115 | m_NavMeshData: {fileID: 0} 116 | --- !u!1 &132516750 117 | GameObject: 118 | m_ObjectHideFlags: 0 119 | m_PrefabParentObject: {fileID: 0} 120 | m_PrefabInternal: {fileID: 0} 121 | serializedVersion: 5 122 | m_Component: 123 | - component: {fileID: 132516752} 124 | - component: {fileID: 132516751} 125 | m_Layer: 0 126 | m_Name: Directional Light 127 | m_TagString: Untagged 128 | m_Icon: {fileID: 0} 129 | m_NavMeshLayer: 0 130 | m_StaticEditorFlags: 0 131 | m_IsActive: 1 132 | --- !u!108 &132516751 133 | Light: 134 | m_ObjectHideFlags: 0 135 | m_PrefabParentObject: {fileID: 0} 136 | m_PrefabInternal: {fileID: 0} 137 | m_GameObject: {fileID: 132516750} 138 | m_Enabled: 1 139 | serializedVersion: 8 140 | m_Type: 1 141 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 142 | m_Intensity: 1 143 | m_Range: 10 144 | m_SpotAngle: 30 145 | m_CookieSize: 10 146 | m_Shadows: 147 | m_Type: 2 148 | m_Resolution: -1 149 | m_CustomResolution: -1 150 | m_Strength: 1 151 | m_Bias: 0.05 152 | m_NormalBias: 0.4 153 | m_NearPlane: 0.2 154 | m_Cookie: {fileID: 0} 155 | m_DrawHalo: 0 156 | m_Flare: {fileID: 0} 157 | m_RenderMode: 0 158 | m_CullingMask: 159 | serializedVersion: 2 160 | m_Bits: 4294967295 161 | m_Lightmapping: 4 162 | m_AreaSize: {x: 1, y: 1} 163 | m_BounceIntensity: 1 164 | m_ColorTemperature: 6570 165 | m_UseColorTemperature: 0 166 | m_ShadowRadius: 0 167 | m_ShadowAngle: 0 168 | --- !u!4 &132516752 169 | Transform: 170 | m_ObjectHideFlags: 0 171 | m_PrefabParentObject: {fileID: 0} 172 | m_PrefabInternal: {fileID: 0} 173 | m_GameObject: {fileID: 132516750} 174 | m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} 175 | m_LocalPosition: {x: 0, y: 3, z: 0} 176 | m_LocalScale: {x: 1, y: 1, z: 1} 177 | m_Children: [] 178 | m_Father: {fileID: 0} 179 | m_RootOrder: 1 180 | m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} 181 | --- !u!1001 &152440738 182 | Prefab: 183 | m_ObjectHideFlags: 0 184 | serializedVersion: 2 185 | m_Modification: 186 | m_TransformParent: {fileID: 2142178373} 187 | m_Modifications: 188 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 189 | propertyPath: m_LocalPosition.x 190 | value: 0 191 | objectReference: {fileID: 0} 192 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 193 | propertyPath: m_LocalPosition.y 194 | value: 0 195 | objectReference: {fileID: 0} 196 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 197 | propertyPath: m_LocalPosition.z 198 | value: 0 199 | objectReference: {fileID: 0} 200 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 201 | propertyPath: m_LocalRotation.x 202 | value: -0 203 | objectReference: {fileID: 0} 204 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 205 | propertyPath: m_LocalRotation.y 206 | value: -0 207 | objectReference: {fileID: 0} 208 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 209 | propertyPath: m_LocalRotation.z 210 | value: -0 211 | objectReference: {fileID: 0} 212 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 213 | propertyPath: m_LocalRotation.w 214 | value: 1 215 | objectReference: {fileID: 0} 216 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 217 | propertyPath: m_RootOrder 218 | value: 1 219 | objectReference: {fileID: 0} 220 | m_RemovedComponents: [] 221 | m_ParentPrefab: {fileID: 100100000, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 222 | m_IsPrefabParent: 0 223 | --- !u!4 &152440739 stripped 224 | Transform: 225 | m_PrefabParentObject: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, 226 | type: 2} 227 | m_PrefabInternal: {fileID: 152440738} 228 | --- !u!1 &766576251 229 | GameObject: 230 | m_ObjectHideFlags: 0 231 | m_PrefabParentObject: {fileID: 0} 232 | m_PrefabInternal: {fileID: 0} 233 | serializedVersion: 5 234 | m_Component: 235 | - component: {fileID: 766576255} 236 | - component: {fileID: 766576254} 237 | - component: {fileID: 766576253} 238 | - component: {fileID: 766576252} 239 | m_Layer: 0 240 | m_Name: Main Camera 241 | m_TagString: MainCamera 242 | m_Icon: {fileID: 0} 243 | m_NavMeshLayer: 0 244 | m_StaticEditorFlags: 0 245 | m_IsActive: 1 246 | --- !u!81 &766576252 247 | AudioListener: 248 | m_ObjectHideFlags: 0 249 | m_PrefabParentObject: {fileID: 0} 250 | m_PrefabInternal: {fileID: 0} 251 | m_GameObject: {fileID: 766576251} 252 | m_Enabled: 1 253 | --- !u!124 &766576253 254 | Behaviour: 255 | m_ObjectHideFlags: 0 256 | m_PrefabParentObject: {fileID: 0} 257 | m_PrefabInternal: {fileID: 0} 258 | m_GameObject: {fileID: 766576251} 259 | m_Enabled: 1 260 | --- !u!20 &766576254 261 | Camera: 262 | m_ObjectHideFlags: 0 263 | m_PrefabParentObject: {fileID: 0} 264 | m_PrefabInternal: {fileID: 0} 265 | m_GameObject: {fileID: 766576251} 266 | m_Enabled: 1 267 | serializedVersion: 2 268 | m_ClearFlags: 1 269 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 270 | m_NormalizedViewPortRect: 271 | serializedVersion: 2 272 | x: 0 273 | y: 0 274 | width: 1 275 | height: 1 276 | near clip plane: 0.3 277 | far clip plane: 1000 278 | field of view: 60 279 | orthographic: 0 280 | orthographic size: 5 281 | m_Depth: -1 282 | m_CullingMask: 283 | serializedVersion: 2 284 | m_Bits: 4294967295 285 | m_RenderingPath: -1 286 | m_TargetTexture: {fileID: 0} 287 | m_TargetDisplay: 0 288 | m_TargetEye: 3 289 | m_HDR: 1 290 | m_AllowMSAA: 1 291 | m_AllowDynamicResolution: 0 292 | m_ForceIntoRT: 0 293 | m_OcclusionCulling: 1 294 | m_StereoConvergence: 10 295 | m_StereoSeparation: 0.022 296 | --- !u!4 &766576255 297 | Transform: 298 | m_ObjectHideFlags: 0 299 | m_PrefabParentObject: {fileID: 0} 300 | m_PrefabInternal: {fileID: 0} 301 | m_GameObject: {fileID: 766576251} 302 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 303 | m_LocalPosition: {x: 0, y: 0, z: 0} 304 | m_LocalScale: {x: 1, y: 1, z: 1} 305 | m_Children: [] 306 | m_Father: {fileID: 0} 307 | m_RootOrder: 0 308 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 309 | --- !u!1 &1151287535 310 | GameObject: 311 | m_ObjectHideFlags: 0 312 | m_PrefabParentObject: {fileID: 1162083648059480, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 313 | type: 2} 314 | m_PrefabInternal: {fileID: 0} 315 | serializedVersion: 5 316 | m_Component: 317 | - component: {fileID: 1151287536} 318 | - component: {fileID: 1151287539} 319 | - component: {fileID: 1151287538} 320 | - component: {fileID: 1151287537} 321 | m_Layer: 0 322 | m_Name: TimeLine 323 | m_TagString: Untagged 324 | m_Icon: {fileID: 0} 325 | m_NavMeshLayer: 0 326 | m_StaticEditorFlags: 0 327 | m_IsActive: 1 328 | --- !u!4 &1151287536 329 | Transform: 330 | m_ObjectHideFlags: 0 331 | m_PrefabParentObject: {fileID: 4754383764296070, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 332 | type: 2} 333 | m_PrefabInternal: {fileID: 0} 334 | m_GameObject: {fileID: 1151287535} 335 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 336 | m_LocalPosition: {x: 0.375, y: 0.075, z: 0.00999999} 337 | m_LocalScale: {x: 0.0025, y: 0.15, z: 0.01} 338 | m_Children: [] 339 | m_Father: {fileID: 2142178373} 340 | m_RootOrder: 0 341 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 342 | --- !u!23 &1151287537 343 | MeshRenderer: 344 | m_ObjectHideFlags: 0 345 | m_PrefabParentObject: {fileID: 23913408000214496, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 346 | type: 2} 347 | m_PrefabInternal: {fileID: 0} 348 | m_GameObject: {fileID: 1151287535} 349 | m_Enabled: 1 350 | m_CastShadows: 1 351 | m_ReceiveShadows: 1 352 | m_DynamicOccludee: 1 353 | m_MotionVectors: 1 354 | m_LightProbeUsage: 1 355 | m_ReflectionProbeUsage: 1 356 | m_Materials: 357 | - {fileID: 2100000, guid: 7c5e91b86fddaeb41965ed926d24d075, type: 2} 358 | m_StaticBatchInfo: 359 | firstSubMesh: 0 360 | subMeshCount: 0 361 | m_StaticBatchRoot: {fileID: 0} 362 | m_ProbeAnchor: {fileID: 0} 363 | m_LightProbeVolumeOverride: {fileID: 0} 364 | m_ScaleInLightmap: 1 365 | m_PreserveUVs: 1 366 | m_IgnoreNormalsForChartDetection: 0 367 | m_ImportantGI: 0 368 | m_StitchLightmapSeams: 0 369 | m_SelectedEditorRenderState: 3 370 | m_MinimumChartSize: 4 371 | m_AutoUVMaxDistance: 0.5 372 | m_AutoUVMaxAngle: 89 373 | m_LightmapParameters: {fileID: 0} 374 | m_SortingLayerID: 0 375 | m_SortingLayer: 0 376 | m_SortingOrder: 0 377 | --- !u!65 &1151287538 378 | BoxCollider: 379 | m_ObjectHideFlags: 0 380 | m_PrefabParentObject: {fileID: 65474107738210112, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 381 | type: 2} 382 | m_PrefabInternal: {fileID: 0} 383 | m_GameObject: {fileID: 1151287535} 384 | m_Material: {fileID: 0} 385 | m_IsTrigger: 0 386 | m_Enabled: 1 387 | serializedVersion: 2 388 | m_Size: {x: 1, y: 1, z: 1} 389 | m_Center: {x: 0, y: 0, z: 0} 390 | --- !u!33 &1151287539 391 | MeshFilter: 392 | m_ObjectHideFlags: 0 393 | m_PrefabParentObject: {fileID: 33727871057544708, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 394 | type: 2} 395 | m_PrefabInternal: {fileID: 0} 396 | m_GameObject: {fileID: 1151287535} 397 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 398 | --- !u!1 &1325650112 399 | GameObject: 400 | m_ObjectHideFlags: 0 401 | m_PrefabParentObject: {fileID: 0} 402 | m_PrefabInternal: {fileID: 0} 403 | serializedVersion: 5 404 | m_Component: 405 | - component: {fileID: 1325650114} 406 | - component: {fileID: 1325650113} 407 | - component: {fileID: 1325650115} 408 | m_Layer: 0 409 | m_Name: SongController 410 | m_TagString: Untagged 411 | m_Icon: {fileID: 0} 412 | m_NavMeshLayer: 0 413 | m_StaticEditorFlags: 0 414 | m_IsActive: 1 415 | --- !u!114 &1325650113 416 | MonoBehaviour: 417 | m_ObjectHideFlags: 0 418 | m_PrefabParentObject: {fileID: 0} 419 | m_PrefabInternal: {fileID: 0} 420 | m_GameObject: {fileID: 1325650112} 421 | m_Enabled: 1 422 | m_EditorHideFlags: 0 423 | m_Script: {fileID: 11500000, guid: 1ed2c36dc1422cb41a642438927225ad, type: 3} 424 | m_Name: 425 | m_EditorClassIdentifier: 426 | realTimeSamples: 1 427 | preProcessSamples: 1 428 | --- !u!4 &1325650114 429 | Transform: 430 | m_ObjectHideFlags: 0 431 | m_PrefabParentObject: {fileID: 0} 432 | m_PrefabInternal: {fileID: 0} 433 | m_GameObject: {fileID: 1325650112} 434 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 435 | m_LocalPosition: {x: 0, y: 0, z: 0} 436 | m_LocalScale: {x: 1, y: 1, z: 1} 437 | m_Children: [] 438 | m_Father: {fileID: 0} 439 | m_RootOrder: 2 440 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 441 | --- !u!82 &1325650115 442 | AudioSource: 443 | m_ObjectHideFlags: 0 444 | m_PrefabParentObject: {fileID: 0} 445 | m_PrefabInternal: {fileID: 0} 446 | m_GameObject: {fileID: 1325650112} 447 | m_Enabled: 1 448 | serializedVersion: 4 449 | OutputAudioMixerGroup: {fileID: 0} 450 | m_audioClip: {fileID: 8300000, guid: 011903a47b70002479ab7619fb564f5c, type: 3} 451 | m_PlayOnAwake: 1 452 | m_Volume: 1 453 | m_Pitch: 1 454 | Loop: 0 455 | Mute: 0 456 | Spatialize: 0 457 | SpatializePostEffects: 0 458 | Priority: 128 459 | DopplerLevel: 1 460 | MinDistance: 1 461 | MaxDistance: 500 462 | Pan2D: 0 463 | rolloffMode: 0 464 | BypassEffects: 0 465 | BypassListenerEffects: 0 466 | BypassReverbZones: 0 467 | rolloffCustomCurve: 468 | serializedVersion: 2 469 | m_Curve: 470 | - serializedVersion: 2 471 | time: 0 472 | value: 1 473 | inSlope: 0 474 | outSlope: 0 475 | tangentMode: 0 476 | - serializedVersion: 2 477 | time: 1 478 | value: 0 479 | inSlope: 0 480 | outSlope: 0 481 | tangentMode: 0 482 | m_PreInfinity: 2 483 | m_PostInfinity: 2 484 | m_RotationOrder: 4 485 | panLevelCustomCurve: 486 | serializedVersion: 2 487 | m_Curve: 488 | - serializedVersion: 2 489 | time: 0 490 | value: 0 491 | inSlope: 0 492 | outSlope: 0 493 | tangentMode: 0 494 | m_PreInfinity: 2 495 | m_PostInfinity: 2 496 | m_RotationOrder: 0 497 | spreadCustomCurve: 498 | serializedVersion: 2 499 | m_Curve: 500 | - serializedVersion: 2 501 | time: 0 502 | value: 0 503 | inSlope: 0 504 | outSlope: 0 505 | tangentMode: 0 506 | m_PreInfinity: 2 507 | m_PostInfinity: 2 508 | m_RotationOrder: 0 509 | reverbZoneMixCustomCurve: 510 | serializedVersion: 2 511 | m_Curve: 512 | - serializedVersion: 2 513 | time: 0 514 | value: 1 515 | inSlope: 0 516 | outSlope: 0 517 | tangentMode: 0 518 | m_PreInfinity: 2 519 | m_PostInfinity: 2 520 | m_RotationOrder: 0 521 | --- !u!1 &1349695228 522 | GameObject: 523 | m_ObjectHideFlags: 0 524 | m_PrefabParentObject: {fileID: 1253657439438104, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 525 | type: 2} 526 | m_PrefabInternal: {fileID: 0} 527 | serializedVersion: 5 528 | m_Component: 529 | - component: {fileID: 1349695229} 530 | - component: {fileID: 1349695232} 531 | - component: {fileID: 1349695231} 532 | - component: {fileID: 1349695230} 533 | m_Layer: 0 534 | m_Name: TimeLine 535 | m_TagString: Untagged 536 | m_Icon: {fileID: 0} 537 | m_NavMeshLayer: 0 538 | m_StaticEditorFlags: 0 539 | m_IsActive: 1 540 | --- !u!4 &1349695229 541 | Transform: 542 | m_ObjectHideFlags: 0 543 | m_PrefabParentObject: {fileID: 4374965427199374, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 544 | type: 2} 545 | m_PrefabInternal: {fileID: 0} 546 | m_GameObject: {fileID: 1349695228} 547 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 548 | m_LocalPosition: {x: 0, y: 0.075, z: 0.00999999} 549 | m_LocalScale: {x: 0.0025, y: 0.15, z: 0.01} 550 | m_Children: [] 551 | m_Father: {fileID: 2102209731} 552 | m_RootOrder: 0 553 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 554 | --- !u!23 &1349695230 555 | MeshRenderer: 556 | m_ObjectHideFlags: 0 557 | m_PrefabParentObject: {fileID: 23069593794767074, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 558 | type: 2} 559 | m_PrefabInternal: {fileID: 0} 560 | m_GameObject: {fileID: 1349695228} 561 | m_Enabled: 1 562 | m_CastShadows: 1 563 | m_ReceiveShadows: 1 564 | m_DynamicOccludee: 1 565 | m_MotionVectors: 1 566 | m_LightProbeUsage: 1 567 | m_ReflectionProbeUsage: 1 568 | m_Materials: 569 | - {fileID: 2100000, guid: 7c5e91b86fddaeb41965ed926d24d075, type: 2} 570 | m_StaticBatchInfo: 571 | firstSubMesh: 0 572 | subMeshCount: 0 573 | m_StaticBatchRoot: {fileID: 0} 574 | m_ProbeAnchor: {fileID: 0} 575 | m_LightProbeVolumeOverride: {fileID: 0} 576 | m_ScaleInLightmap: 1 577 | m_PreserveUVs: 1 578 | m_IgnoreNormalsForChartDetection: 0 579 | m_ImportantGI: 0 580 | m_StitchLightmapSeams: 0 581 | m_SelectedEditorRenderState: 3 582 | m_MinimumChartSize: 4 583 | m_AutoUVMaxDistance: 0.5 584 | m_AutoUVMaxAngle: 89 585 | m_LightmapParameters: {fileID: 0} 586 | m_SortingLayerID: 0 587 | m_SortingLayer: 0 588 | m_SortingOrder: 0 589 | --- !u!65 &1349695231 590 | BoxCollider: 591 | m_ObjectHideFlags: 0 592 | m_PrefabParentObject: {fileID: 65258962889183544, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 593 | type: 2} 594 | m_PrefabInternal: {fileID: 0} 595 | m_GameObject: {fileID: 1349695228} 596 | m_Material: {fileID: 0} 597 | m_IsTrigger: 0 598 | m_Enabled: 1 599 | serializedVersion: 2 600 | m_Size: {x: 1, y: 1, z: 1} 601 | m_Center: {x: 0, y: 0, z: 0} 602 | --- !u!33 &1349695232 603 | MeshFilter: 604 | m_ObjectHideFlags: 0 605 | m_PrefabParentObject: {fileID: 33647231908331272, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 606 | type: 2} 607 | m_PrefabInternal: {fileID: 0} 608 | m_GameObject: {fileID: 1349695228} 609 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 610 | --- !u!1001 &1500422035 611 | Prefab: 612 | m_ObjectHideFlags: 0 613 | serializedVersion: 2 614 | m_Modification: 615 | m_TransformParent: {fileID: 2102209731} 616 | m_Modifications: 617 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 618 | propertyPath: m_LocalPosition.x 619 | value: 0 620 | objectReference: {fileID: 0} 621 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 622 | propertyPath: m_LocalPosition.y 623 | value: 0 624 | objectReference: {fileID: 0} 625 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 626 | propertyPath: m_LocalPosition.z 627 | value: 0 628 | objectReference: {fileID: 0} 629 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 630 | propertyPath: m_LocalRotation.x 631 | value: -0 632 | objectReference: {fileID: 0} 633 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 634 | propertyPath: m_LocalRotation.y 635 | value: -0 636 | objectReference: {fileID: 0} 637 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 638 | propertyPath: m_LocalRotation.z 639 | value: -0 640 | objectReference: {fileID: 0} 641 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 642 | propertyPath: m_LocalRotation.w 643 | value: 1 644 | objectReference: {fileID: 0} 645 | - target: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 646 | propertyPath: m_RootOrder 647 | value: 1 648 | objectReference: {fileID: 0} 649 | m_RemovedComponents: [] 650 | m_ParentPrefab: {fileID: 100100000, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, type: 2} 651 | m_IsPrefabParent: 0 652 | --- !u!4 &1500422036 stripped 653 | Transform: 654 | m_PrefabParentObject: {fileID: 4536838457428552, guid: 8a552ee8d4e985f4eb965c1dbd8cb815, 655 | type: 2} 656 | m_PrefabInternal: {fileID: 1500422035} 657 | --- !u!1 &2102209729 658 | GameObject: 659 | m_ObjectHideFlags: 0 660 | m_PrefabParentObject: {fileID: 1858942967679866, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 661 | type: 2} 662 | m_PrefabInternal: {fileID: 0} 663 | serializedVersion: 5 664 | m_Component: 665 | - component: {fileID: 2102209731} 666 | - component: {fileID: 2102209730} 667 | m_Layer: 0 668 | m_Name: PreprocessedPlot 669 | m_TagString: Untagged 670 | m_Icon: {fileID: 0} 671 | m_NavMeshLayer: 0 672 | m_StaticEditorFlags: 0 673 | m_IsActive: 1 674 | --- !u!114 &2102209730 675 | MonoBehaviour: 676 | m_ObjectHideFlags: 0 677 | m_PrefabParentObject: {fileID: 0} 678 | m_PrefabInternal: {fileID: 0} 679 | m_GameObject: {fileID: 2102209729} 680 | m_Enabled: 1 681 | m_EditorHideFlags: 0 682 | m_Script: {fileID: 11500000, guid: 4c4537fa49e29be49a11e10e73efd93c, type: 3} 683 | m_Name: 684 | m_EditorClassIdentifier: 685 | plotPoints: [] 686 | displayWindowSize: 300 687 | --- !u!4 &2102209731 688 | Transform: 689 | m_ObjectHideFlags: 0 690 | m_PrefabParentObject: {fileID: 4871077455905390, guid: 392f6a573c8ea7f4d86fe0a7f2e16d2e, 691 | type: 2} 692 | m_PrefabInternal: {fileID: 0} 693 | m_GameObject: {fileID: 2102209729} 694 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 695 | m_LocalPosition: {x: 0, y: -0.15, z: 1} 696 | m_LocalScale: {x: 1, y: 1, z: 1} 697 | m_Children: 698 | - {fileID: 1349695229} 699 | - {fileID: 1500422036} 700 | m_Father: {fileID: 0} 701 | m_RootOrder: 4 702 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 703 | --- !u!1 &2142178370 704 | GameObject: 705 | m_ObjectHideFlags: 0 706 | m_PrefabParentObject: {fileID: 1223875549596272, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 707 | type: 2} 708 | m_PrefabInternal: {fileID: 0} 709 | serializedVersion: 5 710 | m_Component: 711 | - component: {fileID: 2142178373} 712 | - component: {fileID: 2142178371} 713 | m_Layer: 0 714 | m_Name: RealtimePlot 715 | m_TagString: Untagged 716 | m_Icon: {fileID: 0} 717 | m_NavMeshLayer: 0 718 | m_StaticEditorFlags: 0 719 | m_IsActive: 1 720 | --- !u!114 &2142178371 721 | MonoBehaviour: 722 | m_ObjectHideFlags: 0 723 | m_PrefabParentObject: {fileID: 0} 724 | m_PrefabInternal: {fileID: 0} 725 | m_GameObject: {fileID: 2142178370} 726 | m_Enabled: 1 727 | m_EditorHideFlags: 0 728 | m_Script: {fileID: 11500000, guid: 4c4537fa49e29be49a11e10e73efd93c, type: 3} 729 | m_Name: 730 | m_EditorClassIdentifier: 731 | plotPoints: [] 732 | displayWindowSize: 150 733 | --- !u!4 &2142178373 734 | Transform: 735 | m_ObjectHideFlags: 0 736 | m_PrefabParentObject: {fileID: 4773519846245870, guid: 1afb47c6bcd3b1344bfa6e638fb53f04, 737 | type: 2} 738 | m_PrefabInternal: {fileID: 0} 739 | m_GameObject: {fileID: 2142178370} 740 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 741 | m_LocalPosition: {x: -0.375, y: 0.15, z: 1} 742 | m_LocalScale: {x: 1, y: 1, z: 1} 743 | m_Children: 744 | - {fileID: 1151287536} 745 | - {fileID: 152440739} 746 | m_Father: {fileID: 0} 747 | m_RootOrder: 3 748 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 749 | -------------------------------------------------------------------------------- /Assets/PlotDemo.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63180a6b7fd72cd4b9055f209cce704f 3 | timeCreated: 1518748056 4 | licenseType: Free 5 | DefaultImporter: 6 | externalObjects: {} 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Resources.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c6e166cc6bdbe274aabed9c7c4e29294 3 | folderAsset: yes 4 | timeCreated: 1518748081 5 | licenseType: Free 6 | DefaultImporter: 7 | externalObjects: {} 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /Assets/Resources/Point.prefab: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1001 &100100000 4 | Prefab: 5 | m_ObjectHideFlags: 1 6 | serializedVersion: 2 7 | m_Modification: 8 | m_TransformParent: {fileID: 0} 9 | m_Modifications: [] 10 | m_RemovedComponents: [] 11 | m_ParentPrefab: {fileID: 0} 12 | m_RootGameObject: {fileID: 1700265148678854} 13 | m_IsPrefabParent: 1 14 | --- !u!1 &1064531388013294 15 | GameObject: 16 | m_ObjectHideFlags: 0 17 | m_PrefabParentObject: {fileID: 0} 18 | m_PrefabInternal: {fileID: 100100000} 19 | serializedVersion: 5 20 | m_Component: 21 | - component: {fileID: 4527106114495816} 22 | - component: {fileID: 33509433753061288} 23 | - component: {fileID: 65974321329487320} 24 | - component: {fileID: 23153992449497764} 25 | m_Layer: 0 26 | m_Name: FluxPoint 27 | m_TagString: Untagged 28 | m_Icon: {fileID: 0} 29 | m_NavMeshLayer: 0 30 | m_StaticEditorFlags: 0 31 | m_IsActive: 1 32 | --- !u!1 &1129795695811848 33 | GameObject: 34 | m_ObjectHideFlags: 0 35 | m_PrefabParentObject: {fileID: 0} 36 | m_PrefabInternal: {fileID: 100100000} 37 | serializedVersion: 5 38 | m_Component: 39 | - component: {fileID: 4779218826680174} 40 | - component: {fileID: 33625152965020132} 41 | - component: {fileID: 65642411168087844} 42 | - component: {fileID: 23139974683899668} 43 | m_Layer: 0 44 | m_Name: BasePoint 45 | m_TagString: Untagged 46 | m_Icon: {fileID: 0} 47 | m_NavMeshLayer: 0 48 | m_StaticEditorFlags: 0 49 | m_IsActive: 1 50 | --- !u!1 &1487127936856526 51 | GameObject: 52 | m_ObjectHideFlags: 0 53 | m_PrefabParentObject: {fileID: 0} 54 | m_PrefabInternal: {fileID: 100100000} 55 | serializedVersion: 5 56 | m_Component: 57 | - component: {fileID: 4902838228050152} 58 | - component: {fileID: 33107040953166546} 59 | - component: {fileID: 65367271237695000} 60 | - component: {fileID: 23933578613599788} 61 | m_Layer: 0 62 | m_Name: PeakPoint 63 | m_TagString: Untagged 64 | m_Icon: {fileID: 0} 65 | m_NavMeshLayer: 0 66 | m_StaticEditorFlags: 0 67 | m_IsActive: 1 68 | --- !u!1 &1635602081565074 69 | GameObject: 70 | m_ObjectHideFlags: 0 71 | m_PrefabParentObject: {fileID: 0} 72 | m_PrefabInternal: {fileID: 100100000} 73 | serializedVersion: 5 74 | m_Component: 75 | - component: {fileID: 4227500876696368} 76 | - component: {fileID: 33522575642740422} 77 | - component: {fileID: 65247462676963828} 78 | - component: {fileID: 23915978871669282} 79 | m_Layer: 0 80 | m_Name: ThreshPoint 81 | m_TagString: Untagged 82 | m_Icon: {fileID: 0} 83 | m_NavMeshLayer: 0 84 | m_StaticEditorFlags: 0 85 | m_IsActive: 1 86 | --- !u!1 &1700265148678854 87 | GameObject: 88 | m_ObjectHideFlags: 0 89 | m_PrefabParentObject: {fileID: 0} 90 | m_PrefabInternal: {fileID: 100100000} 91 | serializedVersion: 5 92 | m_Component: 93 | - component: {fileID: 4536838457428552} 94 | m_Layer: 0 95 | m_Name: Point 96 | m_TagString: Untagged 97 | m_Icon: {fileID: 0} 98 | m_NavMeshLayer: 0 99 | m_StaticEditorFlags: 0 100 | m_IsActive: 1 101 | --- !u!4 &4227500876696368 102 | Transform: 103 | m_ObjectHideFlags: 1 104 | m_PrefabParentObject: {fileID: 0} 105 | m_PrefabInternal: {fileID: 100100000} 106 | m_GameObject: {fileID: 1635602081565074} 107 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 108 | m_LocalPosition: {x: 0, y: 0, z: 0.01} 109 | m_LocalScale: {x: 0.005, y: 0.005, z: 0.01} 110 | m_Children: [] 111 | m_Father: {fileID: 4536838457428552} 112 | m_RootOrder: 1 113 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 114 | --- !u!4 &4527106114495816 115 | Transform: 116 | m_ObjectHideFlags: 1 117 | m_PrefabParentObject: {fileID: 0} 118 | m_PrefabInternal: {fileID: 100100000} 119 | m_GameObject: {fileID: 1064531388013294} 120 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 121 | m_LocalPosition: {x: 0, y: 0, z: 0.01} 122 | m_LocalScale: {x: 0.005, y: 0.005, z: 0.01} 123 | m_Children: [] 124 | m_Father: {fileID: 4536838457428552} 125 | m_RootOrder: 0 126 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 127 | --- !u!4 &4536838457428552 128 | Transform: 129 | m_ObjectHideFlags: 1 130 | m_PrefabParentObject: {fileID: 0} 131 | m_PrefabInternal: {fileID: 100100000} 132 | m_GameObject: {fileID: 1700265148678854} 133 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 134 | m_LocalPosition: {x: 0, y: 0, z: 0} 135 | m_LocalScale: {x: 1, y: 1, z: 1} 136 | m_Children: 137 | - {fileID: 4527106114495816} 138 | - {fileID: 4227500876696368} 139 | - {fileID: 4779218826680174} 140 | - {fileID: 4902838228050152} 141 | m_Father: {fileID: 0} 142 | m_RootOrder: 0 143 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 144 | --- !u!4 &4779218826680174 145 | Transform: 146 | m_ObjectHideFlags: 1 147 | m_PrefabParentObject: {fileID: 0} 148 | m_PrefabInternal: {fileID: 100100000} 149 | m_GameObject: {fileID: 1129795695811848} 150 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 151 | m_LocalPosition: {x: 0, y: 0, z: 0} 152 | m_LocalScale: {x: 0.005, y: 0.005, z: 0.01} 153 | m_Children: [] 154 | m_Father: {fileID: 4536838457428552} 155 | m_RootOrder: 2 156 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 157 | --- !u!4 &4902838228050152 158 | Transform: 159 | m_ObjectHideFlags: 1 160 | m_PrefabParentObject: {fileID: 0} 161 | m_PrefabInternal: {fileID: 100100000} 162 | m_GameObject: {fileID: 1487127936856526} 163 | m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} 164 | m_LocalPosition: {x: 0, y: 0, z: 0.01} 165 | m_LocalScale: {x: 0.005, y: 0.005, z: 0.01} 166 | m_Children: [] 167 | m_Father: {fileID: 4536838457428552} 168 | m_RootOrder: 3 169 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 170 | --- !u!23 &23139974683899668 171 | MeshRenderer: 172 | m_ObjectHideFlags: 1 173 | m_PrefabParentObject: {fileID: 0} 174 | m_PrefabInternal: {fileID: 100100000} 175 | m_GameObject: {fileID: 1129795695811848} 176 | m_Enabled: 1 177 | m_CastShadows: 1 178 | m_ReceiveShadows: 1 179 | m_DynamicOccludee: 1 180 | m_MotionVectors: 1 181 | m_LightProbeUsage: 1 182 | m_ReflectionProbeUsage: 1 183 | m_Materials: 184 | - {fileID: 2100000, guid: 1f373dd111dd91340a3f1cd4748b2d77, type: 2} 185 | m_StaticBatchInfo: 186 | firstSubMesh: 0 187 | subMeshCount: 0 188 | m_StaticBatchRoot: {fileID: 0} 189 | m_ProbeAnchor: {fileID: 0} 190 | m_LightProbeVolumeOverride: {fileID: 0} 191 | m_ScaleInLightmap: 1 192 | m_PreserveUVs: 1 193 | m_IgnoreNormalsForChartDetection: 0 194 | m_ImportantGI: 0 195 | m_StitchLightmapSeams: 0 196 | m_SelectedEditorRenderState: 3 197 | m_MinimumChartSize: 4 198 | m_AutoUVMaxDistance: 0.5 199 | m_AutoUVMaxAngle: 89 200 | m_LightmapParameters: {fileID: 0} 201 | m_SortingLayerID: 0 202 | m_SortingLayer: 0 203 | m_SortingOrder: 0 204 | --- !u!23 &23153992449497764 205 | MeshRenderer: 206 | m_ObjectHideFlags: 1 207 | m_PrefabParentObject: {fileID: 0} 208 | m_PrefabInternal: {fileID: 100100000} 209 | m_GameObject: {fileID: 1064531388013294} 210 | m_Enabled: 1 211 | m_CastShadows: 1 212 | m_ReceiveShadows: 1 213 | m_DynamicOccludee: 1 214 | m_MotionVectors: 1 215 | m_LightProbeUsage: 1 216 | m_ReflectionProbeUsage: 1 217 | m_Materials: 218 | - {fileID: 2100000, guid: 7c5e91b86fddaeb41965ed926d24d075, type: 2} 219 | m_StaticBatchInfo: 220 | firstSubMesh: 0 221 | subMeshCount: 0 222 | m_StaticBatchRoot: {fileID: 0} 223 | m_ProbeAnchor: {fileID: 0} 224 | m_LightProbeVolumeOverride: {fileID: 0} 225 | m_ScaleInLightmap: 1 226 | m_PreserveUVs: 1 227 | m_IgnoreNormalsForChartDetection: 0 228 | m_ImportantGI: 0 229 | m_StitchLightmapSeams: 0 230 | m_SelectedEditorRenderState: 3 231 | m_MinimumChartSize: 4 232 | m_AutoUVMaxDistance: 0.5 233 | m_AutoUVMaxAngle: 89 234 | m_LightmapParameters: {fileID: 0} 235 | m_SortingLayerID: 0 236 | m_SortingLayer: 0 237 | m_SortingOrder: 0 238 | --- !u!23 &23915978871669282 239 | MeshRenderer: 240 | m_ObjectHideFlags: 1 241 | m_PrefabParentObject: {fileID: 0} 242 | m_PrefabInternal: {fileID: 100100000} 243 | m_GameObject: {fileID: 1635602081565074} 244 | m_Enabled: 1 245 | m_CastShadows: 1 246 | m_ReceiveShadows: 1 247 | m_DynamicOccludee: 1 248 | m_MotionVectors: 1 249 | m_LightProbeUsage: 1 250 | m_ReflectionProbeUsage: 1 251 | m_Materials: 252 | - {fileID: 2100000, guid: bca9ce34683a7f6499200a7007f39881, type: 2} 253 | m_StaticBatchInfo: 254 | firstSubMesh: 0 255 | subMeshCount: 0 256 | m_StaticBatchRoot: {fileID: 0} 257 | m_ProbeAnchor: {fileID: 0} 258 | m_LightProbeVolumeOverride: {fileID: 0} 259 | m_ScaleInLightmap: 1 260 | m_PreserveUVs: 1 261 | m_IgnoreNormalsForChartDetection: 0 262 | m_ImportantGI: 0 263 | m_StitchLightmapSeams: 0 264 | m_SelectedEditorRenderState: 3 265 | m_MinimumChartSize: 4 266 | m_AutoUVMaxDistance: 0.5 267 | m_AutoUVMaxAngle: 89 268 | m_LightmapParameters: {fileID: 0} 269 | m_SortingLayerID: 0 270 | m_SortingLayer: 0 271 | m_SortingOrder: 0 272 | --- !u!23 &23933578613599788 273 | MeshRenderer: 274 | m_ObjectHideFlags: 1 275 | m_PrefabParentObject: {fileID: 0} 276 | m_PrefabInternal: {fileID: 100100000} 277 | m_GameObject: {fileID: 1487127936856526} 278 | m_Enabled: 1 279 | m_CastShadows: 1 280 | m_ReceiveShadows: 1 281 | m_DynamicOccludee: 1 282 | m_MotionVectors: 1 283 | m_LightProbeUsage: 1 284 | m_ReflectionProbeUsage: 1 285 | m_Materials: 286 | - {fileID: 2100000, guid: 2bdcde7c59d53f14ba9ee6ff94d6b719, type: 2} 287 | m_StaticBatchInfo: 288 | firstSubMesh: 0 289 | subMeshCount: 0 290 | m_StaticBatchRoot: {fileID: 0} 291 | m_ProbeAnchor: {fileID: 0} 292 | m_LightProbeVolumeOverride: {fileID: 0} 293 | m_ScaleInLightmap: 1 294 | m_PreserveUVs: 1 295 | m_IgnoreNormalsForChartDetection: 0 296 | m_ImportantGI: 0 297 | m_StitchLightmapSeams: 0 298 | m_SelectedEditorRenderState: 3 299 | m_MinimumChartSize: 4 300 | m_AutoUVMaxDistance: 0.5 301 | m_AutoUVMaxAngle: 89 302 | m_LightmapParameters: {fileID: 0} 303 | m_SortingLayerID: 0 304 | m_SortingLayer: 0 305 | m_SortingOrder: 0 306 | --- !u!33 &33107040953166546 307 | MeshFilter: 308 | m_ObjectHideFlags: 1 309 | m_PrefabParentObject: {fileID: 0} 310 | m_PrefabInternal: {fileID: 100100000} 311 | m_GameObject: {fileID: 1487127936856526} 312 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 313 | --- !u!33 &33509433753061288 314 | MeshFilter: 315 | m_ObjectHideFlags: 1 316 | m_PrefabParentObject: {fileID: 0} 317 | m_PrefabInternal: {fileID: 100100000} 318 | m_GameObject: {fileID: 1064531388013294} 319 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 320 | --- !u!33 &33522575642740422 321 | MeshFilter: 322 | m_ObjectHideFlags: 1 323 | m_PrefabParentObject: {fileID: 0} 324 | m_PrefabInternal: {fileID: 100100000} 325 | m_GameObject: {fileID: 1635602081565074} 326 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 327 | --- !u!33 &33625152965020132 328 | MeshFilter: 329 | m_ObjectHideFlags: 1 330 | m_PrefabParentObject: {fileID: 0} 331 | m_PrefabInternal: {fileID: 100100000} 332 | m_GameObject: {fileID: 1129795695811848} 333 | m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} 334 | --- !u!65 &65247462676963828 335 | BoxCollider: 336 | m_ObjectHideFlags: 1 337 | m_PrefabParentObject: {fileID: 0} 338 | m_PrefabInternal: {fileID: 100100000} 339 | m_GameObject: {fileID: 1635602081565074} 340 | m_Material: {fileID: 0} 341 | m_IsTrigger: 0 342 | m_Enabled: 1 343 | serializedVersion: 2 344 | m_Size: {x: 1, y: 1, z: 1} 345 | m_Center: {x: 0, y: 0, z: 0} 346 | --- !u!65 &65367271237695000 347 | BoxCollider: 348 | m_ObjectHideFlags: 1 349 | m_PrefabParentObject: {fileID: 0} 350 | m_PrefabInternal: {fileID: 100100000} 351 | m_GameObject: {fileID: 1487127936856526} 352 | m_Material: {fileID: 0} 353 | m_IsTrigger: 0 354 | m_Enabled: 1 355 | serializedVersion: 2 356 | m_Size: {x: 1, y: 1, z: 1} 357 | m_Center: {x: 0, y: 0, z: 0} 358 | --- !u!65 &65642411168087844 359 | BoxCollider: 360 | m_ObjectHideFlags: 1 361 | m_PrefabParentObject: {fileID: 0} 362 | m_PrefabInternal: {fileID: 100100000} 363 | m_GameObject: {fileID: 1129795695811848} 364 | m_Material: {fileID: 0} 365 | m_IsTrigger: 0 366 | m_Enabled: 1 367 | serializedVersion: 2 368 | m_Size: {x: 1, y: 1, z: 1} 369 | m_Center: {x: 0, y: 0, z: 0} 370 | --- !u!65 &65974321329487320 371 | BoxCollider: 372 | m_ObjectHideFlags: 1 373 | m_PrefabParentObject: {fileID: 0} 374 | m_PrefabInternal: {fileID: 100100000} 375 | m_GameObject: {fileID: 1064531388013294} 376 | m_Material: {fileID: 0} 377 | m_IsTrigger: 0 378 | m_Enabled: 1 379 | serializedVersion: 2 380 | m_Size: {x: 1, y: 1, z: 1} 381 | m_Center: {x: 0, y: 0, z: 0} 382 | -------------------------------------------------------------------------------- /Assets/Resources/Point.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8a552ee8d4e985f4eb965c1dbd8cb815 3 | timeCreated: 1518748233 4 | licenseType: Free 5 | NativeFormatImporter: 6 | externalObjects: {} 7 | mainObjectFileID: 0 8 | userData: 9 | assetBundleName: 10 | assetBundleVariant: 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jesse Keogh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 0 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 1 23 | m_ClothInterCollisionSettingsToggle: 0 24 | m_ContactPairsMode: 0 25 | m_BroadphaseType: 0 26 | m_WorldBounds: 27 | m_Center: {x: 0, y: 0, z: 0} 28 | m_Extent: {x: 250, y: 250, z: 250} 29 | m_WorldSubdivisions: 8 30 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: [] 8 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 7 7 | m_ExternalVersionControlSupport: Hidden Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_SpritePackerMode: 0 12 | m_SpritePackerPaddingPower: 1 13 | m_EtcTextureCompressorBehavior: 1 14 | m_EtcTextureFastCompressor: 1 15 | m_EtcTextureNormalCompressor: 2 16 | m_EtcTextureBestCompressor: 4 17 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp 18 | m_ProjectGenerationRootNamespace: 19 | m_UserGeneratedProjectSuffix: 20 | m_CollabEditorSettings: 21 | inProgressEnabled: 1 22 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 3 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_AutoSimulation: 1 23 | m_QueriesHitTriggers: 1 24 | m_QueriesStartInColliders: 1 25 | m_ChangeStopsCallbacks: 0 26 | m_CallbacksOnDisable: 1 27 | m_AutoSyncTransforms: 1 28 | m_AlwaysShowColliders: 0 29 | m_ShowColliderSleep: 1 30 | m_ShowColliderContacts: 0 31 | m_ShowColliderAABB: 0 32 | m_ContactArrowScale: 0.2 33 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 34 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 35 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 36 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 37 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 38 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 14 7 | productGUID: 4ea4f379c102eaf408e9f09d07d6a300 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | defaultScreenOrientation: 4 11 | targetDevice: 2 12 | useOnDemandResources: 0 13 | accelerometerFrequency: 60 14 | companyName: DefaultCompany 15 | productName: Onset Detection Using Spectral Flux 16 | defaultCursor: {fileID: 0} 17 | cursorHotspot: {x: 0, y: 0} 18 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 19 | m_ShowUnitySplashScreen: 1 20 | m_ShowUnitySplashLogo: 1 21 | m_SplashScreenOverlayOpacity: 1 22 | m_SplashScreenAnimation: 1 23 | m_SplashScreenLogoStyle: 1 24 | m_SplashScreenDrawMode: 0 25 | m_SplashScreenBackgroundAnimationZoom: 1 26 | m_SplashScreenLogoAnimationZoom: 1 27 | m_SplashScreenBackgroundLandscapeAspect: 1 28 | m_SplashScreenBackgroundPortraitAspect: 1 29 | m_SplashScreenBackgroundLandscapeUvs: 30 | serializedVersion: 2 31 | x: 0 32 | y: 0 33 | width: 1 34 | height: 1 35 | m_SplashScreenBackgroundPortraitUvs: 36 | serializedVersion: 2 37 | x: 0 38 | y: 0 39 | width: 1 40 | height: 1 41 | m_SplashScreenLogos: [] 42 | m_VirtualRealitySplashScreen: {fileID: 0} 43 | m_HolographicTrackingLossScreen: {fileID: 0} 44 | defaultScreenWidth: 1024 45 | defaultScreenHeight: 768 46 | defaultScreenWidthWeb: 960 47 | defaultScreenHeightWeb: 600 48 | m_StereoRenderingPath: 0 49 | m_ActiveColorSpace: 0 50 | m_MTRendering: 1 51 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 52 | iosShowActivityIndicatorOnLoading: -1 53 | androidShowActivityIndicatorOnLoading: -1 54 | tizenShowActivityIndicatorOnLoading: -1 55 | iosAppInBackgroundBehavior: 0 56 | displayResolutionDialog: 1 57 | iosAllowHTTPDownload: 1 58 | allowedAutorotateToPortrait: 1 59 | allowedAutorotateToPortraitUpsideDown: 1 60 | allowedAutorotateToLandscapeRight: 1 61 | allowedAutorotateToLandscapeLeft: 1 62 | useOSAutorotation: 1 63 | use32BitDisplayBuffer: 1 64 | preserveFramebufferAlpha: 0 65 | disableDepthAndStencilBuffers: 0 66 | androidBlitType: 0 67 | defaultIsFullScreen: 1 68 | defaultIsNativeResolution: 1 69 | macRetinaSupport: 1 70 | runInBackground: 0 71 | captureSingleScreen: 0 72 | muteOtherAudioSources: 0 73 | Prepare IOS For Recording: 0 74 | Force IOS Speakers When Recording: 0 75 | deferSystemGesturesMode: 0 76 | hideHomeButton: 0 77 | submitAnalytics: 1 78 | usePlayerLog: 1 79 | bakeCollisionMeshes: 0 80 | forceSingleInstance: 0 81 | resizableWindow: 0 82 | useMacAppStoreValidation: 0 83 | macAppStoreCategory: public.app-category.games 84 | gpuSkinning: 0 85 | graphicsJobs: 0 86 | xboxPIXTextureCapture: 0 87 | xboxEnableAvatar: 0 88 | xboxEnableKinect: 0 89 | xboxEnableKinectAutoTracking: 0 90 | xboxEnableFitness: 0 91 | visibleInBackground: 1 92 | allowFullscreenSwitch: 1 93 | graphicsJobMode: 0 94 | macFullscreenMode: 2 95 | d3d11FullscreenMode: 1 96 | xboxSpeechDB: 0 97 | xboxEnableHeadOrientation: 0 98 | xboxEnableGuest: 0 99 | xboxEnablePIXSampling: 0 100 | metalFramebufferOnly: 0 101 | n3dsDisableStereoscopicView: 0 102 | n3dsEnableSharedListOpt: 1 103 | n3dsEnableVSync: 0 104 | xboxOneResolution: 0 105 | xboxOneSResolution: 0 106 | xboxOneXResolution: 3 107 | xboxOneMonoLoggingLevel: 0 108 | xboxOneLoggingLevel: 1 109 | xboxOneDisableEsram: 0 110 | xboxOnePresentImmediateThreshold: 0 111 | videoMemoryForVertexBuffers: 0 112 | psp2PowerMode: 0 113 | psp2AcquireBGM: 1 114 | wiiUTVResolution: 0 115 | wiiUGamePadMSAA: 1 116 | wiiUSupportsNunchuk: 0 117 | wiiUSupportsClassicController: 0 118 | wiiUSupportsBalanceBoard: 0 119 | wiiUSupportsMotionPlus: 0 120 | wiiUSupportsProController: 0 121 | wiiUAllowScreenCapture: 1 122 | wiiUControllerCount: 0 123 | m_SupportedAspectRatios: 124 | 4:3: 1 125 | 5:4: 1 126 | 16:10: 1 127 | 16:9: 1 128 | Others: 1 129 | bundleVersion: 1.0 130 | preloadedAssets: [] 131 | metroInputSource: 0 132 | wsaTransparentSwapchain: 0 133 | m_HolographicPauseOnTrackingLoss: 1 134 | xboxOneDisableKinectGpuReservation: 0 135 | xboxOneEnable7thCore: 0 136 | vrSettings: 137 | cardboard: 138 | depthFormat: 0 139 | enableTransitionView: 0 140 | daydream: 141 | depthFormat: 0 142 | useSustainedPerformanceMode: 0 143 | enableVideoLayer: 0 144 | useProtectedVideoMemory: 0 145 | minimumSupportedHeadTracking: 0 146 | maximumSupportedHeadTracking: 1 147 | hololens: 148 | depthFormat: 1 149 | depthBufferSharingEnabled: 0 150 | oculus: 151 | sharedDepthBuffer: 0 152 | dashSupport: 0 153 | protectGraphicsMemory: 0 154 | useHDRDisplay: 0 155 | m_ColorGamuts: 00000000 156 | targetPixelDensity: 30 157 | resolutionScalingMode: 0 158 | androidSupportedAspectRatio: 1 159 | androidMaxAspectRatio: 2.1 160 | applicationIdentifier: {} 161 | buildNumber: {} 162 | AndroidBundleVersionCode: 1 163 | AndroidMinSdkVersion: 16 164 | AndroidTargetSdkVersion: 0 165 | AndroidPreferredInstallLocation: 1 166 | aotOptions: 167 | stripEngineCode: 1 168 | iPhoneStrippingLevel: 0 169 | iPhoneScriptCallOptimization: 0 170 | ForceInternetPermission: 0 171 | ForceSDCardPermission: 0 172 | CreateWallpaper: 0 173 | APKExpansionFiles: 0 174 | keepLoadedShadersAlive: 0 175 | StripUnusedMeshComponents: 0 176 | VertexChannelCompressionMask: 177 | serializedVersion: 2 178 | m_Bits: 238 179 | iPhoneSdkVersion: 988 180 | iOSTargetOSVersionString: 7.0 181 | tvOSSdkVersion: 0 182 | tvOSRequireExtendedGameController: 0 183 | tvOSTargetOSVersionString: 9.0 184 | uIPrerenderedIcon: 0 185 | uIRequiresPersistentWiFi: 0 186 | uIRequiresFullScreen: 1 187 | uIStatusBarHidden: 1 188 | uIExitOnSuspend: 0 189 | uIStatusBarStyle: 0 190 | iPhoneSplashScreen: {fileID: 0} 191 | iPhoneHighResSplashScreen: {fileID: 0} 192 | iPhoneTallHighResSplashScreen: {fileID: 0} 193 | iPhone47inSplashScreen: {fileID: 0} 194 | iPhone55inPortraitSplashScreen: {fileID: 0} 195 | iPhone55inLandscapeSplashScreen: {fileID: 0} 196 | iPhone58inPortraitSplashScreen: {fileID: 0} 197 | iPhone58inLandscapeSplashScreen: {fileID: 0} 198 | iPadPortraitSplashScreen: {fileID: 0} 199 | iPadHighResPortraitSplashScreen: {fileID: 0} 200 | iPadLandscapeSplashScreen: {fileID: 0} 201 | iPadHighResLandscapeSplashScreen: {fileID: 0} 202 | appleTVSplashScreen: {fileID: 0} 203 | appleTVSplashScreen2x: {fileID: 0} 204 | tvOSSmallIconLayers: [] 205 | tvOSSmallIconLayers2x: [] 206 | tvOSLargeIconLayers: [] 207 | tvOSLargeIconLayers2x: [] 208 | tvOSTopShelfImageLayers: [] 209 | tvOSTopShelfImageLayers2x: [] 210 | tvOSTopShelfImageWideLayers: [] 211 | tvOSTopShelfImageWideLayers2x: [] 212 | iOSLaunchScreenType: 0 213 | iOSLaunchScreenPortrait: {fileID: 0} 214 | iOSLaunchScreenLandscape: {fileID: 0} 215 | iOSLaunchScreenBackgroundColor: 216 | serializedVersion: 2 217 | rgba: 0 218 | iOSLaunchScreenFillPct: 100 219 | iOSLaunchScreenSize: 100 220 | iOSLaunchScreenCustomXibPath: 221 | iOSLaunchScreeniPadType: 0 222 | iOSLaunchScreeniPadImage: {fileID: 0} 223 | iOSLaunchScreeniPadBackgroundColor: 224 | serializedVersion: 2 225 | rgba: 0 226 | iOSLaunchScreeniPadFillPct: 100 227 | iOSLaunchScreeniPadSize: 100 228 | iOSLaunchScreeniPadCustomXibPath: 229 | iOSUseLaunchScreenStoryboard: 0 230 | iOSLaunchScreenCustomStoryboardPath: 231 | iOSDeviceRequirements: [] 232 | iOSURLSchemes: [] 233 | iOSBackgroundModes: 0 234 | iOSMetalForceHardShadows: 0 235 | metalEditorSupport: 1 236 | metalAPIValidation: 1 237 | iOSRenderExtraFrameOnPause: 0 238 | appleDeveloperTeamID: 239 | iOSManualSigningProvisioningProfileID: 240 | tvOSManualSigningProvisioningProfileID: 241 | appleEnableAutomaticSigning: 0 242 | clonedFromGUID: 00000000000000000000000000000000 243 | AndroidTargetDevice: 0 244 | AndroidSplashScreenScale: 0 245 | androidSplashScreen: {fileID: 0} 246 | AndroidKeystoreName: 247 | AndroidKeyaliasName: 248 | AndroidTVCompatibility: 1 249 | AndroidIsGame: 1 250 | AndroidEnableTango: 0 251 | androidEnableBanner: 1 252 | androidUseLowAccuracyLocation: 0 253 | m_AndroidBanners: 254 | - width: 320 255 | height: 180 256 | banner: {fileID: 0} 257 | androidGamepadSupportLevel: 0 258 | resolutionDialogBanner: {fileID: 0} 259 | m_BuildTargetIcons: [] 260 | m_BuildTargetBatching: [] 261 | m_BuildTargetGraphicsAPIs: [] 262 | m_BuildTargetVRSettings: [] 263 | m_BuildTargetEnableVuforiaSettings: [] 264 | openGLRequireES31: 0 265 | openGLRequireES31AEP: 0 266 | m_TemplateCustomTags: {} 267 | mobileMTRendering: 268 | Android: 1 269 | iPhone: 1 270 | tvOS: 1 271 | m_BuildTargetGroupLightmapEncodingQuality: [] 272 | wiiUTitleID: 0005000011000000 273 | wiiUGroupID: 00010000 274 | wiiUCommonSaveSize: 4096 275 | wiiUAccountSaveSize: 2048 276 | wiiUOlvAccessKey: 0 277 | wiiUTinCode: 0 278 | wiiUJoinGameId: 0 279 | wiiUJoinGameModeMask: 0000000000000000 280 | wiiUCommonBossSize: 0 281 | wiiUAccountBossSize: 0 282 | wiiUAddOnUniqueIDs: [] 283 | wiiUMainThreadStackSize: 3072 284 | wiiULoaderThreadStackSize: 1024 285 | wiiUSystemHeapSize: 128 286 | wiiUTVStartupScreen: {fileID: 0} 287 | wiiUGamePadStartupScreen: {fileID: 0} 288 | wiiUDrcBufferDisabled: 0 289 | wiiUProfilerLibPath: 290 | playModeTestRunnerEnabled: 0 291 | actionOnDotNetUnhandledException: 1 292 | enableInternalProfiler: 0 293 | logObjCUncaughtExceptions: 1 294 | enableCrashReportAPI: 0 295 | cameraUsageDescription: 296 | locationUsageDescription: 297 | microphoneUsageDescription: 298 | switchNetLibKey: 299 | switchSocketMemoryPoolSize: 6144 300 | switchSocketAllocatorPoolSize: 128 301 | switchSocketConcurrencyLimit: 14 302 | switchScreenResolutionBehavior: 2 303 | switchUseCPUProfiler: 0 304 | switchApplicationID: 0x01004b9000490000 305 | switchNSODependencies: 306 | switchTitleNames_0: 307 | switchTitleNames_1: 308 | switchTitleNames_2: 309 | switchTitleNames_3: 310 | switchTitleNames_4: 311 | switchTitleNames_5: 312 | switchTitleNames_6: 313 | switchTitleNames_7: 314 | switchTitleNames_8: 315 | switchTitleNames_9: 316 | switchTitleNames_10: 317 | switchTitleNames_11: 318 | switchTitleNames_12: 319 | switchTitleNames_13: 320 | switchTitleNames_14: 321 | switchPublisherNames_0: 322 | switchPublisherNames_1: 323 | switchPublisherNames_2: 324 | switchPublisherNames_3: 325 | switchPublisherNames_4: 326 | switchPublisherNames_5: 327 | switchPublisherNames_6: 328 | switchPublisherNames_7: 329 | switchPublisherNames_8: 330 | switchPublisherNames_9: 331 | switchPublisherNames_10: 332 | switchPublisherNames_11: 333 | switchPublisherNames_12: 334 | switchPublisherNames_13: 335 | switchPublisherNames_14: 336 | switchIcons_0: {fileID: 0} 337 | switchIcons_1: {fileID: 0} 338 | switchIcons_2: {fileID: 0} 339 | switchIcons_3: {fileID: 0} 340 | switchIcons_4: {fileID: 0} 341 | switchIcons_5: {fileID: 0} 342 | switchIcons_6: {fileID: 0} 343 | switchIcons_7: {fileID: 0} 344 | switchIcons_8: {fileID: 0} 345 | switchIcons_9: {fileID: 0} 346 | switchIcons_10: {fileID: 0} 347 | switchIcons_11: {fileID: 0} 348 | switchIcons_12: {fileID: 0} 349 | switchIcons_13: {fileID: 0} 350 | switchIcons_14: {fileID: 0} 351 | switchSmallIcons_0: {fileID: 0} 352 | switchSmallIcons_1: {fileID: 0} 353 | switchSmallIcons_2: {fileID: 0} 354 | switchSmallIcons_3: {fileID: 0} 355 | switchSmallIcons_4: {fileID: 0} 356 | switchSmallIcons_5: {fileID: 0} 357 | switchSmallIcons_6: {fileID: 0} 358 | switchSmallIcons_7: {fileID: 0} 359 | switchSmallIcons_8: {fileID: 0} 360 | switchSmallIcons_9: {fileID: 0} 361 | switchSmallIcons_10: {fileID: 0} 362 | switchSmallIcons_11: {fileID: 0} 363 | switchSmallIcons_12: {fileID: 0} 364 | switchSmallIcons_13: {fileID: 0} 365 | switchSmallIcons_14: {fileID: 0} 366 | switchManualHTML: 367 | switchAccessibleURLs: 368 | switchLegalInformation: 369 | switchMainThreadStackSize: 1048576 370 | switchPresenceGroupId: 371 | switchLogoHandling: 0 372 | switchReleaseVersion: 0 373 | switchDisplayVersion: 1.0.0 374 | switchStartupUserAccount: 0 375 | switchTouchScreenUsage: 0 376 | switchSupportedLanguagesMask: 0 377 | switchLogoType: 0 378 | switchApplicationErrorCodeCategory: 379 | switchUserAccountSaveDataSize: 0 380 | switchUserAccountSaveDataJournalSize: 0 381 | switchApplicationAttribute: 0 382 | switchCardSpecSize: -1 383 | switchCardSpecClock: -1 384 | switchRatingsMask: 0 385 | switchRatingsInt_0: 0 386 | switchRatingsInt_1: 0 387 | switchRatingsInt_2: 0 388 | switchRatingsInt_3: 0 389 | switchRatingsInt_4: 0 390 | switchRatingsInt_5: 0 391 | switchRatingsInt_6: 0 392 | switchRatingsInt_7: 0 393 | switchRatingsInt_8: 0 394 | switchRatingsInt_9: 0 395 | switchRatingsInt_10: 0 396 | switchRatingsInt_11: 0 397 | switchLocalCommunicationIds_0: 398 | switchLocalCommunicationIds_1: 399 | switchLocalCommunicationIds_2: 400 | switchLocalCommunicationIds_3: 401 | switchLocalCommunicationIds_4: 402 | switchLocalCommunicationIds_5: 403 | switchLocalCommunicationIds_6: 404 | switchLocalCommunicationIds_7: 405 | switchParentalControl: 0 406 | switchAllowsScreenshot: 1 407 | switchAllowsVideoCapturing: 1 408 | switchAllowsRuntimeAddOnContentInstall: 0 409 | switchDataLossConfirmation: 0 410 | switchSupportedNpadStyles: 3 411 | switchSocketConfigEnabled: 0 412 | switchTcpInitialSendBufferSize: 32 413 | switchTcpInitialReceiveBufferSize: 64 414 | switchTcpAutoSendBufferSizeMax: 256 415 | switchTcpAutoReceiveBufferSizeMax: 256 416 | switchUdpSendBufferSize: 9 417 | switchUdpReceiveBufferSize: 42 418 | switchSocketBufferEfficiency: 4 419 | switchSocketInitializeEnabled: 1 420 | switchNetworkInterfaceManagerInitializeEnabled: 1 421 | switchPlayerConnectionEnabled: 1 422 | ps4NPAgeRating: 12 423 | ps4NPTitleSecret: 424 | ps4NPTrophyPackPath: 425 | ps4ParentalLevel: 11 426 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 427 | ps4Category: 0 428 | ps4MasterVersion: 01.00 429 | ps4AppVersion: 01.00 430 | ps4AppType: 0 431 | ps4ParamSfxPath: 432 | ps4VideoOutPixelFormat: 0 433 | ps4VideoOutInitialWidth: 1920 434 | ps4VideoOutBaseModeInitialWidth: 1920 435 | ps4VideoOutReprojectionRate: 60 436 | ps4PronunciationXMLPath: 437 | ps4PronunciationSIGPath: 438 | ps4BackgroundImagePath: 439 | ps4StartupImagePath: 440 | ps4StartupImagesFolder: 441 | ps4IconImagesFolder: 442 | ps4SaveDataImagePath: 443 | ps4SdkOverride: 444 | ps4BGMPath: 445 | ps4ShareFilePath: 446 | ps4ShareOverlayImagePath: 447 | ps4PrivacyGuardImagePath: 448 | ps4NPtitleDatPath: 449 | ps4RemotePlayKeyAssignment: -1 450 | ps4RemotePlayKeyMappingDir: 451 | ps4PlayTogetherPlayerCount: 0 452 | ps4EnterButtonAssignment: 1 453 | ps4ApplicationParam1: 0 454 | ps4ApplicationParam2: 0 455 | ps4ApplicationParam3: 0 456 | ps4ApplicationParam4: 0 457 | ps4DownloadDataSize: 0 458 | ps4GarlicHeapSize: 2048 459 | ps4ProGarlicHeapSize: 2560 460 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 461 | ps4pnSessions: 1 462 | ps4pnPresence: 1 463 | ps4pnFriends: 1 464 | ps4pnGameCustomData: 1 465 | playerPrefsSupport: 0 466 | restrictedAudioUsageRights: 0 467 | ps4UseResolutionFallback: 0 468 | ps4ReprojectionSupport: 0 469 | ps4UseAudio3dBackend: 0 470 | ps4SocialScreenEnabled: 0 471 | ps4ScriptOptimizationLevel: 0 472 | ps4Audio3dVirtualSpeakerCount: 14 473 | ps4attribCpuUsage: 0 474 | ps4PatchPkgPath: 475 | ps4PatchLatestPkgPath: 476 | ps4PatchChangeinfoPath: 477 | ps4PatchDayOne: 0 478 | ps4attribUserManagement: 0 479 | ps4attribMoveSupport: 0 480 | ps4attrib3DSupport: 0 481 | ps4attribShareSupport: 0 482 | ps4attribExclusiveVR: 0 483 | ps4disableAutoHideSplash: 0 484 | ps4videoRecordingFeaturesUsed: 0 485 | ps4contentSearchFeaturesUsed: 0 486 | ps4attribEyeToEyeDistanceSettingVR: 0 487 | ps4IncludedModules: [] 488 | monoEnv: 489 | psp2Splashimage: {fileID: 0} 490 | psp2NPTrophyPackPath: 491 | psp2NPSupportGBMorGJP: 0 492 | psp2NPAgeRating: 12 493 | psp2NPTitleDatPath: 494 | psp2NPCommsID: 495 | psp2NPCommunicationsID: 496 | psp2NPCommsPassphrase: 497 | psp2NPCommsSig: 498 | psp2ParamSfxPath: 499 | psp2ManualPath: 500 | psp2LiveAreaGatePath: 501 | psp2LiveAreaBackroundPath: 502 | psp2LiveAreaPath: 503 | psp2LiveAreaTrialPath: 504 | psp2PatchChangeInfoPath: 505 | psp2PatchOriginalPackage: 506 | psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui 507 | psp2KeystoneFile: 508 | psp2MemoryExpansionMode: 0 509 | psp2DRMType: 0 510 | psp2StorageType: 0 511 | psp2MediaCapacity: 0 512 | psp2DLCConfigPath: 513 | psp2ThumbnailPath: 514 | psp2BackgroundPath: 515 | psp2SoundPath: 516 | psp2TrophyCommId: 517 | psp2TrophyPackagePath: 518 | psp2PackagedResourcesPath: 519 | psp2SaveDataQuota: 10240 520 | psp2ParentalLevel: 1 521 | psp2ShortTitle: Not Set 522 | psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF 523 | psp2Category: 0 524 | psp2MasterVersion: 01.00 525 | psp2AppVersion: 01.00 526 | psp2TVBootMode: 0 527 | psp2EnterButtonAssignment: 2 528 | psp2TVDisableEmu: 0 529 | psp2AllowTwitterDialog: 1 530 | psp2Upgradable: 0 531 | psp2HealthWarning: 0 532 | psp2UseLibLocation: 0 533 | psp2InfoBarOnStartup: 0 534 | psp2InfoBarColor: 0 535 | psp2ScriptOptimizationLevel: 0 536 | psmSplashimage: {fileID: 0} 537 | splashScreenBackgroundSourceLandscape: {fileID: 0} 538 | splashScreenBackgroundSourcePortrait: {fileID: 0} 539 | spritePackerPolicy: 540 | webGLMemorySize: 256 541 | webGLExceptionSupport: 1 542 | webGLNameFilesAsHashes: 0 543 | webGLDataCaching: 0 544 | webGLDebugSymbols: 0 545 | webGLEmscriptenArgs: 546 | webGLModulesDirectory: 547 | webGLTemplate: APPLICATION:Default 548 | webGLAnalyzeBuildSize: 0 549 | webGLUseEmbeddedResources: 0 550 | webGLUseWasm: 0 551 | webGLCompressionFormat: 1 552 | scriptingDefineSymbols: {} 553 | platformArchitecture: {} 554 | scriptingBackend: {} 555 | incrementalIl2cppBuild: {} 556 | additionalIl2CppArgs: 557 | scriptingRuntimeVersion: 0 558 | apiCompatibilityLevelPerPlatform: {} 559 | m_RenderingPath: 1 560 | m_MobileRenderingPath: 1 561 | metroPackageName: Onset Detection Using Spectral Flux 562 | metroPackageVersion: 563 | metroCertificatePath: 564 | metroCertificatePassword: 565 | metroCertificateSubject: 566 | metroCertificateIssuer: 567 | metroCertificateNotAfter: 0000000000000000 568 | metroApplicationDescription: Onset Detection Using Spectral Flux 569 | wsaImages: {} 570 | metroTileShortName: 571 | metroCommandLineArgsFile: 572 | metroTileShowName: 0 573 | metroMediumTileShowName: 0 574 | metroLargeTileShowName: 0 575 | metroWideTileShowName: 0 576 | metroDefaultTileSize: 1 577 | metroTileForegroundText: 2 578 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 579 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 580 | a: 1} 581 | metroSplashScreenUseBackgroundColor: 0 582 | platformCapabilities: {} 583 | metroFTAName: 584 | metroFTAFileTypes: [] 585 | metroProtocolName: 586 | metroCompilationOverrides: 1 587 | tizenProductDescription: 588 | tizenProductURL: 589 | tizenSigningProfileName: 590 | tizenGPSPermissions: 0 591 | tizenMicrophonePermissions: 0 592 | tizenDeploymentTarget: 593 | tizenDeploymentTargetType: -1 594 | tizenMinOSVersion: 1 595 | n3dsUseExtSaveData: 0 596 | n3dsCompressStaticMem: 1 597 | n3dsExtSaveDataNumber: 0x12345 598 | n3dsStackSize: 131072 599 | n3dsTargetPlatform: 2 600 | n3dsRegion: 7 601 | n3dsMediaSize: 0 602 | n3dsLogoStyle: 3 603 | n3dsTitle: GameName 604 | n3dsProductCode: 605 | n3dsApplicationId: 0xFF3FF 606 | XboxOneProductId: 607 | XboxOneUpdateKey: 608 | XboxOneSandboxId: 609 | XboxOneContentId: 610 | XboxOneTitleId: 611 | XboxOneSCId: 612 | XboxOneGameOsOverridePath: 613 | XboxOnePackagingOverridePath: 614 | XboxOneAppManifestOverridePath: 615 | XboxOnePackageEncryption: 0 616 | XboxOnePackageUpdateGranularity: 2 617 | XboxOneDescription: 618 | XboxOneLanguage: 619 | - enus 620 | XboxOneCapability: [] 621 | XboxOneGameRating: {} 622 | XboxOneIsContentPackage: 0 623 | XboxOneEnableGPUVariability: 0 624 | XboxOneSockets: {} 625 | XboxOneSplashScreen: {fileID: 0} 626 | XboxOneAllowedProductIds: [] 627 | XboxOnePersistentLocalStorageSize: 0 628 | xboxOneScriptCompiler: 0 629 | vrEditorSettings: 630 | daydream: 631 | daydreamIconForeground: {fileID: 0} 632 | daydreamIconBackground: {fileID: 0} 633 | cloudServicesEnabled: {} 634 | facebookSdkVersion: 7.9.4 635 | apiCompatibilityLevel: 2 636 | cloudProjectId: 4c45a5ed-6794-459b-b878-d2e2689de9d1 637 | projectName: Onset Detection Using Spectral Flux 638 | organizationId: jesse-keogh 639 | cloudEnabled: 0 640 | enableNativePlatformBackendsForNewInputSystem: 0 641 | disableOldInputManagerSupport: 0 642 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2017.3.0f3 2 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | blendWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | particleRaycastBudget: 4 33 | asyncUploadTimeSlice: 2 34 | asyncUploadBufferSize: 4 35 | resolutionScalingFixedDPIFactor: 1 36 | excludedTargetPlatforms: [] 37 | - serializedVersion: 2 38 | name: Low 39 | pixelLightCount: 0 40 | shadows: 0 41 | shadowResolution: 0 42 | shadowProjection: 1 43 | shadowCascades: 1 44 | shadowDistance: 20 45 | shadowNearPlaneOffset: 3 46 | shadowCascade2Split: 0.33333334 47 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 48 | shadowmaskMode: 0 49 | blendWeights: 2 50 | textureQuality: 0 51 | anisotropicTextures: 0 52 | antiAliasing: 0 53 | softParticles: 0 54 | softVegetation: 0 55 | realtimeReflectionProbes: 0 56 | billboardsFaceCameraPosition: 0 57 | vSyncCount: 0 58 | lodBias: 0.4 59 | maximumLODLevel: 0 60 | particleRaycastBudget: 16 61 | asyncUploadTimeSlice: 2 62 | asyncUploadBufferSize: 4 63 | resolutionScalingFixedDPIFactor: 1 64 | excludedTargetPlatforms: [] 65 | - serializedVersion: 2 66 | name: Medium 67 | pixelLightCount: 1 68 | shadows: 1 69 | shadowResolution: 0 70 | shadowProjection: 1 71 | shadowCascades: 1 72 | shadowDistance: 20 73 | shadowNearPlaneOffset: 3 74 | shadowCascade2Split: 0.33333334 75 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 76 | shadowmaskMode: 0 77 | blendWeights: 2 78 | textureQuality: 0 79 | anisotropicTextures: 1 80 | antiAliasing: 0 81 | softParticles: 0 82 | softVegetation: 0 83 | realtimeReflectionProbes: 0 84 | billboardsFaceCameraPosition: 0 85 | vSyncCount: 1 86 | lodBias: 0.7 87 | maximumLODLevel: 0 88 | particleRaycastBudget: 64 89 | asyncUploadTimeSlice: 2 90 | asyncUploadBufferSize: 4 91 | resolutionScalingFixedDPIFactor: 1 92 | excludedTargetPlatforms: [] 93 | - serializedVersion: 2 94 | name: High 95 | pixelLightCount: 2 96 | shadows: 2 97 | shadowResolution: 1 98 | shadowProjection: 1 99 | shadowCascades: 2 100 | shadowDistance: 40 101 | shadowNearPlaneOffset: 3 102 | shadowCascade2Split: 0.33333334 103 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 104 | shadowmaskMode: 1 105 | blendWeights: 2 106 | textureQuality: 0 107 | anisotropicTextures: 1 108 | antiAliasing: 0 109 | softParticles: 0 110 | softVegetation: 1 111 | realtimeReflectionProbes: 1 112 | billboardsFaceCameraPosition: 1 113 | vSyncCount: 1 114 | lodBias: 1 115 | maximumLODLevel: 0 116 | particleRaycastBudget: 256 117 | asyncUploadTimeSlice: 2 118 | asyncUploadBufferSize: 4 119 | resolutionScalingFixedDPIFactor: 1 120 | excludedTargetPlatforms: [] 121 | - serializedVersion: 2 122 | name: Very High 123 | pixelLightCount: 3 124 | shadows: 2 125 | shadowResolution: 2 126 | shadowProjection: 1 127 | shadowCascades: 2 128 | shadowDistance: 70 129 | shadowNearPlaneOffset: 3 130 | shadowCascade2Split: 0.33333334 131 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 132 | shadowmaskMode: 1 133 | blendWeights: 4 134 | textureQuality: 0 135 | anisotropicTextures: 2 136 | antiAliasing: 2 137 | softParticles: 1 138 | softVegetation: 1 139 | realtimeReflectionProbes: 1 140 | billboardsFaceCameraPosition: 1 141 | vSyncCount: 1 142 | lodBias: 1.5 143 | maximumLODLevel: 0 144 | particleRaycastBudget: 1024 145 | asyncUploadTimeSlice: 2 146 | asyncUploadBufferSize: 4 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Ultra 151 | pixelLightCount: 4 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 4 156 | shadowDistance: 150 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | blendWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 2 171 | maximumLODLevel: 0 172 | particleRaycastBudget: 4096 173 | asyncUploadTimeSlice: 2 174 | asyncUploadBufferSize: 4 175 | resolutionScalingFixedDPIFactor: 1 176 | excludedTargetPlatforms: [] 177 | m_PerPlatformDefaultQuality: 178 | Android: 2 179 | Nintendo 3DS: 5 180 | Nintendo Switch: 5 181 | PS4: 5 182 | PSM: 5 183 | PSP2: 2 184 | Standalone: 5 185 | Tizen: 2 186 | WebGL: 3 187 | WiiU: 5 188 | Windows Store Apps: 5 189 | XboxOne: 5 190 | iPhone: 2 191 | tvOS: 2 192 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 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 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | m_Enabled: 0 7 | m_TestMode: 0 8 | m_TestEventUrl: 9 | m_TestConfigUrl: 10 | m_TestInitMode: 0 11 | CrashReportingSettings: 12 | m_EventUrl: https://perf-events.cloud.unity3d.com/api/events/crashes 13 | m_NativeEventUrl: https://perf-events.cloud.unity3d.com/symbolicate 14 | m_Enabled: 0 15 | m_CaptureEditorExceptions: 1 16 | UnityPurchasingSettings: 17 | m_Enabled: 0 18 | m_TestMode: 0 19 | UnityAnalyticsSettings: 20 | m_Enabled: 1 21 | m_InitializeOnStartup: 1 22 | m_TestMode: 0 23 | m_TestEventUrl: 24 | m_TestConfigUrl: 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Real-time and Preprocessed Audio Analysis for Onset Detection (Beat Mapping) Using Spectral Flux 2 | 3 | ## Description 4 | 5 | This code sample demonstrates the topics outlined in my article series "Algorithmic Beat Mapping in Unity" 6 | https://medium.com/giant-scam/algorithmic-beat-mapping-in-unity-intro-d4c2c25d2f27 7 | 8 | This is a minimal example of the foundation for detecting beats in audio files in Unity. Audio analysis is available for real-time audio as well as preprocessing an entire audio file up front. 9 | Both analysis methods use the same spectral flux algorithm that is outlined in this article: 10 | http://www.badlogicgames.com/wordpress/?cat=18&paged=3 11 | 12 | ## Usage 13 | 14 | This code sample was tested using Unity 2017.3.0f3. It should be compatible with Unity 5 as well. 15 | 16 | In the Hierarchy, select `SongController` and enable/disable `Real Time Samples` and `Pre Process Samples`. All combinations of the two are valid. 17 | Load an audio file into the `SongController->AudioSource`. 18 | Press `Play`. 19 | You should hear the audio being played and see the output of the algorithm in the two `Plot` objects on screen. 20 | 21 | 22 | ## License 23 | 24 | All code samples besides DSPLib.cs and Complex.cs are covered by the MIT license. See those source files for information about their external licenses. 25 | Example audio file "Chamber of Secrets for 1" by Terror Pigeon is Copyright Terror Pigeon and, while it may be distributed with this project, it may not be further distributed or used without consent. 26 | 27 | 28 | ## Author 29 | 30 | All code samples besides DSPLib.cs and Complex.cs were written by Jesse Keogh. Jesse Keogh is the Lead Developer / Co-Founder of Giant Scam Industries. 31 | https://twitter.com/giantscam 32 | -------------------------------------------------------------------------------- /UnityPackageManager/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | } 4 | } 5 | --------------------------------------------------------------------------------