예제 #1
0
        public bool TryAddObject(ITimedObject timedObject)
        {
            var handlingBag = _uncompletedBags.FirstOrDefault(b => b.TryAddObject(timedObject, _context, _settings));

            if (handlingBag != null)
            {
                if (!handlingBag.CanObjectsBeAdded)
                {
                    _uncompletedBags.Remove(handlingBag);
                }

                return(true);
            }

            //

            var bag    = new TBag();
            var result = bag.TryAddObject(timedObject, _context, _settings);

            if (result)
            {
                _objectsBags.Add(bag);

                if (bag.CanObjectsBeAdded)
                {
                    _uncompletedBags.Add(bag);
                }
            }

            //

            return(result);
        }
예제 #2
0
        public IEnumerable <Timed <object[]> > EnumTimed(ITimedObject range = null)
        {
            var ci = new ColumnStack[allFields.Length];
            int n  = srcInfos.Length;

            for (int i = 0; i < ci.Length; i++)
            {
                ci[i] = new ColumnStack()
                {
                    name = allFields[i], values = new Stack <ColData>(n)
                }
            }
            ;
            TimeRange rng;

            if (range == null)
            {
                rng = new TimeRange(TimedObject.NonZeroTime, DateTime.MaxValue);
            }
            else
            {
                rng = new TimeRange(range.Time, range.EndTime);
            }
            return(EnumerateTimed(ci, 0, rng));
        }
예제 #3
0
 public static void AreEqual(
     ITimedObject expectedTimedObject,
     ITimedObject actualTimedObject,
     string message)
 {
     AreEqual(expectedTimedObject, actualTimedObject, true, 0, message);
 }
예제 #4
0
    public override void Visualise(int track, ITimedObject timedMidiEvent)
    {
        if (timedMidiEvent is Note)
        {
            if (lengthOverride != 0)
            {
                transform.localScale = new Vector3(transform.localScale.x, transform.localScale.y, lengthOverride);
            }

            Note  note       = timedMidiEvent as Note;
            Color noteColour = ColourUtils.ColourFromNote(note, transposeHue);
            noteColour      = Color.Lerp(PrimaryColour, noteColour, colourMix);
            baseAlpha      *= note.Velocity / 127f;
            noteColour.a    = alphaEnvelope.Evaluate(0f) * baseAlpha;
            line.startColor = line.endColor = noteColour;

            startTime = visualisation.time;
            float noteDuration = durationOverride == 0 ? (note.LengthAs <MetricTimeSpan>(visualisation.MIDITempoMap).TotalMicroseconds / 1000000f) : durationOverride;
            endTime = startTime + noteDuration * durationMult;

            startPos = transform.localPosition;

            line.widthMultiplier = 0f; //This will be updated to correct value next frame.
            line.enabled         = true;
            started = true;
        }
    }
