Пример #1
0
        public static void UpdateBpm(MidiFile rawMidi, SongItem midi)
        {
            if (rawMidi == null)
            {
                Debug.LogError("Cannot find the midi file");
                return;
            }
            midi.notes.Clear();
            if (midi.bpm <= 0)
            {
                return;
            }
            var tempoMap = TempoMap.Create(Tempo.FromBeatsPerMinute(midi.bpm));

            foreach (var note in rawMidi.GetNotes())
            {
                midi.notes.Add(new SongItem.MidiNote()
                {
                    noteName   = ParseEnum <SongItem.NoteName>(note.NoteName.ToString()),
                    noteOctave = note.Octave,
                    time       = GetMetricTimeSpanTotal(note.TimeAs <MetricTimeSpan>(tempoMap)),
                    noteLength = GetMetricTimeSpanTotal(note.LengthAs <MetricTimeSpan>(tempoMap))
                });
            }
            EditorUtility.SetDirty(midi);
        }
Пример #2
0
        public static void ExportMsb(Stream dataStream, string outPath)
        {
            var file = MsbFile.Read(dataStream);

            var midiFile = new MidiFile();

            var tempoMap = TempoMap.Create(new TicksPerQuarterNoteTimeDivision(960),
                                           Tempo.FromBeatsPerMinute((int)file.BpmEntries[0].Bpm));

            foreach (var score in file.ScoreEntries)
            {
                var track = new TrackChunk();

                var scoreNotes = new List <Note>();

                foreach (var bar in score.Bars)
                {
                    scoreNotes.Add(new Note(new SevenBitNumber((byte)(bar.Note + 24)), bar.Length, bar.Offset));
                }

                track.AddNotes(scoreNotes);

                midiFile.Chunks.Add(track);
            }

            midiFile.ReplaceTempoMap(tempoMap);

            midiFile.Write(outPath);
        }
Пример #3
0
        public void Create_TimeSignature()
        {
            var expectedTimeSignature = new TimeSignature(3, 8);

            TestSimpleTempoMap(TempoMap.Create(expectedTimeSignature),
                               new TicksPerQuarterNoteTimeDivision(),
                               Tempo.Default,
                               expectedTimeSignature);
        }
Пример #4
0
        public void Create_Tempo()
        {
            var expectedTempo = new Tempo(123456);

            TestSimpleTempoMap(TempoMap.Create(expectedTempo),
                               new TicksPerQuarterNoteTimeDivision(),
                               expectedTempo,
                               TimeSignature.Default);
        }
Пример #5
0
        public void GetTempoAtTime_NonDefaultTempoMap_SingleChangeAtStart_GetAtMiddle()
        {
            var microsecondsPerQuarterNote = 100000;

            var tempoMap = TempoMap.Create(new Tempo(microsecondsPerQuarterNote));
            var tempo    = tempoMap.GetTempoAtTime(new MetricTimeSpan(0, 0, 1));

            Assert.AreEqual(new Tempo(microsecondsPerQuarterNote), tempo, "Tempo is invalid.");
        }
Пример #6
0
        public void GetBeatLength_ConstantTimeSignature(long bars, int timeSignatureNumerator, int timeSignatureDenominator)
        {
            const short ticksPerQuarterNote = 100;

            var tempoMap = TempoMap.Create(new TicksPerQuarterNoteTimeDivision(ticksPerQuarterNote), new TimeSignature(timeSignatureNumerator, timeSignatureDenominator));
            var length   = BarBeatUtilities.GetBeatLength(bars, tempoMap);

            Assert.AreEqual(ticksPerQuarterNote * 4 / timeSignatureDenominator, length, "Beat length is invalid.");
        }
Пример #7
0
        public void Create_Tempo_TimeSignature()
        {
            var expectedTempo         = Tempo.FromBeatsPerMinute(123);
            var expectedTimeSignature = new TimeSignature(3, 8);

            TestSimpleTempoMap(TempoMap.Create(expectedTempo, expectedTimeSignature),
                               new TicksPerQuarterNoteTimeDivision(),
                               expectedTempo,
                               expectedTimeSignature);
        }
