/// <summary> /// Initializes the static class. /// Loads the music, analyzes the music, stores useful information about it. /// THIS FUNCTION WILL ANALYZE MUSIC UNLESS IT FINDS A CACHE FILE! /// (analysis takes ages!) /// </summary> /// <param name='pathToMusicFile'> /// Path to music file. /// </param> public static IEnumerator initMusic(string pathToMusicFile) { // Set flags songLoaded = false; tagDataSet = false; abortSoundProcessing = false; isWritingCacheFile = false; loadingProgress = 0; #if UNITY_WEBPLAYER // For the WebPlayer: Just get everything from WebPlayerRytData.cs peaks = WebPlayerRytData.getPeaks(Game.Song); loudPartTimeStamps = WebPlayerRytData.getLoudFlags(Game.Song); variationFactor = WebPlayerRytData.getVariationFactor(Game.Song); songLoaded = true; currentlyLoadedSong = "xXBACKgroundMUSICXx"; yield break; #else // For Tutorial: Just get everything from TutorialRytData.cs if(Game.GameMode == Game.Mode.Tutorial) { peaks = TutorialRytData.getPeaks(); loudPartTimeStamps = TutorialRytData.getLoudFlags(); variationFactor = TutorialRytData.getVariationFactor(); audioLength = 213.883f; frequency = 44100; channels = 2; songLoaded = true; currentlyLoadedSong = "xXBACKgroundMUSICXx"; tagDataSet = true; yield break; } // Initialize file handle float start = Time.realtimeSinceStartup; if(freader!=null) { freader.close(); freader = null; } freader = new FileReader (pathToMusicFile); FileReader.ReadStatus success = freader.read (); // Doesn't really "read" (unless it's a WAV file) while (freader.isReading()) { yield return null; } // Succeeded reading? (Which means it found the file when we're just streaming) if (success != FileReader.ReadStatus.SUCCESS) { yield break; } // Set useful information, like AudioClip,length,etc.. frequency = freader.getFrequency (); channels = freader.getChannels (); audioLength = freader.getAudioLengthInSecs (); currentlyLoadedSong = pathToMusicFile; artist = freader.getArtist(); title = freader.getTitle(); tagDataSet = true; start = Time.realtimeSinceStartup; // Check if we have a cache file of the analyzed data for the current song string cacheFile = FileWriter.convertToCacheFileName (pathToMusicFile); System.IO.FileInfo cachedRytData = new System.IO.FileInfo (cacheFile); if (cachedRytData.Exists) { // We have a cache file, so we just read the peaks etc from there. FileReader rytFile = new FileReader (cacheFile); success = rytFile.read (); while (rytFile.isReading()) { yield return 0; } if (success != FileReader.ReadStatus.SUCCESS) { yield break; } peaks = rytFile.getPeaks (); loudPartTimeStamps = rytFile.getLoudnessData (); variationFactor = rytFile.getVariationFactor(); rytFile.close (); rytFile = null; } else { // We have no cache file, so do the actual analysis! soundProcessingThread = new System.Threading.Thread(() => SoundProcessor.analyse(freader)); soundProcessingThread.Start(); while(SoundProcessor.isAnalyzing) { loadingProgress = SoundProcessor.loadingProgress; if(abortSoundProcessing) { // ABORT: Cancel processing thread, release file handle & collect all dat garbage! SoundProcessor.abort(); soundProcessingThread.Join(); soundProcessingThread.Abort(); soundProcessingThread = null; SoundProcessor.reset(); freader.close(); freader = null; System.GC.Collect(); yield break; } yield return null; } isWritingCacheFile = true; SoundProcessor.reset(); soundProcessingThread.Join(); soundProcessingThread.Abort(); soundProcessingThread = null; peaks = SoundProcessor.getPeaks (); loudPartTimeStamps = SoundProcessor.getVolumeLevels (); variationFactor = SoundProcessor.getVariationFactor(); FileWriter.writeAnalysisData (pathToMusicFile, peaks, loudPartTimeStamps, variationFactor); isWritingCacheFile = false; } if(Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsEditor) { // Now that we have analyzed the song, we need to reset & initialize everything for playback freader.reset (); audioBufferSize = (int)(channels * Mathf.Ceil (audioLength) * frequency); audioClip = AudioClip.Create ("main_music1", audioBufferSize, channels, frequency, false, false); // Fill audio buffer with the first few samples initAudioBuffer (); } closeMusicStream(); Debug.Log ("Song loaded in: " + (Time.realtimeSinceStartup - start) + " seconds"); songLoaded = true; // Done a lot of work there, better clean up after ourselves! System.GC.Collect(); #endif }