Beispiel #1
0
 /// <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;
             }
         }
     }
 }
Beispiel #2
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);
        }