Пример #8
0
        public void GetTimeSignatureAtTime_NonDefaultTempoMap_SingleChangeAtStart_GetAtMiddle()
        {
            var numerator   = 1;
            var denominator = 16;

            var tempoMap      = TempoMap.Create(new TimeSignature(numerator, denominator));
            var timeSignature = tempoMap.GetTimeSignatureAtTime(new MetricTimeSpan(0, 0, 1));

            Assert.AreEqual(new TimeSignature(numerator, denominator), timeSignature, "Time signature is invalid.");
        }
        public MidiFile Build()
        {
            var midiFile = new MidiFile(_trackChunk);

            //1000 milliseconds in a second so using this should allow for timing with millisecond deltas
            var tempoMap = TempoMap.Create(new TicksPerQuarterNoteTimeDivision(1000), Tempo.FromBeatsPerMinute(60));

            midiFile.ReplaceTempoMap(tempoMap);

            return(midiFile);
        }
Пример #10
0
        public void GetTempoChanges_SingleChange_AtStart()
        {
            var microsecondsPerQuarterNote = 100000;

            var tempoMap = TempoMap.Create(new Tempo(microsecondsPerQuarterNote));
            var changes  = tempoMap.GetTempoChanges();

            Assert.AreEqual(1, changes.Count(), "Count of tempo changes is invalid.");

            var change = changes.First();

            Assert.AreEqual(0, change.Time, "Time of change is invalid.");
            Assert.AreEqual(new Tempo(microsecondsPerQuarterNote), change.Value, "Tempo of change is invalid.");
        }
Пример #11
0
        public void GetTimeSignatureChanges_SingleChange_AtStart()
        {
            var numerator   = 2;
            var denominator = 16;

            var tempoMap = TempoMap.Create(new TimeSignature(numerator, denominator));
            var changes  = tempoMap.GetTimeSignatureChanges();

            Assert.AreEqual(1, changes.Count(), "Count of time signature changes is invalid.");

            var change = changes.First();

            Assert.AreEqual(0, change.Time, "Time of change is invalid.");
            Assert.AreEqual(new TimeSignature(numerator, denominator), change.Value, "Time signature of change is invalid.");
        }
Пример #12
0
        public static void UpdateBpm(MidiFile rawMidi, SongItem songItem)
        {
            if (rawMidi == null)
            {
                Debug.LogError("Cannot find the midi file");
                return;
            }
            songItem.notes.Clear();
            var detectedTempoMap = rawMidi.GetTempoMap();
            var tempoMap         = songItem.useCurrentBpmMidiImport ? TempoMap.Create(detectedTempoMap.TimeDivision, Tempo.FromBeatsPerMinute(songItem.bpm), detectedTempoMap.TimeSignature.AtTime(0)) : detectedTempoMap;

            if (!songItem.useCurrentBpmMidiImport)
            {
                songItem.bpm = (int)rawMidi.GetTempoMap().Tempo.AtTime(0).BeatsPerMinute;
            }

            Debug.Log($"Updating Midi Data {tempoMap.TimeDivision}, {songItem.bpm}bpm");

            int count = 0;

            foreach (var note in rawMidi.GetNotes())
            {
                count++;
                var beat       = GetMetricTimeSpanTotal(note.TimeAs <MetricTimeSpan>(tempoMap)) * songItem.bpm / 60;
                var beatLength = GetMetricTimeSpanTotal(note.LengthAs <MetricTimeSpan>(tempoMap)) * songItem.bpm / 60;
                // Debug.Log(RoundToNearestBeat(beat));

                songItem.notes.Add(new SongItem.MidiNote()
                {
                    noteName   = ParseEnum <SongItem.NoteName>(note.NoteName.ToString()),
                    noteOctave = note.Octave,
                    time       = GetMetricTimeSpanTotal(note.TimeAs <MetricTimeSpan>(tempoMap)),
                    noteLength = GetMetricTimeSpanTotal(note.LengthAs <MetricTimeSpan>(tempoMap)),

                    //This two is for recalculating the currect time when the bpm is changed
                    beatIndex       = SongItem.RoundToNearestBeat(beat),
                    beatLengthIndex = SongItem.RoundToNearestBeat(beatLength),
                });
            }
            Debug.Log(count + " Note(s) detected from Midi file");
            EditorUtility.SetDirty(songItem);
        }
