Ejemplo n.º 1
0
        public void GetTempoChanges_MultipleChanges()
        {
            var microsecondsPerQuarterNote1 = 100000;
            var time1 = 1000;

            var microsecondsPerQuarterNote2 = 700000;
            var time2 = 1500;

            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(time2, new Tempo(microsecondsPerQuarterNote2));
                tempoMapManager.SetTempo(time1, new Tempo(microsecondsPerQuarterNote1));

                var tempoMap = tempoMapManager.TempoMap;
                var changes  = tempoMap.GetTempoChanges();
                Assert.AreEqual(2, changes.Count(), "Count of tempo changes is invalid.");

                var change1 = changes.First();
                Assert.AreEqual(time1, change1.Time, "Time of first change is invalid.");
                Assert.AreEqual(new Tempo(microsecondsPerQuarterNote1), change1.Value, "Tempo of first change is invalid.");

                var change2 = changes.Last();
                Assert.AreEqual(time2, change2.Time, "Time of second change is invalid.");
                Assert.AreEqual(new Tempo(microsecondsPerQuarterNote2), change2.Value, "Tempo of second change is invalid.");
            }
        }
Ejemplo n.º 2
0
        private static TempoMap GenerateComplexTempoMap()
        {
            // 4/4                                     5/8            5/16                          5/8
            //  |----+----+----+----|----+----+----+----|--+--+--+--+--|-+-+-+-+-|-+-+-+-+-|-+-+-+-+-|--+--+--+--+--|
            //  0                   1                   2              3         4         5         6              7

            var steps = new[]
            {
                Tuple.Create(2 * MusicalTimeSpan.Whole, new TimeSignature(5, 8)),
                Tuple.Create(5 * MusicalTimeSpan.Eighth, new TimeSignature(5, 16)),
                Tuple.Create(15 * MusicalTimeSpan.Sixteenth, new TimeSignature(5, 8)),
            };

            using (var tempoMapManager = new TempoMapManager(new TicksPerQuarterNoteTimeDivision(TicksPerQuarterNote)))
            {
                var time = new MusicalTimeSpan();

                foreach (var step in steps)
                {
                    time += step.Item1;
                    tempoMapManager.SetTimeSignature(time, step.Item2);
                }

                tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 10), Tempo.FromMillisecondsPerQuarterNote(300));
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 1, 30), Tempo.FromMillisecondsPerQuarterNote(600));
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 1, 31), Tempo.FromMillisecondsPerQuarterNote(640));

                return(tempoMapManager.TempoMap);
            }
        }
        private static TempoMap GetTempoMap()
        {
            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 1), Tempo.FromBeatsPerMinute(60));
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 10), Tempo.FromBeatsPerMinute(150));
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 50), Tempo.FromBeatsPerMinute(100));

                return(tempoMapManager.TempoMap);
            }
        }
Ejemplo n.º 4
0
        public void GetTempoAtTime_NonDefaultTempoMap_MultipleChangesAtMiddle_GetAfterSecondChange()
        {
            var microsecondsPerQuarterNote1 = 100000;
            var microsecondsPerQuarterNote2 = 700000;

            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(100, new Tempo(microsecondsPerQuarterNote1));
                tempoMapManager.SetTempo(1000, new Tempo(microsecondsPerQuarterNote2));

                var tempoMap = tempoMapManager.TempoMap;
                var tempo    = tempoMap.GetTempoAtTime(new MidiTimeSpan(5000));
                Assert.AreEqual(new Tempo(microsecondsPerQuarterNote2), tempo, "Tempo is invalid.");
            }
        }
Ejemplo n.º 5
0
        public static void TestTimedEvents(
            Pattern pattern,
            ICollection <TimedEventInfo> expectedTimedEventsInfos,
            params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event,
                                                                                     TimeConverter.ConvertFrom(i.Time ?? new MidiTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            MidiAsserts.AreEqual(
                expectedTimedEvents,
                actualTimedEvents.Where(e => expectedTimedEvents.Any(ee => ee.Event.EventType == e.Event.EventType)),
                false,
                0,
                "Events are invalid.");
        }
Ejemplo n.º 6
0
        private static MidiFile TestNotes(Pattern pattern, ICollection <NoteInfo> expectedNotesInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            var channel = (FourBitNumber)2;

            TempoMap tempoMap = null;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, channel);

            var expectedNotes = expectedNotesInfos.Select(i =>
            {
                var expectedTime   = TimeConverter.ConvertFrom(i.Time ?? new MetricTime(), tempoMap);
                var expectedLength = LengthConverter.ConvertFrom(i.Length, expectedTime, tempoMap);

                return(new Note(i.NoteNumber, expectedLength, expectedTime)
                {
                    Velocity = i.Velocity,
                    Channel = channel
                });
            });

            Assert.IsTrue(NoteEquality.Equals(expectedNotes, midiFile.GetNotes()));

            return(midiFile);
        }
