/// <summary> /// 자동 반주의 상태를 초기화합니다. /// 이것을 호출하는 함수는 반드시 이 함수 호출을 "play"라는 lockName의 Util.TaskQueue 함수 안에서 수행해야 합니다. /// </summary> private static void ResetAccompaniment() { if (SFXTheme.IsReady) { for (int staff = 7; staff <= 8; staff++) { if (SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(staff)) { Accompaniment.SetNewCurrentPattern(staff); accompanimentPlayNumber[staff] = 0; accompanimentTickNumber[staff] = 0; } } } }
/// <summary> /// 리듬에 맞게 음표를 재생합니다. /// tickDelegate에 의해 1초에 32번씩 자동으로 호출됩니다. /// </summary> private static void Tick() { if (!HasStart) { return; } //Score.NoteOff(outDevice); Score.NoteOff(syn); void TickPlay(object[] args) { // 지속 효과음이 멈추는 것을 대비하여 if (SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(5) && SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(6)) { if (tickNumber % ((int)TICK_PER_SECOND * 10) == 0) { StopPlaying(5); SFXTheme.InstrumentInfo inst = SFXTheme.CurrentSFXTheme.Instruments[5]; Note note = new Note(inst.sfxPitchModulator(45), inst.sfxVolume, inst.sfxRhythm * 64 * 60, Measure, Position, 5); // 음표를 3840배 길게 늘여서 재생 //Score.PlayANoteForever(outDevice, note, (int)Math.Round(inst.sfxVolume * (SFXTheme.CurrentSFXTheme.Volume / 100D))); // 기본 빗소리 (사라지지 않아야 함) Score.PlayANote(syn, note, SFXTheme.CurrentSFXTheme.Volume / 100f); } if (tickNumber % ((int)TICK_PER_SECOND * 10) == (int)TICK_PER_SECOND * 5) { StopPlaying(6); SFXTheme.InstrumentInfo inst = SFXTheme.CurrentSFXTheme.Instruments[6]; Note note = new Note(inst.sfxPitchModulator(45), inst.sfxVolume, inst.sfxRhythm * 64 * 60, Measure, Position, 6); // 음표를 3840배 길게 늘여서 재생 //Score.PlayANoteForever(outDevice, note, (int)Math.Round(inst.sfxVolume * (SFXTheme.CurrentSFXTheme.Volume / 100D))); // 기본 빗소리 (사라지지 않아야 함) Score.PlayANote(syn, note, SFXTheme.CurrentSFXTheme.Volume / 100f); } } for (int staff = 7; staff <= 8; staff++) { if (SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(staff)) { if (accompanimentTickNumber[staff] >= Accompaniment.currentPatterns[staff].length) { accompanimentPlayNumber[staff]++; if (accompanimentPlayNumber[staff] >= Accompaniment.currentPatterns[staff].iteration) { Accompaniment.SetNewCurrentPattern(staff); accompanimentPlayNumber[staff] = 0; } else { Score.Play(Accompaniment.currentPatterns[staff].score, "Accompaniment", SFXTheme.CurrentSFXTheme.Instruments[staff].accompanimentVolume / 127f); } accompanimentTickNumber[staff] = 0; } Score accompaniment = Accompaniment.currentPatterns[staff].score; /* * // 64분음표 단위로 음을 하나씩 재생 * long measure = accompanimentTickNumber[staff] / 64; * int position = accompanimentTickNumber[staff] % 64; * if (SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(staff)) * { * accompaniment.PlayEnumerable(syn, measure, position, staff, * (int)Math.Round(SFXTheme.CurrentSFXTheme.Instruments[staff].accompanimentVolume * (SFXTheme.CurrentSFXTheme.Volume / 100D))); * * } */ accompanimentTickNumber[staff]++; } else { accompanimentTickNumber[staff] = 0; } } // 자동 반주 악보에 대해서만, 자동 반주가 꺼지면 음량이 0이 되도록 float volumeChanger(string scoreClassName) { switch (scoreClassName) { case "Accompaniment": float accompVolume = 1f; if (!SFXTheme.CurrentSFXTheme.hasAccompanied) { accompVolume = 0f; } return(SFXTheme.CurrentSFXTheme.Volume / 100f * accompVolume); default: return(SFXTheme.CurrentSFXTheme.Volume / 100f); } } // Play()로 재생 목록에 넣은 악보들을 재생 Score.PlayPerTick(syn, volumeChanger); } Util.TaskQueue.Add("play", TickPlay); if (tickNumber % 64 == 0 && (SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(7) || SFXTheme.CurrentSFXTheme.Instruments.ContainsKey(8)) && SFXTheme.CurrentSFXTheme.hasAccompanied) { syncTransitionBuffer = false; PlayChordTransition(); } else if (syncTransitionBuffer && tickNumber % 32 == 0) { syncTransitionBuffer = false; PlayChordTransition(); } // 동기화된 박자(최소 리듬 단위)에 맞춰 버퍼에 저장되어 있던 음표 재생 if (NoteResolution > 0 && tickNumber % NoteResolution == 0 && syncPlayBuffer.Count > 0) { FlushSyncPlayBuffer(); } //SoundPipeline(buffer); void IncreaseTick(object[] args) { tickNumber++; } Util.TaskQueue.Add("play", IncreaseTick); }