Ejemplo n.º 1
0
        /// loads all available presets from the the streaming assets and persisten data paths.
        public IEnumerator LoadPresets()
        {
            if (System.IO.Directory.Exists(Application.persistentDataPath + "/MusicGenerator/InstrumentClips"))
            {
                foreach (string filename in System.IO.Directory.GetFiles(Application.persistentDataPath + "/MusicGenerator/InstrumentClips"))
                {
                    if (filename.Contains(".meta") == false && filename.Contains("presets") == false)
                    {
                        AddPresetOption(Path.GetFileName(filename));
                    }
                }
            }

            string data = null;

            yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentClips/presets.txt", (x) => { data = x.downloadHandler.text; }));

            List <string> presetFileNames = new List <string>(data.Split(','));

            if (presetFileNames != null)
            {
                for (int i = 0; i < presetFileNames.Count; i++)
                {
                    AddPresetOption(presetFileNames[i]);
                }
            }
            yield return(StartCoroutine(StageMobileClipForPlaying()));
        }
        private IEnumerator AddPresets()
        {
            if (System.IO.Directory.Exists(Application.persistentDataPath + "/MusicGenerator/InstrumentSaves"))
            {
                foreach (string folder in System.IO.Directory.GetDirectories(Application.persistentDataPath + "/MusicGenerator/InstrumentSaves"))
                {
                    if (mPresetFileNames.Contains(name) == false)
                    {
                        mPresetFileNames.Add(name);
                    }
                }
            }
            string data = null;

            yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/presets.txt", (x) => { data = x.downloadHandler.text; }));

            mPresetFileNames = new List <string>(data.Split(','));
            if (mPresetFileNames != null)
            {
                for (int i = 0; i < mPresetFileNames.Count; i++)
                {
                    mStaffPlayerUI.AddPresetOption(mPresetFileNames[i]);
                }
            }

            yield return(null);
        }
        /// <summary>
        /// Returns true if this note should be avoided in pentatonic scales.
        /// </summary>
        /// <param name="noteIN"></param>
        /// <returns></returns>
        private bool IsPentatonicAvoid(int noteIN)
        {
            int note            = MusicHelpers.SafeLoop(noteIN - 1, Instrument.mScaleLength);
            int progressionstep = mInstrument.mCurrentProgressionStep < 0 ? mInstrument.mCurrentProgressionStep * -1 : mInstrument.mCurrentProgressionStep;

            // currently does not respect modal changes and avoids the interval instead. add mMusicGenerator.mGeneratorData.mMode to change with modes
            int scaleNote = MusicHelpers.SafeLoop(note + progressionstep, Instrument.mScaleLength);

            if (mIsStandardPentatonic)
            {
                if (mMusicGenerator.mGeneratorData.mScale == eScale.Major || mMusicGenerator.mGeneratorData.mScale == eScale.HarmonicMajor)
                {
                    return(scaleNote == mMajorPentatonicAvoid[0] || scaleNote == mMajorPentatonicAvoid[1]);
                }
                else if (mMusicGenerator.mGeneratorData.mScale == eScale.NatMinor ||
                         mMusicGenerator.mGeneratorData.mScale == eScale.HarmonicMinor ||
                         mMusicGenerator.mGeneratorData.mScale == eScale.mMelodicMinor)
                {
                    return(scaleNote == mMinorPentatonicAvoid[0] || scaleNote == mMinorPentatonicAvoid[1]);
                }
            }
            else
            {
                return((mAvoidNotes[0] > 0 && scaleNote == mAvoidNotes[0]) || (mAvoidNotes[1] > 0 && scaleNote == mAvoidNotes[1]));
            }
            return(false);
        }
        /// <summary>
        /// Loads our instrument set data
        /// </summary>
        /// <param name="pathIN"></param>
        /// <returns></returns>
        public static IEnumerator LoadData(string pathIN, System.Action <InstrumentSetData> callback)
        {
            string data = null;

            yield return(MusicHelpers.GetUWR(MusicFileConfig.mSavesPath + "/" + pathIN + "/InstrumentSetData.txt", (x) => { data = x.downloadHandler.text; }));

            InstrumentSetData saveOUT = JsonUtility.FromJson <InstrumentSetData>(data);

            // Version check and update.
            if (saveOUT.mVersion == 0.0f)
            {
                string generatorData = null;
                yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/generator.txt", (x) => { generatorData = x.downloadHandler.text; }));

                GeneratorSave generatorSave = JsonUtility.FromJson <GeneratorSave>(generatorData);

                /// we need to grab these from the generatorSave as the variables belonged to that in the last version
                saveOUT                   = new InstrumentSetData();
                saveOUT.Tempo             = generatorSave.mTempo;
                saveOUT.RepeatMeasuresNum = generatorSave.mRepeatMeasuresNum;
                saveOUT.mProgressionRate  = (eProgressionRate)generatorSave.mProgressionRate;
                saveOUT.mTimeSignature    = generatorSave.mTimeSignature;
            }
            callback(saveOUT);
            yield return(null);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///  Loads chord progression data from JSON
        /// </summary>
        /// <param name="pathIN"></param>
        /// <returns></returns>
        public static IEnumerator LoadData(string pathIN, System.Action <ChordProgressionData> callback)
        {
            string data = null;

            yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/ChordProgressionData.txt", (x) => { data = x.downloadHandler.text; }));

            ChordProgressionData saveOUT = JsonUtility.FromJson <ChordProgressionData>(data);

            if (saveOUT.mVersion == 0.0f)
            {
                string generatorData = null;
                yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/generator.txt", (x) => { generatorData = x.downloadHandler.text; }));

                GeneratorSave generatorSave = JsonUtility.FromJson <GeneratorSave>(generatorData);
                /// we need to grab these from the generatorSave as the variables belonged to that in the last version
                saveOUT = new ChordProgressionData();
                saveOUT.DominantInfluence    = generatorSave.mDominantInfluence;
                saveOUT.mExcludedProgSteps   = generatorSave.mExcludedProgSteps.ToArray();
                saveOUT.SubdominantInfluence = generatorSave.mSubdominantInfluence;
                saveOUT.TonicInfluence       = generatorSave.mTonicInfluence;
                saveOUT.TritoneSubInfluence  = generatorSave.mTritoneSubInfluence;
            }

            callback(saveOUT);
            yield return(null);
        }
Ejemplo n.º 6
0
        // Update is called once per frame
        void Update()
        {
            if (mMusicGenerator == null)
            {
                return;
            }
            if (mFileCurrentlyWriting != "")
            {
                bool completed = MusicHelpers.CheckClipwriteComplete(mFileCurrentlyWriting);
                if (completed)
                {
                    Debug.Log(mFileCurrentlyWriting + " clip save complete");
                    AddPresetOption(mFileCurrentlyWriting + ".txt");
                    mFileCurrentlyWriting   = "";
                    mPlayClipDropdown.value = mPlayClipDropdown.options.Count - 1;
                }
            }

            else if (mMusicGenerator.mState >= eGeneratorState.editorInitializing)
            {
                InstrumentSet instrumentSet = mLoadedClip.mInstrumentSet;
                instrumentSet.mData.Tempo = mTempo.value;
                mCurrentInstSet.mData.RepeatMeasuresNum = mNumberOfMeasures.value;
                mCurrentInstSet.mRepeatCount            = mCurrentMeasure.value;
                if (mInstrumentPanel.mInstrument != null)
                {
                    int currentInstIndex = (int)mInstrumentPanel.mInstrument.InstrumentIndex;
                    mStaffPlayer.SetEditorNotes(instrumentSet.mInstruments[currentInstIndex]);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Loads the data for an instrument.
        /// </summary>
        /// <param name="resourceDirectory"></param>
        private IEnumerator LoadInstrumentsData(string argDirectory, bool async = false)
        {
            UnitySystemConsoleRedirector.Redirect();
            InstrumentSet set = MusicGenerator.Instance.mInstrumentSet;

            for (int i = 0; i < MusicGenerator.mMaxInstruments; i++)
            {
                string path = "/instruments" + i.ToString() + ".txt";

                string data = null;
                yield return(MusicHelpers.GetUWR(mSavesPath + "/" + argDirectory + path, (x) => { data = x.downloadHandler.text; }));

                if (string.IsNullOrEmpty(data))
                {
                    yield break;
                }

                InstrumentData instrumentData = null;
                InstrumentData.LoadData(data, argDirectory, (x) => { instrumentData = x; });
                MusicGenerator.Instance.AddInstrument(set);
                set.mInstruments[set.mInstruments.Count - 1].LoadInstrument(instrumentData);
                int index = 0;
                if (async)
                {
                    yield return(StartCoroutine(MusicGenerator.Instance.AsyncLoadBaseClips(set.mInstruments[set.mInstruments.Count - 1].mData.InstrumentType, ((x) => { index = x; }))));
                }
                else
                {
                    index = MusicGenerator.Instance.LoadBaseClips(set.mInstruments[set.mInstruments.Count - 1].mData.InstrumentType);
                }
                set.mInstruments[set.mInstruments.Count - 1].InstrumentTypeIndex = index;
            }
            yield return(null);
        }
Ejemplo n.º 8
0
        /// Sets our lead avoid notes from data.
        public void SetLeadAvoidNotes()
        {
            int avoid1 = mInstrument.mData.mLeadAvoidNotes[0] >= 0 ? MusicHelpers.SafeLoop(mInstrument.mData.mLeadAvoidNotes[0] + 1, 7) : -1;
            int avoid2 = mInstrument.mData.mLeadAvoidNotes[1] >= 0 ? MusicHelpers.SafeLoop(mInstrument.mData.mLeadAvoidNotes[1] + 1, 7) : -1;

            for (int i = 0; i < mLeadAvoidSteps.Length; i++)
            {
                mLeadAvoidSteps[i].isOn = i == avoid1 || i == avoid2 ? true : false;
            }
        }
Ejemplo n.º 9
0
        public static void CreatePrefabsFromClips()
        {
            string generatorPath = MusicHelpers.GetMusicGeneratorPath();

            if (Directory.Exists(generatorPath + "/Assets/Resources/Music/") == false)
            {
                return;
            }

            string[] pathName = Directory.GetDirectories(generatorPath + "/Assets/Resources/Music/");

            for (int i = 0; i < pathName.Length; i++)
            {
                pathName[i] = Path.GetFileName(pathName[i]);
            }

            List <List <List <AudioClip> > > mAllClips = new List <List <List <AudioClip> > >();
            int numNotes = 37;

            for (int j = 0; j < pathName.Length; j++)
            {
                mAllClips.Add(new List <List <AudioClip> >());
                mAllClips[mAllClips.Count - 1].Add(new List <AudioClip>());
                GameObject go = new GameObject();
                go.name = pathName[j];
                InstrumentPrefabList instrumentList = go.AddComponent <InstrumentPrefabList>();

                for (int i = 1; i < numNotes; i++)
                {
                    string clipPath = generatorPath + "MusicGenerator/Assets/Resources/Music/" + pathName[j] + "/" + i.ToString();

                    string assetPath = "Assets/MusicGenerator/Assets/Resources/Music/" + pathName[j] + "/" + i.ToString();;

                    AudioClip clip = Resources.Load("Music/" + pathName[j] + "/" + (i).ToString()) as AudioClip;
                    if (clip)
                    {
                        mAllClips[j][mAllClips[j].Count - 1].Add(clip);
                        AudioSource source = instrumentList.gameObject.AddComponent <AudioSource>();
                        source.clip = clip;
                        instrumentList.mAudioSources[i - 1] = (source);
                        if (File.Exists(clipPath + ".mp3"))
                        {
                            AssetImporter.GetAtPath(assetPath + ".mp3").assetBundleName = go.name;
                        }
                    }
                }

                PrefabBuilder.CreatePrefab(go);
                UnityEngine.Object.DestroyImmediate(go);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Loads a clip configuration.
        /// </summary>
        /// <param name="fileNameIN"></param>
        /// <returns></returns>
        public IEnumerator LoadClipConfigurations(string argFileName, System.Action <ClipSave> argCallback)
        {
            string clipSaveString = "";

            yield return(StartCoroutine(MusicHelpers.GetUWR(mClipsPath + "/" + argFileName, (x) => { clipSaveString = x.downloadHandler.text; })));

            ClipSave clipSave = JsonUtility.FromJson <ClipSave>(clipSaveString);

            if (clipSave == null)
            {
                throw new ArgumentNullException("clipSave was null");
            }

            argCallback(clipSave);
            yield return(null);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// loads the tooltips:
        /// </summary>
        /// <returns></returns>
        public static IEnumerator LoadTooltips(System.Action <TooltipSave> callback)
        {
            string tooltipsString = "";

            yield return(MusicHelpers.GetUWR(TOOLTIPS_PATH, (x) => { tooltipsString = x.downloadHandler.text; }, false));

            TooltipSave saveOUT = JsonUtility.FromJson <TooltipSave>(tooltipsString);

            if (saveOUT == null)
            {
                throw new ArgumentNullException("tooltip file was not sucessfully loaded");
            }

            callback(saveOUT);
            yield return(null);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Checks for out of range notes in our list and forces it back within range.
        /// </summary>
        private void CheckValidity()
        {
            if (mProgressionNotes.Length != mSeventhChord.Length)
            {
                throw new Exception("We haven't fully filled our note array. Something has gone wrong.");
            }

            for (int i = 0; i < mProgressionNotes.Length; i++)
            {
                int note          = mProgressionNotes[i];
                int clipArraySize = MusicGenerator.mMaxInstrumentNotes;

                if (note == mUnplayed || (note < clipArraySize && note >= mUnplayed))
                {
                    continue;
                }

                if (note < 0)
                {
                    note = MusicHelpers.SafeLoop(note, mOctave);
                }
                else if (note >= clipArraySize)
                {
                    note  = MusicHelpers.SafeLoop(note, mOctave);
                    note += (mData.mUsePattern && mbAreRepeatingPattern) ? mCurrentPatternOctave[i] * mOctave : 2 * mOctave;
                }

                /// if somehow this is still out of range, we've utterly broken things...
                if (note < 0 || note > clipArraySize)
                {
                    Debug.Log("something's gone wrong note is out of range.");
                    note = 0;
                }

                mProgressionNotes[i] = note;
            }
        }
        /// <summary>
        /// Returns true if this lead note is a half step above a chord note:
        /// </summary>
        /// <param name="noteIN"></param>
        /// <returns></returns>
        private bool IsAvoidNote(int noteIN)
        {
            if (IsPentatonicAvoid(noteIN))
            {
                return(true);
            }

            int note            = MusicHelpers.SafeLoop(noteIN - 1, Instrument.mScaleLength);
            int progressionstep = mInstrument.mCurrentProgressionStep < 0 ? mInstrument.mCurrentProgressionStep * -1 : mInstrument.mCurrentProgressionStep;
            int scaleNote       = MusicHelpers.SafeLoop(note + (int)mMusicGenerator.mGeneratorData.mMode + progressionstep, Instrument.mScaleLength);

            int[] scale = Instrument.mMusicScales[(int)mMusicGenerator.mGeneratorData.mScale];

            bool isHalfStep = scale[scaleNote] == Instrument.mHalfStep;

            bool isAboveChordNode = (note == Instrument.mSeventhChord[0] ||
                                     note == Instrument.mSeventhChord[1] ||
                                     note == Instrument.mSeventhChord[2] ||
                                     (note == Instrument.mSeventhChord[3] && mInstrument.mData.ChordSize == Instrument.mSeventhChord.Length));

            bool isSeventh = (mInstrument.mData.ChordSize != Instrument.mSeventhChord.Length && note == Instrument.mSeventhChord[3] - 1);

            return((isHalfStep && isAboveChordNode) || isSeventh);
        }
        /// Updates the Generator UI Panel:
        /// Sets the MusicGenerator() values, based on UI values.
        void Update()
        {
            if (mMusicGenerator == null || mMusicGenerator.mState < eGeneratorState.ready)
            {
                return;
            }

            /// Check to see if we're in the process of saving a new config and adds preset when it's finihsed.
            if (mFileCurrentlyWriting != "")
            {
                bool completed = MusicHelpers.CheckConfigWriteComplete(mFileCurrentlyWriting);
                if (completed)
                {
                    Debug.Log(mFileCurrentlyWriting + " save complete");
                    mStaffPlayerUI.AddPresetOption(mFileCurrentlyWriting);
                    mFileCurrentlyWriting = "";
                }
            }

            /// update our generator values from UI sliders, dropdowns, etc:
            if (mMusicGenerator.mVolumeState == eVolumeState.idle)
            {
                if (mMusicGenerator.mGeneratorData.mMasterVolume != mVol.value)
                {
                    mVolText.text = ((int)mVol.value).ToString();
                    mMusicGenerator.mGeneratorData.mMasterVolume = mVol.value;
                }
            }

            mMusicGenerator.mGeneratorData.mThemeRepeatOptions = (eThemeRepeatOptions)mRepeatThemeOptions.value;

            if (mMusicGenerator.mGeneratorData.mProgressionChangeOdds != mProgressionChangeOdds.value)
            {
                mMusicGenerator.mGeneratorData.mProgressionChangeOdds = mProgressionChangeOdds.value;
                mProgressionChangeOutput.text = ((int)mMusicGenerator.mGeneratorData.mProgressionChangeOdds).ToString();
            }

            if (mMusicGenerator.mState < eGeneratorState.editing)
            {
                if (mMusicGenerator.mInstrumentSet.mData.Tempo != mTempo.value)
                {
                    mMusicGenerator.mInstrumentSet.mData.Tempo = mTempo.value;
                    mTempoText.text = ((int)mTempo.value).ToString();
                }

                mMusicGenerator.mGeneratorData.mScale = (eScale)mScale.value;
                mMusicGenerator.mGeneratorData.mMode  = (eMode)mMode.value;
                mMusicGenerator.mGeneratorData.mKey   = (eKey)mKey.value;
            }
            else
            {
                if (mMusicGenerator.mInstrumentSet.mData.Tempo != mMeasureEditor.mTempo.value)
                {
                    mMusicGenerator.mInstrumentSet.mData.Tempo = mMeasureEditor.mTempo.value;
                    mTempoText.text = ((int)mTempo.value).ToString();
                }

                mMusicGenerator.mGeneratorData.mMode  = (eMode)mMeasureEditor.mMode.value;
                mMusicGenerator.mGeneratorData.mScale = (eScale)mMeasureEditor.mScale.value;
                mMusicGenerator.mGeneratorData.mKey   = (eKey)mMeasureEditor.mKey.value;
            }

            if (mMusicGenerator.mGeneratorData.mKeyChangeOdds != mKeyChangeOdds.value)
            {
                mMusicGenerator.mGeneratorData.mKeyChangeOdds = mKeyChangeOdds.value;
                mKeyChangeOddsOutput.text = ((int)mKeyChangeOdds.value).ToString();
            }

            if (mMusicGenerator.mGeneratorData.mGroupOdds[0] != mGroupOdds1.value)
            {
                mMusicGenerator.mGeneratorData.mGroupOdds[0] = mGroupOdds1.value;
                mGroupOdds1Text.text = ((int)mGroupOdds1.value).ToString();
            }

            if (mMusicGenerator.mGeneratorData.mGroupOdds[1] != mGroupOdds2.value)
            {
                mMusicGenerator.mGeneratorData.mGroupOdds[1] = mGroupOdds2.value;
                mGroupOdds2Text.text = ((int)mGroupOdds2.value).ToString();
            }
            if (mMusicGenerator.mGeneratorData.mGroupOdds[2] != mGroupOdds3.value)
            {
                mMusicGenerator.mGeneratorData.mGroupOdds[2] = mGroupOdds3.value;
                mGroupOdds3Text.text = ((int)mGroupOdds3.value).ToString();
            }
            if (mMusicGenerator.mGeneratorData.mGroupOdds[3] != mGroupOdds4.value)
            {
                mMusicGenerator.mGeneratorData.mGroupOdds[3] = mGroupOdds4.value;
                mGroupOdds4Text.text = ((int)mGroupOdds4.value).ToString();
            }

            mMusicGenerator.mInstrumentSet.mData.RepeatMeasuresNum = mRepeatLength.value + 1;

            if (mMusicGenerator.mGeneratorData.mSetThemeOdds != mNewThemeOdds.value)
            {
                mMusicGenerator.mGeneratorData.mSetThemeOdds = mNewThemeOdds.value;
                mNewThemeOutput.text = ((int)mMusicGenerator.mGeneratorData.mSetThemeOdds).ToString();
            }
            if (mMusicGenerator.mGeneratorData.mPlayThemeOdds != mRepeatThemeOdds.value)
            {
                mMusicGenerator.mGeneratorData.mPlayThemeOdds = mRepeatThemeOdds.value;
                mRepeatThemeOutput.text = ((int)mMusicGenerator.mGeneratorData.mPlayThemeOdds).ToString();
            }

            mMusicGenerator.mInstrumentSet.SetProgressionRate(mProgressionRateDropdown.value);
        }
Ejemplo n.º 15
0
        /// Updates data values from UI settings for lead avoid notes.
        public void UpdateLeadAvoidNotes()
        {
            if (mInstrument.mData.mSuccessionType != eSuccessionType.lead)
            {
                for (int i = 0; i < mLeadAvoidSteps.Length; i++)
                {
                    mInstrument.mData.mLeadAvoidNotes[0] = -1;
                    mInstrument.mData.mLeadAvoidNotes[1] = -1;
                }
                return;
            }

            int[] majorPent = NoteGenerator_Lead.mMajorPentatonicAvoid;
            int[] minorPent = NoteGenerator_Lead.mMinorPentatonicAvoid;

            // If our 'standard' pentatonic is enabled, force values to generic pentatonic.
            if (mPentatonic.isOn)
            {
                if (mMusicGenerator.mGeneratorData.mScale == eScale.Major || mMusicGenerator.mGeneratorData.mScale == eScale.HarmonicMajor)
                {
                    mInstrument.mData.mLeadAvoidNotes[0] = majorPent[0];
                    mInstrument.mData.mLeadAvoidNotes[1] = majorPent[1];
                    for (int i = 0; i < mLeadAvoidSteps.Length; i++)
                    {
                        bool isOn = i == majorPent[0] + 1 || i == majorPent[1] + 1 ? true : false;
                        mLeadAvoidSteps[i].isOn = isOn;
                    }
                }
                else if (mMusicGenerator.mGeneratorData.mScale == eScale.NatMinor ||
                         mMusicGenerator.mGeneratorData.mScale == eScale.HarmonicMinor ||
                         mMusicGenerator.mGeneratorData.mScale == eScale.mMelodicMinor)
                {
                    mInstrument.mData.mLeadAvoidNotes[0] = minorPent[0];
                    mInstrument.mData.mLeadAvoidNotes[1] = minorPent[1];
                    for (int i = 0; i < mLeadAvoidSteps.Length; i++)
                    {
                        mLeadAvoidSteps[i].isOn = i == minorPent[0] + 1 || i == minorPent[1] + 1 ? true : false;
                    }
                }
                else
                {
                    mPentatonic.isOn = false;
                }
                return;
            }

            int index = 0;

            mInstrument.mData.mLeadAvoidNotes[0] = -1;
            mInstrument.mData.mLeadAvoidNotes[1] = -1;

            // otherwise set custom avoid notes
            for (int i = 0; i < mLeadAvoidSteps.Length; i++)
            {
                if (mLeadAvoidSteps[i].isOn)
                {
                    if (index < 2)
                    {
                        mInstrument.mData.mLeadAvoidNotes[index] = MusicHelpers.SafeLoop(i - 1, 7);
                        index++;
                    }
                    else
                    {
                        mLeadAvoidSteps[i].isOn = false;
                    }
                }
            }
        }
        /// <summary>
        /// Loads our data
        /// </summary>
        /// <param name="pathIN"></param>
        /// <returns></returns>
        public static IEnumerator LoadData(string pathIN, System.Action <MusicGeneratorData> callback)
        {
            string data = null;

            yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/generator.txt", (x) => { data = x.downloadHandler.text; }));

            MusicGeneratorData generatorData = JsonUtility.FromJson <MusicGeneratorData>(data);

            // Version check and update.
            if (generatorData.mVersion != MusicGenerator.Version)
            {
                ChordProgressionData chordSave = new ChordProgressionData();
                string persistentDir           = MusicFileConfig.GetPersistentSaveDirectory(pathIN);

                // apply the needed changes for version 1.1. was null before.
                if (generatorData.mVersion == 0.0f)
                {
                    string generatorSaveData = null;
                    yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/generator.txt", (x) => { generatorSaveData = x.downloadHandler.text; }));

                    GeneratorSave generatorSave = JsonUtility.FromJson <GeneratorSave>(generatorSaveData);

                    generatorData.mDistortion         = new Pair_String_Float("MasterDistortion", generatorSave.mDistortion);
                    generatorData.mCenterFreq         = new Pair_String_Float("MasterCenterFrequency", generatorSave.mCenterFreq);
                    generatorData.mOctaveRange        = new Pair_String_Float("MasterOctaveRange", generatorSave.mOctaveRange);
                    generatorData.mFreqGain           = new Pair_String_Float("MasterFrequencyGain", generatorSave.mFreqGain);
                    generatorData.mLowpassCutoffFreq  = new Pair_String_Float("MasterLowpassCutoffFreq", generatorSave.mLowpassCutoffFreq);
                    generatorData.mLowpassResonance   = new Pair_String_Float("MasterLowpassResonance", generatorSave.mLowpassResonance);
                    generatorData.mHighpassCutoffFreq = new Pair_String_Float("MasterHighpassCutoffFreq", generatorSave.mHighpassCutoffFreq);
                    generatorData.mHighpassResonance  = new Pair_String_Float("MasterHighpassResonance", generatorSave.mHighpassResonance);
                    generatorData.mEchoDelay          = new Pair_String_Float("MasterEchoDelay", generatorSave.mEchoDelay);
                    generatorData.mEchoDecay          = new Pair_String_Float("MasterEchoDecay", generatorSave.mEchoDecay);
                    generatorData.mEchoDry            = new Pair_String_Float("MasterEchoDry", generatorSave.mEchoDry);
                    generatorData.mEchoWet            = new Pair_String_Float("MasterEchoWet", generatorSave.mEchoWet);
                    generatorData.mNumEchoChannels    = new Pair_String_Float("MasterNumEchoChannels", generatorSave.mNumEchoChannels);
                    generatorData.mReverb             = new Pair_String_Float("MasterReverb", generatorSave.mRever);
                    generatorData.mRoomSize           = new Pair_String_Float("MasterRoomSize", generatorSave.mRoomSize);
                    generatorData.mReverbDecay        = new Pair_String_Float("MasterReverbDecay", generatorSave.mReverbDecay);

                    generatorData.mGroupRate = (eGroupRate)generatorSave.mGroupRate;

                    // We also need to create a chord progression data object:
                    chordSave.mExcludedProgSteps   = generatorSave.mExcludedProgSteps.ToArray();
                    chordSave.SubdominantInfluence = generatorSave.mSubdominantInfluence;
                    chordSave.DominantInfluence    = generatorSave.mDominantInfluence;
                    chordSave.TonicInfluence       = generatorSave.mTonicInfluence;
                    chordSave.TritoneSubInfluence  = generatorSave.mTritoneSubInfluence;
                }
                else if (generatorData.mVersion == 1.1f)
                {
                    string generatorSaveData = null;
                    yield return(MusicHelpers.GetUWR("/MusicGenerator/InstrumentSaves/" + pathIN + "/generator.txt", (x) => { generatorSaveData = x.downloadHandler.text; }));

                    GeneratorSave generatorSave = JsonUtility.FromJson <GeneratorSave>(generatorSaveData);

                    generatorData.mGroupOdds.Clear();
                    for (int i = 0; i < generatorSave.mGroupOdds.Count; i++)
                    {
                        generatorData.mGroupOdds.Add(generatorSave.mGroupOdds[i]);
                    }
                }
            }

            callback(generatorData);
            yield return(null);
        }