Ejemplo n.º 7
0
        private static void TestTimedEventsWithExactOrder(
            Pattern pattern,
            ICollection <TimedEventInfo> expectedTimedEventsInfos,
            params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event, TimeConverter.ConvertFrom(i.Time ?? new MidiTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            Assert.IsTrue(TimedEventEquality.AreEqual(expectedTimedEvents, actualTimedEvents, false), "Events have invalid order.");
        }
Ejemplo n.º 8
0
        private static void TestTimedEvents(
            Pattern pattern,
            ICollection <TimedEventInfo> expectedTimedEventsInfos,
            params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event,
                                                                                     TimeConverter.ConvertFrom(i.Time ?? new MidiTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            foreach (var expectedEvent in expectedTimedEvents)
            {
                Assert.IsTrue(actualTimedEvents.Any(actual => TimedEventEquality.AreEqual(expectedEvent, actual, false)),
                              $"There are no event: {expectedEvent}");
            }
        }
Ejemplo n.º 9
0
        private static MidiFile TestTimedEvents(Pattern pattern, ICollection <TimedEventInfo> expectedTimedEventsInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            var channel = (FourBitNumber)2;

            TempoMap tempoMap = null;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, channel);

            var expectedTimedEvents = expectedTimedEventsInfos.Select(i =>
                                                                      new TimedEvent(i.Event,
                                                                                     TimeConverter.ConvertFrom(i.Time ?? new MetricTimeSpan(), tempoMap)));

            var actualTimedEvents = midiFile.GetTimedEvents();

            Assert.IsTrue(expectedTimedEvents.All(expected => actualTimedEvents.Any(actual => TimedEventEquality.Equals(expected, actual))));

            return(midiFile);
        }
Ejemplo n.º 10
0
        private static TempoMap GetTempoMap(IEnumerable <TimedMidiEvent> timedMidiEvents, TimeDivision timeDivision)
        {
            using (var tempoMapManager = new TempoMapManager(timeDivision))
            {
                var setTempoEvents = timedMidiEvents.Where(e => e.Event is SetTempoEvent)
                                     .OrderBy(e => e.Time, new TimeSpanComparer());
                foreach (var timedMidiEvent in setTempoEvents)
                {
                    var setTempoEvent = (SetTempoEvent)timedMidiEvent.Event;
                    tempoMapManager.SetTempo(timedMidiEvent.Time,
                                             new Tempo(setTempoEvent.MicrosecondsPerQuarterNote));
                }

                var timeSignatureEvents = timedMidiEvents.Where(e => e.Event is TimeSignatureEvent)
                                          .OrderBy(e => e.Time, new TimeSpanComparer());
                foreach (var timedMidiEvent in timeSignatureEvents)
                {
                    var timeSignatureEvent = (TimeSignatureEvent)timedMidiEvent.Event;
                    tempoMapManager.SetTimeSignature(timedMidiEvent.Time,
                                                     new TimeSignature(timeSignatureEvent.Numerator, timeSignatureEvent.Denominator));
                }

                return(tempoMapManager.TempoMap);
            }
        }
Ejemplo n.º 11
0
        public void ReplaceTempoMap_ByDefault()
        {
            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(100, new Tempo(10));
                tempoMapManager.SetTempo(300, new Tempo(100));

                tempoMapManager.ReplaceTempoMap(TempoMap.Default);

                var tempoMap = tempoMapManager.TempoMap;

                Assert.AreEqual(TicksPerQuarterNoteTimeDivision.DefaultTicksPerQuarterNote,
                                ((TicksPerQuarterNoteTimeDivision)tempoMap.TimeDivision).TicksPerQuarterNote);
                Assert.IsFalse(tempoMap.Tempo.Values.Any());
                Assert.IsFalse(tempoMap.TimeSignature.Values.Any());
            }
        }
