Пример #1
0
        void OnHasKeyFrame(BMSEvent bmsEvent)
        {
            if (!bmsEvent.IsNote || !bmsManager.GetAllAdoptedChannels().Contains(bmsEvent.data1))
            {
                return;
            }
            bool                isLongNote = bmsEvent.type == BMSEventType.LongNoteEnd || bmsEvent.type == BMSEventType.LongNoteStart, lnDown = false;
            TimeSpan            lnEndpos      = TimeSpan.Zero;
            QueuedLongNoteState queuedLNState = new QueuedLongNoteState();

            if (isLongNote)
            {
                queuedLongNoteState.TryGetValue(bmsEvent.data1, out queuedLNState);
                lnDown = queuedLNState.isNoteDown;
                queuedLNState.isNoteDown = !lnDown;
                if (!lnDown)
                {
                    queuedLNState.longNoteId++;
                    lnEndpos = bmsEvent.time2;
                }
                queuedLongNoteState[bmsEvent.data1] = queuedLNState;
            }
            GetChannelQueue(bmsEvent.data1).Enqueue(new KeyFrame {
                timePosition  = bmsEvent.time,
                channelId     = bmsEvent.data1,
                dataId        = (int)bmsEvent.data2,
                type          = isLongNote ? (lnDown ? NoteType.LongEnd : NoteType.LongStart) : NoteType.Normal,
                longNoteId    = queuedLNState.longNoteId,
                lnEndPosition = lnEndpos,
                sliceStart    = bmsEvent.sliceStart,
                sliceEnd      = bmsEvent.sliceEnd
            });
        }
Пример #2
0
 void OnPreEvent(BMSEvent bmsEvent)
 {
     if (OnPreNoteEvent != null)
     {
         OnPreNoteEvent.Invoke(bmsEvent);
     }
 }
Пример #3
0
        private void CalculateTimingPoints(List <BMSEvent> bmev)
        {
            BMSEvent referencePoint = DefaultReferencePoint;

            for (int i = 0, l = bmev.Count; i < l; i++)
            {
                BMSEvent ev = bmev[i];
                ev.time = TicksToTime(referencePoint, ev.ticks);
                switch (ev.type)
                {
                case BMSEventType.BPM:
                    if (referencePoint.data2 != ev.data2)
                    {
                        referencePoint = ev;
                    }
                    break;

                case BMSEventType.STOP:
                    referencePoint.time = TicksToTime(referencePoint, ev.ticks + (int)ev.data2);
                    ev.data2            = (referencePoint.time - ev.time).Ticks;
                    break;
                }
                bmev[i] = ev;
            }
        }
Пример #4
0
        protected int FindEventIndex(BMSEvent ev)
        {
            int firstIndex = bmsEvents.BinarySearchIndex(ev, BinarySearchMethod.FirstExact);
            int lastIndex  = bmsEvents.BinarySearchIndex(ev, BinarySearchMethod.LastExact, firstIndex);

            return(firstIndex == lastIndex ? firstIndex :
                   bmsEvents.IndexOf(ev, firstIndex, lastIndex - firstIndex + 1));
        }
Пример #5
0
 void OnPostMap(BMSEvent bmsEvent)
 {
     if (!bmsEvent.IsNote || !bmsManager.GetAllAdoptedChannels().Contains(bmsEvent.data1))
     {
         return;
     }
     HandleNoteEvent(bmsEvent.data1, false, false);
 }