예제 #5
0
        private bool TryAddObjectToNewNoteBag(ITimedObject timedObject, ObjectsBuildingSettings settings)
        {
            var bag = new NotesBag();

            if (!bag.TryAddObject(timedObject, null, settings))
            {
                return(false);
            }

            var newNoteTime    = bag.Time;
            var newNoteChannel = bag.NoteId.Channel;

            if (_chordStart < 0)
            {
                _notesBags.Add(bag);
                _chordStart   = newNoteTime;
                _chordChannel = newNoteChannel;
                return(true);
            }
            else
            {
                if (newNoteTime - _chordStart > settings.ChordBuilderSettings.NotesTolerance || newNoteChannel != _chordChannel)
                {
                    _canObjectsBeAdded = !IsCompleted;
                    return(false);
                }

                _notesBags.Add(bag);
                return(true);
            }
        }
        /// <summary>
        /// Gets time of an <see cref="ITimedObject"/> as an instance of time span defined by the
        /// specified time span type.
        /// </summary>
        /// <param name="obj">Object to get time of.</param>
        /// <param name="timeType">The type of time span to convert the time of <paramref name="obj"/> to.</param>
        /// <param name="tempoMap">Tempo map to calculate time of the <paramref name="obj"/>.</param>
        /// <returns>Time of the specified object as an instance of time span defined by the
        /// <paramref name="timeType"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <para>One of the following errors occured:</para>
        /// <list type="bullet">
        /// <item>
        /// <description><paramref name="obj"/> is <c>null</c>.</description>
        /// </item>
        /// <item>
        /// <description><paramref name="tempoMap"/> is <c>null</c>.</description>
        /// </item>
        /// </list>
        /// </exception>
        /// <exception cref="InvalidEnumArgumentException"><paramref name="timeType"/> specified an invalid value.</exception>
        public static ITimeSpan TimeAs(this ITimedObject obj, TimeSpanType timeType, TempoMap tempoMap)
        {
            ThrowIfArgument.IsNull(nameof(obj), obj);
            ThrowIfArgument.IsInvalidEnumValue(nameof(timeType), timeType);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(TimeConverter.ConvertTo(obj.Time, timeType, tempoMap));
        }
        /// <summary>
        /// Gets time of an <see cref="ITimedObject"/> as an instance of type that implements the
        /// <see cref="ITimeSpan"/> interface.
        /// </summary>
        /// <typeparam name="TTime">Type that will represent the time of the <paramref name="obj"/>.</typeparam>
        /// <param name="obj">Object to get time of.</param>
        /// <param name="tempoMap">Tempo map to calculate time of the <paramref name="obj"/>.</param>
        /// <returns>Time of the specified object as an instance of <typeparamref name="TTime"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <para>One of the following errors occured:</para>
        /// <list type="bullet">
        /// <item>
        /// <description><paramref name="obj"/> is <c>null</c>.</description>
        /// </item>
        /// <item>
        /// <description><paramref name="tempoMap"/> is <c>null</c>.</description>
        /// </item>
        /// </list>
        /// </exception>
        /// <exception cref="NotSupportedException"><typeparamref name="TTime"/> is not supported.</exception>
        public static TTime TimeAs <TTime>(this ITimedObject obj, TempoMap tempoMap)
            where TTime : ITimeSpan
        {
            ThrowIfArgument.IsNull(nameof(obj), obj);
            ThrowIfArgument.IsNull(nameof(tempoMap), tempoMap);

            return(TimeConverter.ConvertTo <TTime>(obj.Time, tempoMap));
        }