Ejemplo n.º 12
0
        private static TempoMap GenerateSimpleTempoMap()
        {
            // 4/4                 5/8            5/16
            //  |----+----+----+----|--+--+--+--+--|-+-+-+-+-|
            //  0                   1              2         3

            using (var tempoMapManager = new TempoMapManager(new TicksPerQuarterNoteTimeDivision(TicksPerQuarterNote)))
            {
                tempoMapManager.SetTimeSignature(MusicalTimeSpan.Whole, new TimeSignature(5, 8));
                tempoMapManager.SetTimeSignature(MusicalTimeSpan.Whole + 5 * MusicalTimeSpan.Eighth, new TimeSignature(5, 16));

                tempoMapManager.SetTempo(new MetricTimeSpan(0, 0, 10), Tempo.FromMillisecondsPerQuarterNote(300));
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 1, 30), Tempo.FromMillisecondsPerQuarterNote(600));

                return(tempoMapManager.TempoMap);
            }
        }
Ejemplo n.º 13
0
        public void ConvertCsvToMidiFile_SingleTrackChunk_MetricTimes(MidiFileCsvLayout layout, bool orderEvents, string[] csvLines)
        {
            if (!orderEvents)
            {
                var tmp = csvLines[2];
                csvLines[2] = csvLines[5];
                csvLines[5] = tmp;
            }

            var midiFile = ConvertCsvToMidiFile(layout, TimeSpanType.Metric, csvLines);

            TempoMap expectedTempoMap;

            using (var tempoMapManager = new TempoMapManager(new TicksPerQuarterNoteTimeDivision(500)))
            {
                tempoMapManager.SetTempo(new MetricTimeSpan(0, 1, 3), new Tempo(300000));
                expectedTempoMap = tempoMapManager.TempoMap;
            }

            var expectedEvents = new[]
            {
                new TimeAndMidiEvent(new MetricTimeSpan(),
                                     new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)120)
                {
                    Channel = (FourBitNumber)10
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(),
                                     new TextEvent("Test")),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 0),
                                     new NoteOnEvent((SevenBitNumber)50, (SevenBitNumber)110)
                {
                    Channel = (FourBitNumber)7
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 3),
                                     new SetTempoEvent(300000)),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 1, 10),
                                     new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)70)
                {
                    Channel = (FourBitNumber)10
                }),
                new TimeAndMidiEvent(new MetricTimeSpan(0, 10, 3),
                                     new NoteOffEvent((SevenBitNumber)50, (SevenBitNumber)80)
                {
                    Channel = (FourBitNumber)7
                })
            }
            .Select(te => new TimedEvent(te.Event, TimeConverter.ConvertFrom(te.Time, expectedTempoMap)))
            .ToArray();

            Assert.AreEqual(1, midiFile.GetTrackChunks().Count(), "Track chunks count is invalid.");
            CollectionAssert.AreEqual(midiFile.GetTempoMap().GetTempoChanges(), expectedTempoMap.GetTempoChanges(), "Invalid tempo map.");
            Assert.AreEqual(new TicksPerQuarterNoteTimeDivision(500), midiFile.TimeDivision, "Invalid time division.");
            Assert.IsTrue(TimedEventEquality.AreEqual(expectedEvents, midiFile.GetTimedEvents(), false),
                          "Invalid events.");
        }
Ejemplo n.º 14
0
        public void Conversion_Metric_Math_Subtract_TempoChanged()
        {
            TempoMap tempoMap = null;

            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(new MetricTime(0, 1, 5), new Tempo(20000));
                tempoMapManager.SetTempo(new MetricTime(0, 1, 50), new Tempo(2400));
                tempoMap = tempoMapManager.TempoMap;
            }

            var mathLength = new MathLength(new MetricLength(0, 0, 20),
                                            new MetricLength(0, 0, 50));
            var mathTime = new MathTime(new MetricTime(0, 2, 0),
                                        mathLength,
                                        MathOperation.Subtract);

            Assert.AreEqual(TimeConverter.ConvertFrom(new MetricTime(0, 0, 50), tempoMap),
                            TimeConverter.ConvertFrom(mathTime, tempoMap));
        }