Пример #6
0
        void OnEventUpdate(BMSEvent bmsEvent)
        {
            switch (bmsEvent.type)
            {
            case BMSEventType.WAV: PlayWAV((int)bmsEvent.data2, bmsEvent.sliceStart, bmsEvent.sliceEnd); break;

            case BMSEventType.BMP: ChangeBGA(bmsEvent.data1, (int)bmsEvent.data2); break;

            case BMSEventType.BeatReset:
                bpmBasePointBeatFlow = 0;
                bpmBasePoint         = timePosition;
                currentTimeSignature = (float)bmsEvent.Data2F;
                break;

            case BMSEventType.BPM:
                float newBpm = (float)bmsEvent.Data2F;
                bpmBasePointBeatFlow += (timePosition - bpmBasePoint).ToAccurateMinuteF() * bpm;
                bpmBasePoint          = timePosition;
                bpm = newBpm;
                CalculatePreOffset();
                if (OnChangeBPM != null)
                {
                    OnChangeBPM.Invoke(newBpm);
                }
                break;

            case BMSEventType.STOP:
                TimeSpan offset = new TimeSpan(bmsEvent.data2);
                stopPosition  = bmsEvent.time + offset;
                bpmBasePoint -= offset;
                break;

            default:
                if (!handledChannels.Contains(bmsEvent.data1))
                {
                    bool shouldPlayWav = true;
                    if (bmsEvent.type == BMSEventType.LongNoteEnd || bmsEvent.type == BMSEventType.LongNoteStart)
                    {
                        int lnState;
                        if (!autoPlayLNState.TryGetValue(bmsEvent.data1, out lnState))
                        {
                            lnState = 0;
                        }
                        shouldPlayWav = lnState != bmsEvent.data2;
                        autoPlayLNState[bmsEvent.data1] = lnState > 0 ? 0 : bmsEvent.data1;
                    }
                    if (shouldPlayWav)
                    {
                        PlayWAV((int)bmsEvent.data2, bmsEvent.sliceStart, bmsEvent.sliceEnd);
                    }
                }
                if (OnNoteEvent != null)
                {
                    OnNoteEvent.Invoke(bmsEvent);
                }
                break;
            }
        }
Пример #7
0
 protected int AddEvent(BMSEvent ev)
 {
     if (ev.IsNote)
     {
         allChannels.Add(ev.data1);
         maxCombos++;
     }
     return(bmsEvents.InsertInOrdered(ev));
 }
Пример #8
0
 private TimeSpan TicksToTime(BMSEvent referencePoint, int currentTicks)
 {
     return(referencePoint.time + new TimeSpan(
                (long)Math.Round(
                    (double)(currentTicks - referencePoint.ticks) / tickResoultion /
                    referencePoint.Data2F *
                    TimeSpan.TicksPerMinute
                    )
                ));
 }
Пример #9
0
 void NoteEvent(BMSEvent bmsEvent)
 {
     if (autoMode)
     {
         if (!bmsManager.GetAllAdoptedChannels().Contains(bmsEvent.data1))
         {
             return;
         }
         HandleNoteEvent(bmsEvent.data1, true, bmsEvent.type == BMSEventType.LongNoteStart || bmsEvent.type == BMSEventType.Note);
     }
 }
Пример #10
0
        protected void ReplaceEvent(int index, BMSEvent newEv)
        {
            BMSEvent original = bmsEvents[index];

            if (original.CompareTo(newEv) == 0)
            {
                bmsEvents[index] = newEv;
                return;
            }
            bmsEvents.RemoveAt(index);
            bmsEvents.InsertInOrdered(newEv);
        }
Пример #11
0
 // Insert beat reset after 1 measure of time signature change event according to BMS specifications.
 private static void BeatResetFix(ExtendedSortedSet <BMSEvent> bmev)
 {
     BMSEvent[] beatResetEvents = bmev.Where(ev => ev.type == BMSEventType.BeatReset).ToArray();
     for (int i = 0, l = beatResetEvents.Length; i < l; i++)
     {
         BMSEvent currentEv = beatResetEvents[i];
         int      meas      = currentEv.measure;
         if (i == l - 1 || (beatResetEvents[i + 1].measure - meas > 1 &&
                            currentEv.Data2F != 1))
         {
             bmev.Add(new BMSEvent {
                 measure = meas + 1,
                 beat    = 0,
                 Data2F  = 1,
                 type    = BMSEventType.BeatReset
             }, InsertMode.OldFirst);
         }
     }
 }