예제 #8
0
    /// <returns>Was the step successful? (false if e.g. startTime == endTIme)</returns>
    public bool StepMIDI(double startTime, double endTime) //Fire all events between prevTime and time.
    {
        //Convert times to absolute:
        startTime = GetTimeInTicks(startTime);
        endTime   = GetTimeInTicks(endTime);

        if (startTime == endTime)
        {
            return(false);                      //Ignore if start and end time are equal.
        }
        if (logTrack != -1)
        {
            Debug.Log("Stepping MIDI from " + startTime + " to " + endTime + "...");
        }
        for (int t = 0; t < MIDIEvents.Length; t++)                            //for every track...
        {
            for (int i = lastEventCache[t] + 1; i < trackLengthsCache[t]; i++) //for every event...
            {
                ITimedObject e = MIDIEvents[t][i];
                if (e.Time < startTime) //Event has already played. Skip to next one.
                {
                    if (t == logTrack)
                    {
                        Debug.Log("Read expired event on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time);
                    }
                    lastEventCache[t] = i;
                    continue;
                }
                if (e.Time >= endTime) //Event is too far in the future. Abort loop.
                {
                    if (t == logTrack)
                    {
                        Debug.Log("Read future event on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time);
                    }
                    //Don't set last event cache - we want to revisit this event in the future.
                    break;
                }
                //Else, event is within the timestep.
                if (e is TimedEvent && ((TimedEvent)e).Event is NoteOnEvent) //NoteOn without Note Off - convert it to a short note because Reaper f****d shit up.
                {
                    NoteOnEvent noteOn  = ((TimedEvent)e).Event as NoteOnEvent;
                    Note        newNote = new Note(noteOn.NoteNumber, midi.TimeDivision.ToInt16() / 4, e.Time);
                    newNote.Velocity = noteOn.Velocity;
                    e = newNote;
                }
                if (e is Note) //If it is a Note...
                {
                    if (t == logTrack)
                    {
                        Debug.Log("Read new note on track " + t + " between times " + startTime + " and " + endTime + ". Event time is " + e.Time);
                    }
                    OnMIDINoteDown(t, e as Note); //Fire OnMIDINoteDown event.
                    lastEventCache[t] = i;
                }
            }
        }
        return(true);
    }
예제 #9
0
        public override bool TryAddObject(ITimedObject timedObject, IBuildingContext context, ObjectsBuildingSettings settings)
        {
            if (!CanObjectsBeAdded)
            {
                return(false);
            }

            return(TryAddTimedEvent(timedObject as TimedEvent, settings) ||
                   TryAddNote(timedObject as Note, settings) ||
                   TryAddChord(timedObject as Chord));
        }
        public override bool TryAddObject(ITimedObject timedObject, IBuildingContext context, ObjectsBuildingSettings settings)
        {
            if (!CanObjectsBeAdded)
            {
                return(false);
            }

            var buildingContext = (RegisteredParametersContext)context;

            return(TryAddTimedEvent(timedObject as TimedEvent, buildingContext));
        }
예제 #11
0
    public override void Visualise(int track, ITimedObject timedMidiEvent)
    {
        if (timedMidiEvent is Note)
        {
            Note note = timedMidiEvent as Note;
            baseIntensity *= note.Velocity / 127f;                                     //Higher vel = more intensity
            baseSize       = Mathf.Lerp(sizeAtMinVel, baseSize, note.Velocity / 127f); //Higher vel = bigger size
            baseLifetime  *= (1 - note.NoteNumber / 127f);                             //Lower pitch = longer lifetime (slower wave)
        }

        StartCoroutine(ShockwaveCoroutine());
    }
예제 #12
0
        public override bool TryAddObject(ITimedObject timedObject, IBuildingContext context, ObjectsBuildingSettings settings)
        {
            if (IsCompleted)
            {
                return(false);
            }

            return(TryAddTimedEvent(timedObject as TimedEvent) ||
                   TryAddNote(timedObject as Note) ||
                   TryAddChord(timedObject as Chord) ||
                   TryAddRegisteredParameter(timedObject as RegisteredParameter));
        }
예제 #13
0
        public static void AreEqual(
            ITimedObject expectedTimedObject,
            ITimedObject actualTimedObject,
            bool compareDeltaTimes,
            long timesEpsilon,
            string message)
        {
            if (ReferenceEquals(expectedTimedObject, actualTimedObject))
            {
                return;
            }

            if (ReferenceEquals(null, expectedTimedObject) || ReferenceEquals(null, actualTimedObject))
            {
                Assert.Fail($"{message} One of objects is null.");
            }

            var timedEvent = expectedTimedObject as TimedEvent;

            if (timedEvent != null)
            {
                AreEqual(timedEvent, actualTimedObject as TimedEvent, compareDeltaTimes, timesEpsilon, $"{message} Timed event is invalid.");
                return;
            }

            var note = expectedTimedObject as Note;

            if (note != null)
            {
                AreEqual(note, actualTimedObject as Note, $"{message} Note is invalid.");
                return;
            }

            var chord = expectedTimedObject as Chord;

            if (chord != null)
            {
                AreEqual(chord, actualTimedObject as Chord, $"{message} Chord is invalid.");
                return;
            }

            var rest = expectedTimedObject as Rest;

            if (rest != null)
            {
                AreEqual(rest, actualTimedObject as Rest, $"{message} Rest is invalid.");
                return;
            }

            Assert.Inconclusive($"Comparing of {expectedTimedObject} and {actualTimedObject} is not implemented.");
        }
예제 #14
0
        public void GetTimedEventsAndNotes_SameNotesInTail()
        {
            var events = new MidiEvent[]
            {
                new NoteOnEvent((SevenBitNumber)1, (SevenBitNumber)100)
                {
                    DeltaTime = 10
                },
                new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)70)
                {
                    DeltaTime = 10
                },
                new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)1),
                new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)0),
                new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)0)
                {
                    DeltaTime = 10
                },
                new NoteOffEvent((SevenBitNumber)1, (SevenBitNumber)0)
                {
                    DeltaTime = 10
                }
            };

            var timedEvents   = new TrackChunk(events).GetTimedEvents().Concat(new[] { default(TimedEvent) });
            var actualObjects = timedEvents.GetTimedEventsAndNotes().ToList();

            var expectedObjects = new ITimedObject[]
            {
                new Note((SevenBitNumber)1, 30, 10)
                {
                    Velocity = (SevenBitNumber)100
                },
                new Note((SevenBitNumber)2, 0, 20)
                {
                    Velocity = (SevenBitNumber)70, OffVelocity = (SevenBitNumber)1
                },
                new Note((SevenBitNumber)2, 10, 20)
                {
                    Velocity = (SevenBitNumber)0
                },
                null
            };

            CollectionAssert.AreEqual(expectedObjects, actualObjects, new TimedObjectComparer());
        }