Ejemplo n.º 15
0
        public void GetTempoAtTime_NonDefaultTempoMap_SingleChangeAtMiddle_GetAtChange()
        {
            var microsecondsPerQuarterNote = 100000;

            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(1000, new Tempo(microsecondsPerQuarterNote));

                var tempoMap = tempoMapManager.TempoMap;
                var tempo    = tempoMap.GetTempoAtTime(new MidiTimeSpan(1000));
                Assert.AreEqual(new Tempo(microsecondsPerQuarterNote), tempo, "Tempo is invalid.");
            }
        }
Ejemplo n.º 16
0
        public static MidiFile TestNotes(Pattern pattern, ICollection <NoteInfo> expectedNotesInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedNotes = expectedNotesInfos.Select(i =>
            {
                var expectedTime   = TimeConverter.ConvertFrom(i.Time ?? new MetricTimeSpan(), tempoMap);
                var expectedLength = LengthConverter.ConvertFrom(i.Length, expectedTime, tempoMap);

                return(new DryWetMidi.Interaction.Note(i.NoteNumber, expectedLength, expectedTime)
                {
                    Velocity = i.Velocity,
                    Channel = Channel
                });
            })
                                .OrderBy(n => n.Time)
                                .ToArray();

            var actualNotes = midiFile.GetNotes().ToArray();

            Assert.AreEqual(expectedNotes.Length, actualNotes.Length, "Notes count is invalid.");

            var j = 0;

            foreach (var expectedActual in expectedNotes.Zip(actualNotes, (e, a) => new { Expected = e, Actual = a }))
            {
                var expectedNote = expectedActual.Expected;
                var actualNote   = expectedActual.Actual;

                Assert.IsTrue(NoteEquality.AreEqual(expectedNote, actualNote), $"Note {j} is invalid. Expected: {expectedNote}; actual: {actualNote}.");
                j++;
            }

            return(midiFile);
        }
Ejemplo n.º 17
0
        public void GetTempoChanges_SingleChange_AtMiddle()
        {
            var microsecondsPerQuarterNote = 100000;
            var time = 1000;

            using (var tempoMapManager = new TempoMapManager())
            {
                tempoMapManager.SetTempo(time, new Tempo(microsecondsPerQuarterNote));

                var tempoMap = tempoMapManager.TempoMap;
                var changes  = tempoMap.GetTempoChanges();
                Assert.AreEqual(1, changes.Count(), "Count of tempo changes is invalid.");

                var change = changes.First();
                Assert.AreEqual(time, change.Time, "Time of change is invalid.");
                Assert.AreEqual(new Tempo(microsecondsPerQuarterNote), change.Value, "Tempo of change is invalid.");
            }
        }
Ejemplo n.º 18
0
            private static TempoMap GetTempoMap()
            {
                var changeTempoOffset = 5 * TimeOffset - 1;
                var maxTime           = Math.Max((TimesCount - 1) * TimeOffset, (TimesCount - 1) * TimeOffset + Length);

                bool firstTempo = true;

                using (var tempoMapManager = new TempoMapManager())
                {
                    var time = 0L;

                    while (time < maxTime)
                    {
                        tempoMapManager.SetTempo(time, firstTempo ? FirstTempo : SecondTempo);

                        firstTempo = !firstTempo;
                        time      += changeTempoOffset;
                    }

                    return(tempoMapManager.TempoMap);
                }
            }
Ejemplo n.º 19
0
        public static MidiFile TestNotes(Pattern pattern, ICollection <NoteInfo> expectedNotesInfos, params Tuple <long, Tempo>[] tempoChanges)
        {
            TempoMap tempoMap;

            using (var tempoMapManager = new TempoMapManager())
            {
                foreach (var tempoChange in tempoChanges)
                {
                    tempoMapManager.SetTempo(tempoChange.Item1, tempoChange.Item2);
                }

                tempoMap = tempoMapManager.TempoMap;
            }

            var midiFile = pattern.ToFile(tempoMap, Channel);

            var expectedNotes = expectedNotesInfos.Select(i =>
            {
                var expectedTime   = TimeConverter.ConvertFrom(i.Time ?? new MetricTimeSpan(), tempoMap);
                var expectedLength = LengthConverter.ConvertFrom(i.Length, expectedTime, tempoMap);

                return(new DryWetMidi.Interaction.Note(i.NoteNumber, expectedLength, expectedTime)
                {
                    Velocity = i.Velocity,
                    Channel = Channel
                });
            })
                                .OrderBy(n => n.Time)
                                .ToArray();

            var actualNotes = midiFile.GetNotes().ToArray();

            MidiAsserts.AreEqual(expectedNotes, actualNotes, "Notes are invalid.");

            return(midiFile);
        }