Пример #12
0
        private TimeSpan CalculateTime(List <BMSEvent> bmev, int ticks)
        {
            int index = bmev.BinarySearchIndex(
                new BMSEvent {
                ticks = ticks
            },
                BinarySearchMethod.FloorClosest | BinarySearchMethod.LastExact,
                0, -1, TicksComparer.instance
                );

            BMSEvent lastReferencePoint = DefaultReferencePoint;
            TimeSpan stopOffset         = TimeSpan.Zero;

            while (index >= 0)
            {
                lastReferencePoint = bmev[index];
                bool found = false;
                switch (lastReferencePoint.type)
                {
                case BMSEventType.BPM:
                    lastReferencePoint.time += stopOffset;
                    found = true;
                    break;

                case BMSEventType.STOP:
                    stopOffset += new TimeSpan(lastReferencePoint.data2);
                    break;
                }
                if (found)
                {
                    break;
                }
                index--;
            }
            return(TicksToTime(lastReferencePoint, ticks));
        }
Пример #13
0
        private void PostProcessContent(ExtendedSortedSet <BMSEvent> bmev)
        {
            Dictionary <int, BMSEvent> lnMarker = new Dictionary <int, BMSEvent>();
            double   bpm = initialBPM, beatOffset = 0, beatPerMeas = 1;
            TimeSpan referenceTimePoint = TimeSpan.Zero;

            TimeSpan stopTimePoint = TimeSpan.Zero;
            float    stopMeasBeat  = 0;

            EnsureCapacity(bmev.Count + 1);

            AddEvent(new BMSEvent {
                measure = 0,
                beat    = 0,
                type    = BMSEventType.BPM,
                Data2F  = bpm
            });

            foreach (BMSEvent ev in bmev)
            {
                BMSEvent converted = new BMSEvent {
                    measure = ev.measure,
                    beat    = (float)(ev.beat * beatPerMeas),
                };
                if (ev.measure + ev.beat == stopMeasBeat)
                {
                    converted.time = stopTimePoint;
                }
                else
                {
                    converted.time = referenceTimePoint + MeasureBeatToTimeSpan(ev.measure + ev.beat - beatOffset, beatPerMeas, bpm);
                }
                switch (ev.type)
                {
                case BMSEventType.BPM:
                    double newBpm;
                    if (ev.data1 == 8 && TryGetResourceData(ResourceType.bpm, ev.data2, out BMSResourceData bpmData))    // Extended BPM
                    {
                        newBpm = Convert.ToDouble(bpmData.additionalData);
                    }
                    else if (ev.data1 == 3 && int.TryParse(Base36.Encode((int)ev.data2), NumberStyles.HexNumber, null, out int bpmInt))    // BPM
                    {
                        newBpm = bpmInt;
                    }
                    else
                    {
                        continue;
                    }
                    if (newBpm == bpm)
                    {
                        continue;
                    }
                    converted.type     = BMSEventType.BPM;
                    converted.Data2F   = newBpm;
                    referenceTimePoint = converted.time;
                    beatOffset         = ev.measure + ev.beat;
                    bpm    = newBpm;
                    minBpm = Math.Min(minBpm, (float)newBpm);
                    break;

                case BMSEventType.BeatReset:
                    double newBeatPerMeas = ev.Data2F;
                    if (newBeatPerMeas == beatPerMeas)
                    {
                        continue;
                    }
                    converted.type     = BMSEventType.BeatReset;
                    converted.Data2F   = ev.Data2F * 4;
                    beatOffset         = ev.measure;
                    beatPerMeas        = newBeatPerMeas;
                    referenceTimePoint = converted.time;
                    break;

                case BMSEventType.STOP:
                    if (!TryGetResourceData(ResourceType.stop, ev.data2, out BMSResourceData stopData))
                    {
                        continue;
                    }
                    double stopSeconds = Convert.ToDouble(stopData.additionalData) / bpm * 1.25;
                    if (stopSeconds <= 0)
                    {
                        continue;
                    }
                    converted.type = BMSEventType.STOP;
                    stopTimePoint  = converted.time;
                    stopMeasBeat   = ev.measure + ev.beat;
                    TimeSpan stopTime = new TimeSpan((long)Math.Round(stopSeconds * TimeSpan.TicksPerSecond));
                    converted.data2     = stopTime.Ticks;
                    referenceTimePoint += stopTime;
                    break;

                case BMSEventType.BMP:
                    converted.type = BMSEventType.BMP;
                    switch (ev.data1)
                    {
                    case 4: converted.data1 = 0; break;

                    case 6: converted.data1 = -1; break;

                    case 7: converted.data1 = 1; break;

                    default: continue;
                    }
                    converted.data2 = ev.data2;
                    break;

                case BMSEventType.LongNoteStart:
                    converted.data1      = ev.data1 - 40;
                    converted.data2      = ev.data2;
                    converted.sliceStart = TimeSpan.Zero;
                    converted.sliceEnd   = TimeSpan.MaxValue;
                    if (lnMarker.TryGetValue(ev.data1, out BMSEvent lnStart))
                    {
                        converted.type = BMSEventType.LongNoteEnd;
                        int index = FindEventIndex(lnStart);
                        lnStart.time2 = converted.time;
                        ReplaceEvent(index, lnStart);
                        lnMarker.Remove(ev.data1);
                    }
                    else
                    {
                        converted.type     = BMSEventType.LongNoteStart;
                        lnMarker[ev.data1] = converted;
                    }
                    break;

                case BMSEventType.Unknown:
                    continue;

                default:
                    if ((ev.data1 >= 30 && ev.data1 <= 50) || ev.data1 >= 70)
                    {
                        continue;
                    }
                    converted.type       = ev.type;
                    converted.data1      = ev.data1;
                    converted.data2      = ev.data2;
                    converted.sliceStart = TimeSpan.Zero;
                    converted.sliceEnd   = TimeSpan.MaxValue;
                    break;
                }
                AddEvent(converted);
            }
        }
