Ejemplo n.º 1
0
    /// <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
    }