Ejemplo n.º 20
0
        internal static MidiFile Load(string filePath)
        {
            try
            {
                MMSong mmSong = JsonExtensions.DeserializeFromFileCompressed <MMSong>(filePath);

                if (mmSong.schemaVersion < 1 && mmSong.schemaVersion > 2)
                {
                    throw new FileFormatException("Error: This mmsong file format is not understood.");
                }
                // For now, just play the first available song.
                // if (mmSong.songs.Count != 1) throw new FileFormatException("Error: BMP currently only supports mmsong files with 1 song in them.");

                MMSong.Song song = mmSong.songs[0];

                MidiFile sequence = new MidiFile();
                sequence.Chunks.Add(new TrackChunk());
                sequence.TimeDivision = new TicksPerQuarterNoteTimeDivision(600);
                using (TempoMapManager tempoMapManager = sequence.ManageTempoMap()) tempoMapManager.SetTempo(0, Tempo.FromBeatsPerMinute(100));

                foreach (MMSong.Bard bard in song.bards)
                {
                    List <Note> notes   = new List <Note>();
                    bool        failure = false;

                    switch (bard.instrument)
                    {
                    case Instrument.Cymbal:
                    case Instrument.Trumpet:
                    case Instrument.Trombone:
                    case Instrument.Horn:
                    case Instrument.Tuba:
                    case Instrument.Saxophone:
                    case Instrument.Violin:
                    case Instrument.Viola:
                    case Instrument.Cello:
                    case Instrument.DoubleBass:
                        bard.sequence = bard.sequence.ToDictionary(
                            x => x.Key + 2,
                            x => x.Value);
                        break;

                    default:
                        break;
                    }

                    if (bard.sequence.Count % 2 == 0)
                    {
                        long lastTime = 0;
                        int  lastNote = 254;
                        foreach (KeyValuePair <long, int> sEvent in bard.sequence)
                        {
                            if (!failure)
                            {
                                if (lastNote == 254)
                                {
                                    if (sEvent.Value <= 60 && sEvent.Value >= 24 && ((sEvent.Key * 25 % 100) == 50 || (sEvent.Key * 25) % 100 == 0))
                                    {
                                        lastNote = sEvent.Value + 24;
                                        lastTime = sEvent.Key * 25;
                                    }
                                    else
                                    {
                                        failure = true;
                                    }
                                }
                                else
                                {
                                    if (sEvent.Value == 254)
                                    {
                                        long dur = (sEvent.Key * 25) - lastTime;
                                        notes.Add(new Note((SevenBitNumber)lastNote, dur, lastTime)
                                        {
                                            Channel     = (FourBitNumber)14,
                                            Velocity    = (SevenBitNumber)(int)127,
                                            OffVelocity = (SevenBitNumber)(int)0
                                        });
                                        lastNote = 254;
                                        lastTime = sEvent.Key * 25;
                                    }
                                    else
                                    {
                                        failure = true;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        failure = true;
                    }

                    if (failure)
                    {
                        throw new FileFormatException("Error: This mmsong file is corrupted");
                    }

                    TrackChunk currentChunk = new TrackChunk(new SequenceTrackNameEvent(bard.instrument.ToString()));
                    currentChunk.AddNotes(notes);
                    notes = null;
                    sequence.Chunks.Add(currentChunk);
                    currentChunk = null;
                }

                using (var manager = new TimedEventsManager(sequence.GetTrackChunks().First().Events))
                    manager.Events.Add(new TimedEvent(new MarkerEvent(), (sequence.GetDuration <MetricTimeSpan>().TotalMicroseconds / 1000) + 100));

                return(sequence);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Ejemplo n.º 21
0
        public static void ExportToAudicaFile(AudicaFile audicaFile)
        {
            if (!File.Exists(audicaFile.filepath))
            {
                Debug.Log("Save file is gone... :(");
                return;
            }

            Encoding encoding = Encoding.GetEncoding(437);

            using (var archive = ZipArchive.Open(audicaFile.filepath)) {
                HandleCache.CheckCacheFolderValid();
                HandleCache.CheckSaveFolderValid();

                bool expert = false, advanced = false, standard = false, easy = false;
                //Write the cues files to disk so we can add them to the audica file.
                if (audicaFile.diffs.expert.cues != null)
                {
                    File.WriteAllText($"{Application.dataPath}/.cache/expert-new.cues", CuesToJson(audicaFile.diffs.expert));
                    expert = true;
                }
                if (audicaFile.diffs.advanced.cues != null)
                {
                    File.WriteAllText($"{Application.dataPath}/.cache/advanced-new.cues", CuesToJson(audicaFile.diffs.advanced));
                    advanced = true;
                }
                if (audicaFile.diffs.moderate.cues != null)
                {
                    File.WriteAllText($"{Application.dataPath}/.cache/moderate-new.cues", CuesToJson(audicaFile.diffs.moderate));
                    standard = true;
                }
                if (audicaFile.diffs.beginner.cues != null)
                {
                    File.WriteAllText($"{Application.dataPath}/.cache/beginner-new.cues", CuesToJson(audicaFile.diffs.beginner));
                    easy = true;
                }

                File.WriteAllText($"{Application.dataPath}/.cache/song-new.desc", JsonUtility.ToJson(audicaFile.desc));

                var      workFolder = Path.Combine(Application.streamingAssetsPath, "Ogg2Audica");
                MidiFile songMidi   = MidiFile.Read(Path.Combine(workFolder, "songtemplate.mid"));

                using (var tempoMapManager = new TempoMapManager(new TicksPerQuarterNoteTimeDivision(480)))
                {
                    float    oneMinuteInMicroseconds = 60000000f;
                    TempoMap tempoMap = tempoMapManager.TempoMap;

                    foreach (var tempo in audicaFile.desc.tempoList)
                    {
                        tempoMapManager.SetTempo(new MetricTimeSpan((long)(tempo.time * 1000000)), new Tempo((long)(oneMinuteInMicroseconds / tempo.bpm)));
                    }

                    songMidi.ReplaceTempoMap(tempoMap);
                }

                songMidi.Write(Path.Combine(workFolder, $"{Application.dataPath}/.cache/song.mid"), true, MidiFileFormat.MultiTrack);

                //Remove any files we'll be replacing
                foreach (ZipArchiveEntry entry in archive.Entries)
                {
                    if (entry.ToString() == "expert.cues")
                    {
                        archive.RemoveEntry(entry);
                    }
                    else if (entry.ToString() == "song.desc")
                    {
                        archive.RemoveEntry(entry);
                    }
                    else if (entry.ToString() == "song.mid")
                    {
                        archive.RemoveEntry(entry);
                    }
                    else if (entry.ToString() == "advanced.cues")
                    {
                        archive.RemoveEntry(entry);
                    }
                    else if (entry.ToString() == "moderate.cues")
                    {
                        archive.RemoveEntry(entry);
                    }
                    else if (entry.ToString() == "beginner.cues")
                    {
                        archive.RemoveEntry(entry);
                    }
                }
                if (expert)
                {
                    archive.AddEntry("expert.cues", $"{Application.dataPath}/.cache/expert-new.cues");
                }
                if (advanced)
                {
                    archive.AddEntry("advanced.cues", $"{Application.dataPath}/.cache/advanced-new.cues");
                }
                if (standard)
                {
                    archive.AddEntry("moderate.cues", $"{Application.dataPath}/.cache/moderate-new.cues");
                }
                if (easy)
                {
                    archive.AddEntry("beginner.cues", $"{Application.dataPath}/.cache/beginner-new.cues");
                }

                archive.AddEntry("song.desc", $"{Application.dataPath}/.cache/song-new.desc");
                archive.AddEntry("song.mid", $"{Application.dataPath}/.cache/song.mid");
                archive.SaveTo(audicaFile.filepath + ".temp", SharpCompress.Common.CompressionType.None);
                archive.Dispose();
            }
            File.Delete(audicaFile.filepath);
            File.Move(audicaFile.filepath + ".temp", audicaFile.filepath);


            Debug.Log("Export finished.");
        }