/// 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); }
/// <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); }
// 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]); } } }
/// <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); }
/// 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; } }
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); } }
/// <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); }
/// <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); }
/// <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); }
/// 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); }