Beispiel #1
0
    public void TestGroupSimultaneousNotesAndFlattenNotes()
    {
        var clip = new Clip(4, true)
        {
            Notes = new SortedList <NoteEvent>()
            {
                new NoteEvent(60, 0, 2m, 100),
                new NoteEvent(62, .5m, .5m, 100),
                new NoteEvent(62, 1, .5m, 100),
                new NoteEvent(65, 1, 1m, 100),
                new NoteEvent(60, 2, .5m, 100),
                new NoteEvent(62, 2.5m, .5m, 100),
                new NoteEvent(66, 2.5m, .5m, 100)
            }
        };

        clip.GroupSimultaneousNotes();

        Assert.AreEqual(clip.Notes[0].Start, 0);
        Assert.AreEqual(clip.Notes[1].Start, .5m);
        Assert.AreEqual(clip.Notes[2].Start, 1);
        Assert.AreEqual(clip.Notes[3].Start, 2);
        Assert.AreEqual(clip.Notes[4].Start, 2.5m);

        clip.Flatten();

        Assert.AreEqual(clip.Notes[0].Start, 0);
        Assert.AreEqual(clip.Notes[1].Start, .5m);
        Assert.AreEqual(clip.Notes[2].Start, 1);
        Assert.AreEqual(clip.Notes[3].Start, 1);
        Assert.AreEqual(clip.Notes[4].Start, 2);
        Assert.AreEqual(clip.Notes[5].Start, 2.5m);
        Assert.AreEqual(clip.Notes[6].Start, 2.5m);
    }
Beispiel #2
0
        public static ProcessResultArray <Clip> Apply(InterleaveOptions options, ClipMetaData metadata, params Clip[] clips)
        {
            if (clips.Length < 2)
            {
                clips = new[] { clips[0], clips[0] };
            }
            decimal position     = 0;
            int     repeatsIndex = 0;
            Clip    resultClip   = new Clip(4, true);

            switch (options.Mode)
            {
            case Event:
                if (options.ChunkChords)
                {
                    foreach (var clip in clips)
                    {
                        clip.GroupSimultaneousNotes();
                    }
                }
                var noteCounters = clips.Select(c => new IntCounter(c.Notes.Count)).ToArray();
                position = clips[0].Notes[0].Start;

                while (noteCounters.Any(nc => !nc.Overflow))
                {
                    for (var clipIndex = 0; clipIndex < clips.Length; clipIndex++)
                    {
                        var clip = clips[clipIndex];
                        var currentNoteCounter = noteCounters[clipIndex];

                        for (var repeats = 0; repeats < options.Repeats[repeatsIndex % options.Repeats.Length]; repeats++)
                        {
                            var note = clip.Notes[currentNoteCounter.Value];

                            if (!options.Solo || clip.ClipReference.Track == metadata.TrackNumber)
                            {
                                var newNote = new NoteEvent(note);
                                newNote.Start = position;
                                resultClip.Notes.Add(newNote);
                            }
                            position += clip.DurationUntilNextNote(currentNoteCounter.Value);
                        }
                        if (options.Skip)
                        {
                            foreach (var noteCounter in noteCounters)
                            {
                                noteCounter.Inc();
                            }
                        }
                        else
                        {
                            currentNoteCounter.Inc();
                        }
                        repeatsIndex++;
                    }
                }
                if (options.ChunkChords)
                {
                    resultClip.Flatten();
                }
                break;

            case Time:
                var srcPositions   = clips.Select(c => new DecimalCounter(c.Length)).ToArray();
                int timeRangeIndex = 0;

                while (srcPositions.Any(c => !c.Overflow))
                {
                    for (var clipIndex = 0; clipIndex < clips.Length; clipIndex++)
                    {
                        var clip             = clips[clipIndex];
                        var currentTimeRange = options.Ranges[timeRangeIndex];
                        for (var repeats = 0; repeats < options.Repeats[repeatsIndex % options.Repeats.Length]; repeats++)
                        {
                            if (!options.Solo || clip.ClipReference.Track == metadata.TrackNumber)
                            {
                                resultClip.Notes.AddRange(
                                    ClipUtilities.GetSplitNotesInRangeAtPosition(
                                        srcPositions[clipIndex].Value,
                                        srcPositions[clipIndex].Value + currentTimeRange,
                                        clips[clipIndex].Notes,
                                        position
                                        )
                                    );
                            }
                            position += currentTimeRange;
                        }
                        if (options.Skip)
                        {
                            foreach (var srcPosition in srcPositions)
                            {
                                srcPosition.Inc(currentTimeRange);
                            }
                        }
                        else
                        {
                            srcPositions[clipIndex].Inc(currentTimeRange);
                        }
                        repeatsIndex++;
                        timeRangeIndex = (timeRangeIndex + 1) % options.Ranges.Length;     // this means that you cannot use the Counts parameter to have varying time ranges for each repeat
                    }
                }
                break;
            }
            resultClip.Length = position;
            return(new ProcessResultArray <Clip>(new[] { resultClip }));
        }