Пример #14
0
 public void AddEvent(BMSEvent bmsEvent) => eventTree.Add(bmsEvent);
Пример #15
0
        private void ParseSoundChannel(List <BMSEvent> bmev, IJsonWrapper rawData, int index)
        {
            string name = rawData.GetChild("name").AsString();

            if (string.IsNullOrEmpty(name))
            {
                return;
            }
            AddResource(ResourceType.wav, index, name);

            BMSEvent?        lastEvent      = null;
            TimeSpan         slicedPosition = TimeSpan.Zero;
            IList <BMSEvent> events         = Events;

            foreach (IJsonWrapper note in rawData.GetChild("notes").GetChilds())
            {
                BMSEvent currentEvent;
                int      ticks       = note.GetChild("y").AsInt32();
                int      channelId   = GetChannelMap(note.GetChild("x").AsInt32());
                int      length      = note.GetChild("l").AsInt32();
                TimeSpan currentTime = CalculateTime(bmev, ticks);

                if (lastEvent.HasValue)
                {
                    currentEvent = lastEvent.Value;
                    int lastIndex = FindEventIndex(currentEvent);
                    if (note.GetChild("c").AsBoolean())
                    {
                        currentEvent.sliceEnd = slicedPosition = currentTime - currentEvent.time + currentEvent.sliceStart;
                    }
                    else
                    {
                        currentEvent.sliceEnd = TimeSpan.MaxValue;
                        slicedPosition        = TimeSpan.Zero;
                    }
                    ReplaceEvent(lastIndex, currentEvent);
                }

                if (length > 0)
                {
                    TimeSpan endTime = CalculateTime(bmev, ticks + length);
                    lastEvent = currentEvent = new BMSEvent {
                        type       = BMSEventType.LongNoteStart,
                        ticks      = ticks,
                        time       = currentTime,
                        data1      = channelId,
                        data2      = index,
                        time2      = endTime - currentTime,
                        sliceStart = slicedPosition,
                        sliceEnd   = TimeSpan.MaxValue
                    };
                    AddEvent(currentEvent);
                    AddEvent(new BMSEvent {
                        type  = BMSEventType.LongNoteEnd,
                        ticks = ticks + length,
                        time  = endTime,
                        data1 = channelId,
                        data2 = index
                    });
                }
                else
                {
                    lastEvent = currentEvent = new BMSEvent {
                        type       = channelId == 0 ? BMSEventType.WAV : BMSEventType.Note,
                        ticks      = ticks,
                        time       = currentTime,
                        data1      = channelId,
                        data2      = index,
                        sliceStart = slicedPosition,
                        sliceEnd   = TimeSpan.MaxValue
                    };
                    AddEvent(currentEvent);
                }
            }
        }