Exemplo n.º 1
0
 public void Stop()
 {
     SyncObject.Invoke((MethodInvoker)(() => Timer.Stop()));
     SoundManager.StopAll();
     Playing = false;
     Finished?.Invoke(this, EventArgs.Empty);
 }
Exemplo n.º 2
0
        public bool Start(SoundSource music, int startTick, HashSet <int> ticks, IEnumerable <BPMChangeEvent> bpms)
        {
            if (Playing)
            {
                throw new InvalidOperationException();
            }
            if (music == null)
            {
                throw new ArgumentNullException("music");
            }
            if (IsStopAtLastNote && ticks.Count == 0)
            {
                return(false);
            }
            SoundManager.Register(ClapSource.FilePath);
            SoundManager.Register(music.FilePath);
            EndTick = IsStopAtLastNote ? ticks.Max() : GetTickFromTime(SoundManager.GetDuration(music.FilePath), bpms);
            if (EndTick < startTick)
            {
                return(false);
            }

            TickElement = new LinkedList <int>(ticks.Where(p => p >= startTick).OrderBy(p => p)).First;
            BPMElement  = new LinkedList <BPMChangeEvent>(bpms.OrderBy(p => p.Tick)).First;

            // スタート時まで進める
            while (TickElement != null && TickElement.Value < startTick)
            {
                TickElement = TickElement.Next;
            }
            while (BPMElement.Next != null && BPMElement.Next.Value.Tick <= startTick)
            {
                BPMElement = BPMElement.Next;
            }

            int clapLatencyTick = GetLatencyTick(ClapSource.Latency, (double)BPMElement.Value.BPM);

            InitialTick = startTick - clapLatencyTick;
            CurrentTick = InitialTick;
            StartTick   = startTick;

            TimeSpan startTime = GetTimeFromTick(startTick, bpms);
            TimeSpan headGap   = TimeSpan.FromSeconds(-music.Latency) - startTime;

            ElapsedTick = 0;
            Task.Run(() =>
            {
                LastSystemTick = Environment.TickCount;
                SyncObject.Invoke((MethodInvoker)(() => Timer.Start()));

                System.Threading.Thread.Sleep(TimeSpan.FromSeconds(Math.Max(ClapSource.Latency, 0)));
                if (headGap.TotalSeconds > 0)
                {
                    System.Threading.Thread.Sleep(headGap);
                }
                if (!Playing)
                {
                    return;           // 音源再生前に停止されたら取り消す
                }
                SoundManager.Play(music.FilePath, startTime + TimeSpan.FromSeconds(music.Latency));
            });

            Playing = true;
            return(true);
        }