예제 #15
0
    /// <summary>
    /// Returns the status of the goal from the time marker.
    /// </summary>
    /// <returns>bool</returns>
    public bool IsReachTimeGoal()
    {
        float now = chronometer != null ? chronometer.ElapsedMilliseconds / 1000.0f : 0;

        if (timeGoal > 0 && now >= timeGoal)
        {
            if (ITimedObject != null)
            {
                ITimedObject.OnReachTimeGoal();
            }

            return(true);
        }
        else
        {
            return(false);
        }
    }
예제 #16
0
    public List <Note> GetAllNotesOnTrack(int track)
    {
        List <Note> notes = new List <Note>();

        for (int i = 0; i < trackLengthsCache[track]; i++) //for every event...
        {
            ITimedObject e = MIDIEvents[track][i];
            if (e is TimedEvent && ((TimedEvent)e).Event is NoteOnEvent) //NoteOn without Note Off - convert it to a short note because Reaper f****d shit up.
            {
                NoteOnEvent noteOn  = ((TimedEvent)e).Event as NoteOnEvent;
                Note        newNote = new Note(noteOn.NoteNumber, midi.TimeDivision.ToInt16() / 4, e.Time);
                newNote.Velocity = noteOn.Velocity;
                e = newNote;
            }
            if (e is Note)
            {
                notes.Add(e as Note);
            }
        }
        return(notes);
    }
예제 #17
0
        public void GetTimedEventsAndNotes_AllProcessed()
        {
            var events = new MidiEvent[]
            {
                new SetTempoEvent(1234),
                new NoteOnEvent((SevenBitNumber)1, (SevenBitNumber)100)
                {
                    DeltaTime = 10, Channel = (FourBitNumber)1
                },
                new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)70)
                {
                    DeltaTime = 10, Channel = (FourBitNumber)1
                },
                new PitchBendEvent(123)
                {
                    DeltaTime = 10
                },
                new MarkerEvent("Marker")
                {
                    DeltaTime = 10
                },
                new NoteOnEvent((SevenBitNumber)3, (SevenBitNumber)1)
                {
                    Channel = (FourBitNumber)1
                },
                new MarkerEvent("Marker 2")
                {
                    DeltaTime = 10
                },
                new TextEvent("Text")
                {
                    DeltaTime = 10
                },
                new TextEvent("Text 2")
                {
                    DeltaTime = 10
                },
                new NoteOnEvent((SevenBitNumber)2, (SevenBitNumber)1)
                {
                    Channel = (FourBitNumber)10
                },
                new CuePointEvent("Point")
                {
                    DeltaTime = 10
                },
                new NoteOffEvent((SevenBitNumber)3, (SevenBitNumber)1)
                {
                    Channel = (FourBitNumber)1
                },
                new NoteOffEvent((SevenBitNumber)1, (SevenBitNumber)0)
                {
                    DeltaTime = 10, Channel = (FourBitNumber)1
                },
                new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)0)
                {
                    Channel = (FourBitNumber)10
                },
                new NoteOffEvent((SevenBitNumber)2, (SevenBitNumber)0)
                {
                    DeltaTime = 10, Channel = (FourBitNumber)1
                }
            };

            var timedEvents   = new TrackChunk(events).GetTimedEvents();
            var actualObjects = timedEvents.GetTimedEventsAndNotes().ToList();

            var expectedObjects = new ITimedObject[]
            {
                new TimedEvent(new SetTempoEvent(1234), 0),
                new Note((SevenBitNumber)1, 80, 10)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)100
                },
                new Note((SevenBitNumber)2, 80, 20)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)70
                },
                new TimedEvent(new PitchBendEvent(123), 30),
                new TimedEvent(new MarkerEvent("Marker"), 40),
                new Note((SevenBitNumber)3, 40, 40)
                {
                    Channel = (FourBitNumber)1, Velocity = (SevenBitNumber)1, OffVelocity = (SevenBitNumber)1
                },
                new TimedEvent(new MarkerEvent("Marker 2"), 50),
                new TimedEvent(new TextEvent("Text"), 60),
                new TimedEvent(new TextEvent("Text 2"), 70),
                new Note((SevenBitNumber)2, 20, 70)
                {
                    Channel = (FourBitNumber)10, Velocity = (SevenBitNumber)1
                },
                new TimedEvent(new CuePointEvent("Point"), 80)
            };

            CollectionAssert.AreEqual(expectedObjects, actualObjects, new TimedObjectComparer());
        }
예제 #18
0
 public abstract bool TryAddObject(ITimedObject timedObject, IBuildingContext context, ObjectsBuildingSettings settings);