void StartSection(MusicSection section, double time) { sectionCurrPieceIndex = 0; section.startTime = AudioSettings.dspTime; currSection = section; nextSection = null; AudioSource newMusicSource = musicSource2; musicSource2 = musicSource; musicSource = newMusicSource; newMusicSource.Stop(); newMusicSource.clip = clips[section.clipId]; newMusicSource.PlayScheduled(time); for (int i = 0; i < baseSegments.Count; i++) { LineSegment seg = baseSegments[i]; if (seg.piece.section == null || (seg.piece.section != currSection && seg.piece.section != nextSection)) { RecycleSegment(seg); baseSegments.RemoveAt(i); i--; continue; } } }
void UpdateSection(MusicSection section, float time) { if (section.nextUnloadedPiece < section.pieces.Count) { MusicPiece piece = section.pieces[section.nextUnloadedPiece]; if ((piece.startTime - time) < 10.0f) { section.nextUnloadedPiece++; LineSegment seg = NewSegment(); seg.piece = piece; seg.MakeArc(NoteToAngle(piece.noteArcFrom), NoteToAngle(piece.noteArcTo), (piece.endTime - piece.startTime) * scale); seg.UpdateMaterial(); if (section.currTail && piece.connected) { seg.transform.SetParent(section.currTail.transform); seg.transform.localPosition = section.currTail.end; section.currTail.next = seg; } else { seg.transform.SetParent(transform); UpdateApproachingSegment(seg); baseSegments.Add(seg); } section.currTail = seg; } } }
public override void DoEvent(LevelController cont) { if (cont.nextSection == null) { cont.sections.TryGetValue(possibilities[Random.Range(0, possibilities.Length)], out cont.nextSection); if (cont.nextSection != null) { MusicSection section = cont.nextSection; section.Reset(); } } }
void UpdateGameObjectNames() { for (int i = 0; i < musicSources_.Length; ++i) { AudioSource source = musicSources_[i]; if (source.clip != null) { source.gameObject.name = String.Format("{0}[{1}] Playing ({2:F2})", CurrentSection.Name, i, modeLayerVolumes_[i]); } else { source.gameObject.name = "_no track_"; } } MusicSection transitionSection = null; switch (TransitionState) { case ETransitionState.Synced: case ETransitionState.PreEntry: transitionSection = NextSection; break; case ETransitionState.PostEntry: transitionSection = PrevSection; break; } for (int i = 0; i < transitionMusicSources_.Length; ++i) { AudioSource transitionSource = transitionMusicSources_[i]; if (transitionSection != null && transitionSource.clip != null) { transitionSource.gameObject.name = String.Format("{0}[{1}] {2}", transitionSection.Name, i, TransitionState); } else { transitionSource.gameObject.name = "_no track_"; } } }
void Start() { _currentSection = 1; _currentMusicSection = MusicSection[0]; }
void ReadLevelData(string str) { string[] lines = str.Split('\n'); MusicSection currMusicSection = null; bool runsepFlag = false; float timeBase = 0; float timeScale = 1; foreach (string line in lines) { try { int firstSpaceIndex = line.IndexOf(' '); string key = firstSpaceIndex == -1 ? line : line.Substring(0, firstSpaceIndex); string value = firstSpaceIndex == -1 ? "" : line.Substring(firstSpaceIndex + 1); key = key.Trim(); value = value.Trim(); if (key == "section") { currMusicSection = new MusicSection(); currMusicSection.name = value; timeBase = 0; timeScale = 1; sections.Add(value, currMusicSection); } else if (key == "rebase") { string[] parts = value.Trim().Split(' '); float newBase = parts.Length >= 1 ? float.Parse(parts[0]) : 0; float newScale = parts.Length >= 2 ? (60 / float.Parse(parts[1])) : timeScale; timeBase = timeBase + (newBase * timeScale); timeScale = newScale; } else if (key == "transition") { currMusicSection.transitionTime = float.Parse(value) * timeScale + timeBase; } else if (key == "setnext") { MusicEventSetNext evt = new MusicEventSetNext(); string[] parts = value.Split(' '); evt.time = float.Parse(parts[0]) * timeScale + timeBase; evt.possibilities = parts[1].Split(','); currMusicSection.events.Add(evt); } else if (key == "play") { PlayEvent evt = new PlayEvent(); string[] parts = value.Split(' '); evt.time = float.Parse(parts[0]) * timeScale + timeBase; evt.index = int.Parse(parts[1]); currMusicSection.events.Add(evt); } else if (key == "clip") { currMusicSection.clipId = int.Parse(value); } else if (key == "run") { string[] parts = value.Split(','); int[] notes = new int[parts.Length - 1]; float[] noteTimes = new float[parts.Length]; int earliestNonzeroNote = 0; for (int i = 0; i < parts.Length - 1; i++) { string[] partparts = parts[i].Split(':'); notes[i] = int.Parse(partparts[0].Trim()); noteTimes[i] = timeBase + timeScale * float.Parse(partparts[1].Trim()); if (earliestNonzeroNote == 0 && notes[i] != 0) { earliestNonzeroNote = notes[i]; } } noteTimes[parts.Length - 1] = timeBase + timeScale * float.Parse(parts[parts.Length - 1].Trim()); MusicPiece lastPiece = currMusicSection.pieces.Count > 0 ? currMusicSection.pieces[currMusicSection.pieces.Count - 1] : null; MusicPiece joiner = null; if (lastPiece != null && !runsepFlag) { if (lastPiece.endTime >= noteTimes[0]) { joiner = lastPiece; } else { joiner = new MusicPiece(); joiner.section = currMusicSection; joiner.note = 0; joiner.startTime = lastPiece.endTime; joiner.endTime = noteTimes[0]; joiner.noteArcFrom = lastPiece.noteArcTo; joiner.noteArcTo = earliestNonzeroNote == 0 ? joiner.noteArcFrom : earliestNonzeroNote; joiner.isAttack = false; currMusicSection.pieces.Add(joiner); } } for (int i = 0; i < notes.Length; i++) { MusicPiece piece = new MusicPiece(); piece.section = currMusicSection; piece.isAttack = (i == 0); piece.isNote = true; piece.connected = joiner != null; piece.startTime = noteTimes[i]; piece.endTime = noteTimes[i + 1]; piece.note = notes[i]; if (piece.note != 0) { piece.noteArcFrom = piece.note; piece.noteArcTo = piece.note; } else { if (joiner != null) { piece.noteArcFrom = joiner.noteArcTo; } else if (earliestNonzeroNote != 0) { piece.noteArcFrom = earliestNonzeroNote; } else if (lastPiece != null) { piece.noteArcFrom = lastPiece.noteArcTo; } else { piece.noteArcFrom = 1; } if (i < notes.Length - 1 && notes[i + 1] > 0) { piece.noteArcTo = notes[i + 1]; } else { piece.noteArcTo = piece.noteArcFrom; } } currMusicSection.pieces.Add(piece); joiner = piece; } runsepFlag = false; } else if (key == "runsep") { runsepFlag = true; } } catch (System.Exception e) { Debug.Log(line); throw e; } } }
void DrawSection(SerializedProperty sectionProp, MusicSection section) { SerializedProperty nameProp = sectionProp.FindPropertyRelative("Name"); sectionProp.isExpanded = EditorGUILayout.Foldout(sectionProp.isExpanded, nameProp.stringValue); if (sectionProp.isExpanded) { EditorGUI.indentLevel++; // name EditorGUILayout.PropertyField(nameProp); // type SerializedProperty transitionTypeProp = sectionProp.FindPropertyRelative("TransitionType"); MusicSection.AutoTransitionType transitionType = (MusicSection.AutoTransitionType)transitionTypeProp.enumValueIndex; if (transitionType == MusicSection.AutoTransitionType.Transition) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PropertyField(transitionTypeProp, new GUIContent("Transition Type"), GUILayout.Width(EditorGUIUtility.labelWidth + 80)); SerializedProperty destinationProp = sectionProp.FindPropertyRelative("TransitionDestinationIndex"); destinationProp.intValue = EditorGUILayout.Popup(destinationProp.intValue, sectionListDisplayOptions_); EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.PropertyField(transitionTypeProp); } // clips SerializedProperty clipListProp = sectionProp.FindPropertyRelative("Clips"); clipListProp.arraySize = Mathf.Max(1, numTracksProperty_.intValue); for (int i = 0; i < clipListProp.arraySize; ++i) { EditorGUILayout.PropertyField(clipListProp.GetArrayElementAtIndex(i), new GUIContent("Track " + i.ToString())); } // meters SerializedProperty meterListProp = sectionProp.FindPropertyRelative("Meters"); meterListProp.isExpanded = EditorGUILayout.Foldout(meterListProp.isExpanded, "Meters " + (section != null && section.IsValid ? section.Meters[0].ToString() : "")); if (meterListProp.isExpanded) { EditorGUI.indentLevel++; meterListProp.arraySize = Mathf.Max(1, EditorGUILayout.IntField("Size", meterListProp.arraySize)); for (int i = 0; i < meterListProp.arraySize; ++i) { DrawMeter(meterListProp.GetArrayElementAtIndex(i)); } EditorGUI.indentLevel--; } // markers SerializedProperty markerListProp = sectionProp.FindPropertyRelative("Markers"); EditorGUILayout.PropertyField(markerListProp, includeChildren: true); // transition DrawSectionTransitionParam(sectionProp); // entry / exit / loop if (section != null && section.IsValid) { EditorGUILayout.PropertyField(sectionProp.FindPropertyRelative("EntryPointTiming")); EditorGUILayout.PropertyField(sectionProp.FindPropertyRelative("ExitPointTiming")); float minValue = section.EntryPointTiming.Bar; float maxValue = section.EntryPointTiming.Bar + section.ExitPointTiming.Bar; EditorGUILayout.MinMaxSlider(ref minValue, ref maxValue, 0, section.ClipEndTiming.Bar); if (transitionType == MusicSection.AutoTransitionType.Loop) { EditorGUILayout.PropertyField(sectionProp.FindPropertyRelative("LoopStartTiming")); EditorGUILayout.PropertyField(sectionProp.FindPropertyRelative("LoopEndTiming")); minValue = section.EntryPointTiming.Bar + section.LoopStartTiming.Bar; maxValue = section.EntryPointTiming.Bar + section.LoopEndTiming.Bar; EditorGUILayout.MinMaxSlider(ref minValue, ref maxValue, 0, section.ClipEndTiming.Bar); } } EditorGUI.indentLevel--; } }
void OnSectionChange(MusicSection section, int partIndex) { bool muted = m_musicCurrent.Player.IsSectionMuted(partIndex); m_renderer.material = muted ? matMute : matUnmute; }
void OnMuteSection(MusicSection section, bool muted) { // button should display the opposite of the current state. // so if it's paused, we show the 'resume' material m_renderer.material = muted ? matMute : matUnmute; }
void SetNextSection(SectionTransitionParam param) { // 遷移タイミング計算 MusicSection requestedSection = Sections[param.SectionIndex]; int entryPointSample = requestedSection.EntryPointSample; int currentSample = currentSample_; int syncPointSample = 0; if (FindSyncPoint(param.SyncType, param.SyncFactor, currentSample, entryPointSample, out syncPointSample) == false) { requenstedTransition_ = param; return; } // 遷移状態によって前のをキャンセルしたり switch (TransitionState) { case ETransitionState.Ready: // 準備OK break; case ETransitionState.Synced: // 前のをキャンセル CancelSyncedTransition(); break; case ETransitionState.Intro: case ETransitionState.PreEntry: case ETransitionState.PostEntry: case ETransitionState.Outro: // 遷移できないはずなんですが…… print("invalid transition state " + TransitionState); return; } // 波形終了予約 endScheduledDSPTime_ = 0.0; if (param.Transition.UseFadeOut == false) { if (param.SyncType == Music.SyncType.ExitPoint) { endScheduledDSPTime_ = AudioSettings.dspTime + (double)(musicSources_[0].clip.samples - currentSample) / sampleRate_;; } else { endScheduledDSPTime_ = AudioSettings.dspTime + (double)(syncPointSample - currentSample) / sampleRate_; } } // 遷移波形予約 syncScheduledDSPTime_ = AudioSettings.dspTime + (double)(syncPointSample - currentSample - entryPointSample) / sampleRate_; for (int i = 0; i < NumTracks; ++i) { if (i < requestedSection.Clips.Length) { transitionMusicSources_[i].clip = requestedSection.Clips[i]; transitionMusicSources_[i].timeSamples = 0; transitionMusicSources_[i].PlayScheduled(syncScheduledDSPTime_); } else { transitionMusicSources_[i].clip = null; } if (i < CurrentSection.Clips.Length && endScheduledDSPTime_ > 0) { musicSources_[i].SetScheduledEndTime(endScheduledDSPTime_); } } // 状態遷移 TransitionState = ETransitionState.Synced; nextSectionIndex_ = param.SectionIndex; requenstedTransition_ = null; executedTransition_ = param; // フェード時間計算 transitionFadeOutVolume_ = 1.0f; transitionFadeInVolume_ = 1.0f; if (param.Transition.UseFadeOut) { transitionFadeOut_.SetFade( (int)(param.Transition.FadeOutOffset * sampleRate_) + NextSection.EntryPointSample, (int)(param.Transition.FadeOutTime * sampleRate_)); } if (param.Transition.UseFadeIn) { transitionFadeInVolume_ = 0.0f; transitionFadeIn_.SetFade( (int)(param.Transition.FadeInOffset * sampleRate_), (int)(param.Transition.FadeInTime * sampleRate_)); } UpdateVolumes(); }
void OnSectionChange(MusicSection section, int partIndex) { m_text.text = partIndex + " -> " + section.name; }