Пример #13
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 internal static TempoMap GetMsTempoMap() => TempoMap.Create(new TicksPerQuarterNoteTimeDivision(600), Tempo.FromBeatsPerMinute(100));
Пример #14
0
        public static string Generate(string oggPath, string songID, string songName, string artist, double bpm, string songEndEvent, string author, int offset)
        {
            HandleCache.CheckSaveFolderValid();

            var workFolder = Path.Combine(Application.streamingAssetsPath, "Ogg2Audica");


            string audicaTemplate = Path.Combine(workFolder, ".AudicaTemplate/");

            Encoding encoding = Encoding.GetEncoding("UTF-8");


            //We need to modify the BPM of the song.mid contained in the template audica to match whatever this is.
            File.Delete(Path.Combine(workFolder, "song.mid"));
            MidiFile songMidi = MidiFile.Read(Path.Combine(workFolder, "songtemplate.mid"));

            float oneMinuteInMicroseconds = 60000000f;

            songMidi.ReplaceTempoMap(TempoMap.Create(new Tempo((long)(oneMinuteInMicroseconds / bpm))));
            songMidi.Write(Path.Combine(workFolder, "song.mid"), true, MidiFileFormat.MultiTrack);


            //Generates the mogg into song.mogg, which is moved to the .AudicaTemplate
            File.Delete(Path.Combine(workFolder, "song.mogg"));

            Process          ogg2mogg  = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo();

            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
            startInfo.FileName    = Path.Combine(workFolder, "ogg2mogg.exe");

            string args = $"\"{oggPath}\" \"{workFolder}/song.mogg\"";

            startInfo.Arguments       = args;
            startInfo.UseShellExecute = false;

            ogg2mogg.StartInfo = startInfo;
            ogg2mogg.Start();

            ogg2mogg.WaitForExit();


            //Make the song.desc file;
            File.Delete(Path.Combine(workFolder, "song.desc"));
            SongDesc songDesc = JsonUtility.FromJson <SongDesc>(File.ReadAllText(Path.Combine(workFolder, "songtemplate.desc")));

            songDesc.songID       = songID;
            songDesc.title        = songName;
            songDesc.artist       = artist;
            songDesc.tempo        = (float)bpm;
            songDesc.songEndEvent = songEndEvent;
            songDesc.author       = author;
            songDesc.offset       = offset;
            File.WriteAllText(Path.Combine(workFolder, "song.desc"), JsonUtility.ToJson(songDesc, true));


            //Create the actual audica file and save it to the /saves/ folder
            using (ZipArchive archive = ZipArchive.Create()) {
                archive.AddAllFromDirectory(audicaTemplate);
                archive.AddEntry("song.desc", Path.Combine(workFolder, "song.desc"));
                archive.AddEntry("song.mid", Path.Combine(workFolder, "song.mid"));
                archive.AddEntry("song.mogg", Path.Combine(workFolder, "song.mogg"));


                archive.SaveTo(Path.Combine(Application.dataPath, "saves", songID + ".audica"), SharpCompress.Common.CompressionType.None);
            }

            return(Path.Combine(Application.dataPath, "saves", songID + ".audica"));

            /*
             *
             *      HandleCache.CheckSaveFolderValid();
             *
             *      System.Diagnostics.Process myProcess = new System.Diagnostics.Process();
             *      ProcessStartInfo startInfo = new ProcessStartInfo();
             *      startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
             *      startInfo.FileName = Path.Combine(ogg2AudicaFolder, "Ogg2Audica.exe");
             *
             *      startInfo.Arguments = System.String.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\" \"{4}\" \"{5}\" \"{6}\" \"{7}\"", oggPath, songID, songName, artist, bpm, songEndEvent, mapper, offset);
             *      startInfo.UseShellExecute = true;
             *      startInfo.WorkingDirectory = ogg2AudicaFolder;
             *
             *      myProcess.StartInfo = startInfo;
             *
             *      myProcess.Start();
             *
             *      myProcess.WaitForExit();
             *
             *      File.Move(Path.Combine(ogg2AudicaFolder, "out.audica"), Path.Combine(Application.dataPath, "saves", songID + ".audica"));
             *
             *
             *      return Path.Combine(Application.dataPath, "saves", songID + ".audica");
             */
        }