Exemplo n.º 1
0
        /// <summary>
        /// 이 클래스가 작동하기 위해서는
        /// Initialize()가 호출된 후에 반드시 호출되어야 합니다.
        /// </summary>
        public static void Start()
        {
            if (IsReady && !HasStart)
            {
                timerNumber = 0;
                timer       = new Timer(1, TickTimer);
                Accompaniment.Start();
                HasStart = true;
                ThemeChanged();

                new Test.SFXTest();   // Run some tests.
            }
        }
Exemplo n.º 2
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;
             }
         }
     }
 }
Exemplo n.º 3
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);
        }
Exemplo n.º 4
0
        /// <summary>
        /// 음악 출력 장치와 타이머를 초기화하고, 현재 음악 테마를 SFXThemeName으로 설정합니다.
        /// </summary>
        /// <param name="SFXThemeName">설정할 음악 테마 이름</param>
        /// <param name="noteResolution">단위 리듬</param>
        /// <param name="timerTickDelegates">타이머의 틱마다 추가로 실행할 메서드의 대리자 목록</param>
        public static void Initialize(string SFXThemeName, int noteResolution, Timer.TickDelegate[] timerTickDelegates = null)
        {
            IsReady  = false;
            HasStart = false;

            //outDevice = new OutputDevice(0);
            settings = new Settings();
            settings[ConfigurationKeys.SynthAudioChannels].IntValue = 2;

            syn = new Synth(settings);
            try
            {
                syn.LoadSoundFont("FluidR3_GM.sf2", true);
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e.StackTrace);
                return;
            }
            for (int i = 0; i < 16; i++)
            {
                syn.SoundFontSelect(i, 0);
            }

            adriver = new AudioDriver(syn.Settings, syn);

            /*
             * WaveInEvent recorder = new WaveInEvent
             * {
             *  WaveFormat = new WaveFormat(44100, 2)
             * };
             * BufferedWaveProvider sound = new BufferedWaveProvider(recorder.WaveFormat);
             * recorder.DataAvailable += (object sender, WaveInEventArgs e) =>
             * {
             *  sound.AddSamples(e.Buffer, 0, e.BytesRecorded);
             * };
             * recorder.StartRecording();
             * //sound.Read();
             */
            //playback = new WaveOutEvent();
            //playback.Init(sound);
            //playback.Play();

            /*
             * sound = new BufferedWaveProvider(new WaveFormat(44100, 2));
             * buffer = new byte[44100 * 4];
             * stream = new MemoryStream();
             * Task.Run(() => {
             *  soundStream = new RawSourceWaveStream(stream, new WaveFormat(44100, 2));
             *  reverb = new DmoEffectWaveProvider<DmoWavesReverb, DmoWavesReverb.Params>(soundStream);
             *  outputDevice = new WasapiOut();
             *
             *  outputDevice.Init(reverb);
             *  outputDevice.Play();
             * });
             */
            SFXTheme.CurrentSFXTheme = SFXTheme.FindSFXTheme(SFXThemeName);
            //Console.WriteLine(SFXThemeName + " " + SFXTheme.CurrentSFXTheme.Name);
            NoteResolution = noteResolution;
            Accompaniment.Initialize();

            tickDelegate += Tick;
            if (timerTickDelegates != null)
            {
                foreach (Timer.TickDelegate t in timerTickDelegates)
                {
                    tickDelegate += t;
                }
            }

            mgmt = new PowerManagement();
            mgmt.InitPowerEvents();
            mgmt.OnPowerSuspend += Suspend;
            mgmt.OnPowerResume  += Resume;

            syncPlayBuffer       = new List <Note>();
            syncTransitionBuffer = false;
            playPitchEventBuffer = new List <int>();

            accompanimentTickNumber = new Dictionary <int, int>();
            accompanimentPlayNumber = new Dictionary <int, int>();
            accompanimentTickNumber.Add(7, 0);
            accompanimentTickNumber.Add(8, 0);
            accompanimentPlayNumber.Add(7, 0);
            accompanimentPlayNumber.Add(8, 0);

            IsReady = true;

            /*
             * Task.Run(() =>
             * {
             *  var capture = new WasapiLoopbackCapture();
             *  var effectProvider = new DmoEffectWaveProvider<DmoWavesReverb, DmoWavesReverb.Params>(new WaveInProvider(capture));
             *
             *  PlayEffectorSound(capture, effectProvider);
             *  using (var outputDevice = new WasapiOut())
             *  {
             *      outputDevice.Init(effectProvider);
             *      capture.StartRecording();
             *      outputDevice.Play();
             *      while (capture.CaptureState != NAudio.CoreAudioApi.CaptureState.Stopped)
             *      {
             *          Thread.Sleep(500);
             *          if (!IsReady) capture.StopRecording();
             *      }
             *      Console.WriteLine("Effector stopped");
             *  }
             *
             * });
             */
        }