diff --git a/MidiMetronome.asmdef b/MidiMetronome.asmdef new file mode 100644 index 0000000..ee9bf92 --- /dev/null +++ b/MidiMetronome.asmdef @@ -0,0 +1,16 @@ +{ + "name": "MidiMetronome", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "Melanchall.DryWetMidi.dll" + ], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/MidiMetronome.asmdef.meta b/MidiMetronome.asmdef.meta new file mode 100644 index 0000000..cfab7c3 --- /dev/null +++ b/MidiMetronome.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2ce58dac85564d940bca6af6951ba829 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests.meta b/Utility.Tests.meta new file mode 100644 index 0000000..e087de2 --- /dev/null +++ b/Utility.Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 773a892ca6fa2954e963ced7c5656984 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/GeneralTests.cs b/Utility.Tests/GeneralTests.cs new file mode 100644 index 0000000..f7ab3d2 --- /dev/null +++ b/Utility.Tests/GeneralTests.cs @@ -0,0 +1,70 @@ +using MidiMetronome; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using UnityEditor; +using UnityEngine; + +public class GeneralTests +{ + readonly string[] MidiTestFiles = new string[] + { + "MIDI_sample", + "darude-sandstorm", + "dr.dre-still", + "Under-The-Sea-(From-'The-Little-Mermaid')" + }; + + [Test] + public void Dev() + { + var assets = AssetDatabase.FindAssets(nameof(GeneralTests)) + .Select(guid => AssetDatabase.GUIDToAssetPath(guid)) + .Select(path => AssetDatabase.LoadAssetAtPath(path)) + .Distinct(); + + var script = assets.FirstOrDefault(); + + if (script == null) + throw new Exception($"Can't locate the script in the project!"); + + var path = AssetDatabase.GetAssetPath(script); + var root = Path.GetDirectoryName(path); + var sampleDir = $@"{root}\Samples"; + + var midiFiles = Directory.GetFiles(sampleDir, "*.mid") + .Select(x => new { name = Path.GetFileName(x), rawMidi = File.ReadAllBytes(x) }); + + foreach (var x in midiFiles) + TestMidi(x.rawMidi, x.name); + } + void TestMidi(byte[] rawMidi, string name) + { + + TickInfo[] ticks = null; + + try + { + ticks = MetronomeUtility.GenerateBeats(rawMidi); + } + catch (Exception e) + { + Debug.LogError(name); + Debug.LogException(e); + } + + if (ticks == null) + return; + + Debug.Log($"{name}"); + + foreach (var x in ticks) + { + Debug.Log($"[{x.BPM:F0}] {x.Time:0.###}s"); + } + + Debug.Log("======================"); + } +} diff --git a/Utility.Tests/GeneralTests.cs.meta b/Utility.Tests/GeneralTests.cs.meta new file mode 100644 index 0000000..6903257 --- /dev/null +++ b/Utility.Tests/GeneralTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9bb0bdf638572e540a48d0c90761d586 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/MidiMetronome.Tests.asmdef b/Utility.Tests/MidiMetronome.Tests.asmdef new file mode 100644 index 0000000..8061d9c --- /dev/null +++ b/Utility.Tests/MidiMetronome.Tests.asmdef @@ -0,0 +1,21 @@ +{ + "name": "MidiMetronome.Tests", + "rootNamespace": "", + "references": [ + "MidiMetronome" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "Melanchall.DryWetMidi.dll", + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Utility.Tests/MidiMetronome.Tests.asmdef.meta b/Utility.Tests/MidiMetronome.Tests.asmdef.meta new file mode 100644 index 0000000..b8838bc --- /dev/null +++ b/Utility.Tests/MidiMetronome.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 2175f28bb5fcc24449ed10a2281c3c38 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/Samples.meta b/Utility.Tests/Samples.meta new file mode 100644 index 0000000..a6087c6 --- /dev/null +++ b/Utility.Tests/Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 15063485ed1d2a24090c113b46cef0b9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/Samples/climb.mid b/Utility.Tests/Samples/climb.mid new file mode 100644 index 0000000..bb9f5ca Binary files /dev/null and b/Utility.Tests/Samples/climb.mid differ diff --git a/Utility.Tests/Samples/climb.mid.meta b/Utility.Tests/Samples/climb.mid.meta new file mode 100644 index 0000000..b869c5e --- /dev/null +++ b/Utility.Tests/Samples/climb.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b229da924703af34fb64d40aad890923 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples.meta b/Utility.Tests/~Samples.meta new file mode 100644 index 0000000..93a4afb --- /dev/null +++ b/Utility.Tests/~Samples.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3679e1220ea082446b8a67d590f78f80 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Ahfat01.MID b/Utility.Tests/~Samples/Ahfat01.MID new file mode 100644 index 0000000..d1dc52e Binary files /dev/null and b/Utility.Tests/~Samples/Ahfat01.MID differ diff --git a/Utility.Tests/~Samples/Ahfat01.MID.meta b/Utility.Tests/~Samples/Ahfat01.MID.meta new file mode 100644 index 0000000..2700ae8 --- /dev/null +++ b/Utility.Tests/~Samples/Ahfat01.MID.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 24b6d037d6976cc4999a26ed7a356fa3 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Ahfat02.MID b/Utility.Tests/~Samples/Ahfat02.MID new file mode 100644 index 0000000..914ba0e Binary files /dev/null and b/Utility.Tests/~Samples/Ahfat02.MID differ diff --git a/Utility.Tests/~Samples/Ahfat02.MID.meta b/Utility.Tests/~Samples/Ahfat02.MID.meta new file mode 100644 index 0000000..d4b427d --- /dev/null +++ b/Utility.Tests/~Samples/Ahfat02.MID.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dec73354dafa1b94bbddceb1b17fea17 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Ahfat03.MID b/Utility.Tests/~Samples/Ahfat03.MID new file mode 100644 index 0000000..39c873b Binary files /dev/null and b/Utility.Tests/~Samples/Ahfat03.MID differ diff --git a/Utility.Tests/~Samples/Ahfat03.MID.meta b/Utility.Tests/~Samples/Ahfat03.MID.meta new file mode 100644 index 0000000..597d3b6 --- /dev/null +++ b/Utility.Tests/~Samples/Ahfat03.MID.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 23c59ddb525c9ef47924bcb598b3ddb2 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Ahfat04.MID b/Utility.Tests/~Samples/Ahfat04.MID new file mode 100644 index 0000000..142f694 Binary files /dev/null and b/Utility.Tests/~Samples/Ahfat04.MID differ diff --git a/Utility.Tests/~Samples/Ahfat04.MID.meta b/Utility.Tests/~Samples/Ahfat04.MID.meta new file mode 100644 index 0000000..95fd403 --- /dev/null +++ b/Utility.Tests/~Samples/Ahfat04.MID.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 97d1ee8dcbc7eaa4aa9ddda8fc4efff1 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid b/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid new file mode 100644 index 0000000..fb2ba4f Binary files /dev/null and b/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid differ diff --git a/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid.meta b/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid.meta new file mode 100644 index 0000000..b19ef14 --- /dev/null +++ b/Utility.Tests/~Samples/Blink_182_-_All_The_Small_Things_.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d41a29bc471cd12429ae17b2ea40dd35 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid b/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid new file mode 100644 index 0000000..5572e99 Binary files /dev/null and b/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid differ diff --git a/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid.meta b/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid.meta new file mode 100644 index 0000000..40486d6 --- /dev/null +++ b/Utility.Tests/~Samples/Carter_Family_Wildwood_Flower.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 212af180e7f9c6942af30c983b86867b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Cherubichymn.mid b/Utility.Tests/~Samples/Cherubichymn.mid new file mode 100644 index 0000000..7f995de Binary files /dev/null and b/Utility.Tests/~Samples/Cherubichymn.mid differ diff --git a/Utility.Tests/~Samples/Cherubichymn.mid.meta b/Utility.Tests/~Samples/Cherubichymn.mid.meta new file mode 100644 index 0000000..dc2850b --- /dev/null +++ b/Utility.Tests/~Samples/Cherubichymn.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cd450df9c05e7114294659977d1bfeeb +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid b/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid new file mode 100644 index 0000000..00d5cca Binary files /dev/null and b/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid differ diff --git a/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid.meta b/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid.meta new file mode 100644 index 0000000..5740320 --- /dev/null +++ b/Utility.Tests/~Samples/Delerium - Silence (Tiesto Remix).mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: de8ef154fce2a994d93873fe1531abcb +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Don't be cruel L.mid b/Utility.Tests/~Samples/Don't be cruel L.mid new file mode 100644 index 0000000..7ade8bf Binary files /dev/null and b/Utility.Tests/~Samples/Don't be cruel L.mid differ diff --git a/Utility.Tests/~Samples/Don't be cruel L.mid.meta b/Utility.Tests/~Samples/Don't be cruel L.mid.meta new file mode 100644 index 0000000..798a0a3 --- /dev/null +++ b/Utility.Tests/~Samples/Don't be cruel L.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 3fc1aa738bb9291468bbe5abe0ba8a65 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid b/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid new file mode 100644 index 0000000..8767d81 Binary files /dev/null and b/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid differ diff --git a/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid.meta b/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid.meta new file mode 100644 index 0000000..14c6c40 --- /dev/null +++ b/Utility.Tests/~Samples/Dr Dre - Still Dre (1).mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5fcf1468a72ec8649b3b527d4ad88f78 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid b/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid new file mode 100644 index 0000000..562af69 Binary files /dev/null and b/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid differ diff --git a/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid.meta b/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid.meta new file mode 100644 index 0000000..1e7ebe1 --- /dev/null +++ b/Utility.Tests/~Samples/Eine-Kleine-Nachtmusik1.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 730dbdb4ebf813a4f9291709637a81dc +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/EvilWays3.mid b/Utility.Tests/~Samples/EvilWays3.mid new file mode 100644 index 0000000..34a8953 Binary files /dev/null and b/Utility.Tests/~Samples/EvilWays3.mid differ diff --git a/Utility.Tests/~Samples/EvilWays3.mid.meta b/Utility.Tests/~Samples/EvilWays3.mid.meta new file mode 100644 index 0000000..9be6bf6 --- /dev/null +++ b/Utility.Tests/~Samples/EvilWays3.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 41c2e7eca78883f4d911533a52c7830d +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/FZero - Ending.mid b/Utility.Tests/~Samples/FZero - Ending.mid new file mode 100644 index 0000000..71d470d Binary files /dev/null and b/Utility.Tests/~Samples/FZero - Ending.mid differ diff --git a/Utility.Tests/~Samples/FZero - Ending.mid.meta b/Utility.Tests/~Samples/FZero - Ending.mid.meta new file mode 100644 index 0000000..7514e75 --- /dev/null +++ b/Utility.Tests/~Samples/FZero - Ending.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: eb6e76c9db53de744bd95bd89e265174 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid b/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid new file mode 100644 index 0000000..381acaf Binary files /dev/null and b/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid differ diff --git a/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid.meta b/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid.meta new file mode 100644 index 0000000..e8830df --- /dev/null +++ b/Utility.Tests/~Samples/Freestylers - Cracks (Flux Pavillion Remix).mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 1a47eee52f364da41a998e9cbc6f85ea +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid b/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid new file mode 100644 index 0000000..e554c9e Binary files /dev/null and b/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid differ diff --git a/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid.meta b/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid.meta new file mode 100644 index 0000000..3458c30 --- /dev/null +++ b/Utility.Tests/~Samples/Give-Me-All-Your-Love.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: da68a9494b560f84d88077219a3e3bc7 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/K074.MID b/Utility.Tests/~Samples/K074.MID new file mode 100644 index 0000000..1608f60 Binary files /dev/null and b/Utility.Tests/~Samples/K074.MID differ diff --git a/Utility.Tests/~Samples/K074.MID.meta b/Utility.Tests/~Samples/K074.MID.meta new file mode 100644 index 0000000..6fc7990 --- /dev/null +++ b/Utility.Tests/~Samples/K074.MID.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e79d2bbee48a01c47998040b46644da2 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/MIDI_sample.mid b/Utility.Tests/~Samples/MIDI_sample.mid new file mode 100644 index 0000000..a52838c Binary files /dev/null and b/Utility.Tests/~Samples/MIDI_sample.mid differ diff --git a/Utility.Tests/~Samples/MIDI_sample.mid.meta b/Utility.Tests/~Samples/MIDI_sample.mid.meta new file mode 100644 index 0000000..39298cb --- /dev/null +++ b/Utility.Tests/~Samples/MIDI_sample.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e5024b5e8be561d4fa1e2567d54a06e4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Moby - We are all made of stars.mid b/Utility.Tests/~Samples/Moby - We are all made of stars.mid new file mode 100644 index 0000000..b90528a Binary files /dev/null and b/Utility.Tests/~Samples/Moby - We are all made of stars.mid differ diff --git a/Utility.Tests/~Samples/Moby - We are all made of stars.mid.meta b/Utility.Tests/~Samples/Moby - We are all made of stars.mid.meta new file mode 100644 index 0000000..4e7b224 --- /dev/null +++ b/Utility.Tests/~Samples/Moby - We are all made of stars.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b24211b6e6474c843a457d11f4cbb2d4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid b/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid new file mode 100644 index 0000000..6d7716f Binary files /dev/null and b/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid differ diff --git a/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid.meta b/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid.meta new file mode 100644 index 0000000..eecabe9 --- /dev/null +++ b/Utility.Tests/~Samples/Super Mario Galaxy - Battlerock Galaxy.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f61c5029781cc4c4e92b5775e999e81b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid b/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid new file mode 100644 index 0000000..0c14a33 Binary files /dev/null and b/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid differ diff --git a/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid.meta b/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid.meta new file mode 100644 index 0000000..d22c1c3 --- /dev/null +++ b/Utility.Tests/~Samples/The-Eyes-Of-Jenny.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 6ad8247b6af402646b09e0153f1e42cd +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid b/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid new file mode 100644 index 0000000..e434479 Binary files /dev/null and b/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid differ diff --git a/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid.meta b/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid.meta new file mode 100644 index 0000000..3ef4de2 --- /dev/null +++ b/Utility.Tests/~Samples/Tiesto - Theme From Norefjell.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 0b488de6855355f4a81a7ba5f70c82d5 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid b/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid new file mode 100644 index 0000000..92d2b13 Binary files /dev/null and b/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid differ diff --git a/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid.meta b/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid.meta new file mode 100644 index 0000000..325cfbc --- /dev/null +++ b/Utility.Tests/~Samples/Under-The-Sea-(From-'The-Little-Mermaid')-1.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e8208ce47d02e5c40847a569b3e6dd39 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/WalkDon'tRun.mid b/Utility.Tests/~Samples/WalkDon'tRun.mid new file mode 100644 index 0000000..babf178 Binary files /dev/null and b/Utility.Tests/~Samples/WalkDon'tRun.mid differ diff --git a/Utility.Tests/~Samples/WalkDon'tRun.mid.meta b/Utility.Tests/~Samples/WalkDon'tRun.mid.meta new file mode 100644 index 0000000..3018c62 --- /dev/null +++ b/Utility.Tests/~Samples/WalkDon'tRun.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 8121fda7d9370be49a1d37f9ca719463 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Wayout.mid b/Utility.Tests/~Samples/Wayout.mid new file mode 100644 index 0000000..14480c7 Binary files /dev/null and b/Utility.Tests/~Samples/Wayout.mid differ diff --git a/Utility.Tests/~Samples/Wayout.mid.meta b/Utility.Tests/~Samples/Wayout.mid.meta new file mode 100644 index 0000000..5ec21c7 --- /dev/null +++ b/Utility.Tests/~Samples/Wayout.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: f50384ba50d2c724291ab1577a78ab62 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid b/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid new file mode 100644 index 0000000..56ac9b3 Binary files /dev/null and b/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid differ diff --git a/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid.meta b/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid.meta new file mode 100644 index 0000000..574232a --- /dev/null +++ b/Utility.Tests/~Samples/Wild_Cherry_-_Play_That_Funky_Music.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cccf9bfed632ba745b4a181d274af0d4 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/WoO055 Prelude.mid b/Utility.Tests/~Samples/WoO055 Prelude.mid new file mode 100644 index 0000000..1031f3d Binary files /dev/null and b/Utility.Tests/~Samples/WoO055 Prelude.mid differ diff --git a/Utility.Tests/~Samples/WoO055 Prelude.mid.meta b/Utility.Tests/~Samples/WoO055 Prelude.mid.meta new file mode 100644 index 0000000..74de08e --- /dev/null +++ b/Utility.Tests/~Samples/WoO055 Prelude.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 40ded738c6d9ad34f8f4fd178473aa98 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/ab.mid b/Utility.Tests/~Samples/ab.mid new file mode 100644 index 0000000..171b390 Binary files /dev/null and b/Utility.Tests/~Samples/ab.mid differ diff --git a/Utility.Tests/~Samples/ab.mid.meta b/Utility.Tests/~Samples/ab.mid.meta new file mode 100644 index 0000000..af3662b --- /dev/null +++ b/Utility.Tests/~Samples/ab.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 776845e8e9509634489ad229fdeee808 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/bilyjean.mid b/Utility.Tests/~Samples/bilyjean.mid new file mode 100644 index 0000000..accd4f5 Binary files /dev/null and b/Utility.Tests/~Samples/bilyjean.mid differ diff --git a/Utility.Tests/~Samples/bilyjean.mid.meta b/Utility.Tests/~Samples/bilyjean.mid.meta new file mode 100644 index 0000000..d439c0f --- /dev/null +++ b/Utility.Tests/~Samples/bilyjean.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b4b56ed884f5b3840aab2c90904e432f +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/blitzkrieg.mid b/Utility.Tests/~Samples/blitzkrieg.mid new file mode 100644 index 0000000..38896f6 Binary files /dev/null and b/Utility.Tests/~Samples/blitzkrieg.mid differ diff --git a/Utility.Tests/~Samples/blitzkrieg.mid.meta b/Utility.Tests/~Samples/blitzkrieg.mid.meta new file mode 100644 index 0000000..2f808f9 --- /dev/null +++ b/Utility.Tests/~Samples/blitzkrieg.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 35c73a5a1e9ea334689c4ab30521bf9e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/darude-sandstorm.mid b/Utility.Tests/~Samples/darude-sandstorm.mid new file mode 100644 index 0000000..b112d62 Binary files /dev/null and b/Utility.Tests/~Samples/darude-sandstorm.mid differ diff --git a/Utility.Tests/~Samples/darude-sandstorm.mid.meta b/Utility.Tests/~Samples/darude-sandstorm.mid.meta new file mode 100644 index 0000000..624fc27 --- /dev/null +++ b/Utility.Tests/~Samples/darude-sandstorm.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: caf189b33a85c8044b6a3fd91defdeed +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/fragosyr.mid b/Utility.Tests/~Samples/fragosyr.mid new file mode 100644 index 0000000..aac574c Binary files /dev/null and b/Utility.Tests/~Samples/fragosyr.mid differ diff --git a/Utility.Tests/~Samples/fragosyr.mid.meta b/Utility.Tests/~Samples/fragosyr.mid.meta new file mode 100644 index 0000000..107388b --- /dev/null +++ b/Utility.Tests/~Samples/fragosyr.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 44a88db4a9cb9f643ad2625bf62b349c +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/himno505.mid b/Utility.Tests/~Samples/himno505.mid new file mode 100644 index 0000000..0eb4ff0 Binary files /dev/null and b/Utility.Tests/~Samples/himno505.mid differ diff --git a/Utility.Tests/~Samples/himno505.mid.meta b/Utility.Tests/~Samples/himno505.mid.meta new file mode 100644 index 0000000..ad7062d --- /dev/null +++ b/Utility.Tests/~Samples/himno505.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 4bf0b5b3a50d80348b648cf6718ff08b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/jhh53iltt.mid b/Utility.Tests/~Samples/jhh53iltt.mid new file mode 100644 index 0000000..6476b4f Binary files /dev/null and b/Utility.Tests/~Samples/jhh53iltt.mid differ diff --git a/Utility.Tests/~Samples/jhh53iltt.mid.meta b/Utility.Tests/~Samples/jhh53iltt.mid.meta new file mode 100644 index 0000000..eb2bea6 --- /dev/null +++ b/Utility.Tests/~Samples/jhh53iltt.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 30bd309b21ee59e4bb526b57d907befb +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/nu_xuan_hong.mid b/Utility.Tests/~Samples/nu_xuan_hong.mid new file mode 100644 index 0000000..49ec25b Binary files /dev/null and b/Utility.Tests/~Samples/nu_xuan_hong.mid differ diff --git a/Utility.Tests/~Samples/nu_xuan_hong.mid.meta b/Utility.Tests/~Samples/nu_xuan_hong.mid.meta new file mode 100644 index 0000000..398ca2b --- /dev/null +++ b/Utility.Tests/~Samples/nu_xuan_hong.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: cbe5b12dfba517041ae14ab44687828b +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.Tests/~Samples/whitxmas.mid b/Utility.Tests/~Samples/whitxmas.mid new file mode 100644 index 0000000..5ce6ae5 Binary files /dev/null and b/Utility.Tests/~Samples/whitxmas.mid differ diff --git a/Utility.Tests/~Samples/whitxmas.mid.meta b/Utility.Tests/~Samples/whitxmas.mid.meta new file mode 100644 index 0000000..0690b94 --- /dev/null +++ b/Utility.Tests/~Samples/whitxmas.mid.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d57be8cbabc8bb9469c3c0da02903738 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility.meta b/Utility.meta new file mode 100644 index 0000000..88dd644 --- /dev/null +++ b/Utility.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a77e4c3667c2a4d4fa3451dda3b9ace4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Utility/MetronomeUtility.cs b/Utility/MetronomeUtility.cs new file mode 100644 index 0000000..850c299 --- /dev/null +++ b/Utility/MetronomeUtility.cs @@ -0,0 +1,126 @@ +using Melanchall.DryWetMidi.Core; +using Melanchall.DryWetMidi.Interaction; +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace MidiMetronome +{ + public static class MetronomeUtility + { + public static TickInfo[] GenerateBeats(string path) => GenerateBeats(MidiFile.Read(path)); + public static TickInfo[] GenerateBeats(byte[] raw) + { + using (MemoryStream ms = new MemoryStream(raw)) + return GenerateBeats(MidiFile.Read(ms)); + } + /// + /// + /// + /// + /// Sampling interval in seconds + /// + public static TickInfo[] GenerateBeats(MidiFile midi) + { + //Tempo map contains all tempo and duration information (sort of a timeline) + var tempoMap = midi.GetTempoMap(); + + //Total duration of the midi file + TimeSpan duration = midi.GetDuration(); + + //Buffer to contain all + TickInfo[] changes = null; + + var rawChanges = tempoMap.GetTempoChanges(); + changes = rawChanges.Select(x => new TickInfo().From(x, tempoMap)) + .ToArray(); + + if (changes == null) + { + var initialTempo = tempoMap.GetTempoAtTime(new MetricTimeSpan()); + changes = new TickInfo[] { + new TickInfo() { BPM = initialTempo.BeatsPerMinute } + }; + } + + List ticks = new(); + + for (int i = 0; i < changes.Length; i++) + { + bool isLast = (i + 1) >= changes.Length; + bool isFirst = i == 0; + + + TickInfo current = changes[i]; + + TickInfo next; + if (isLast) + { + next.BPM = current.BPM; + next.Time = duration.TotalSeconds; + } + else + next = changes[i + 1]; + + // How far is the metronome in its cycle + double progress = next.Time % current.BPM_Seconds; + + // [First tick] + if(isFirst) + { + TickInfo firstTick = new() + { + Time = 0, + BPM = current.BPM + }; + ticks.Add(firstTick); + } + + // [All full ticks] - fit as many full beats inside the duration between current and next + double fullStep = current.BPM_Seconds; + + double fullSegmentDuration = next.Time - current.Time; + int fullSegmentTicksCount = (int)(fullSegmentDuration / current.BPM); + for (int seg = 1; seg <= fullSegmentTicksCount; seg++) + { + TickInfo currentTick = new() + { + Time = current.Time + current.BPM_Seconds * seg, + BPM = current.BPM + }; + ticks.Add(currentTick); + } + + // Inset the first tick of the new tempo + TickInfo nextSegmentTick = new() + { + Time = next.Time, + BPM = next.BPM + }; + ticks.Add(nextSegmentTick); + } + + return ticks.ToArray(); + } + } + + public struct TickInfo + { + public double Time; + public double BPM; + public double BPM_Seconds => BPM / 60d; + + public TickInfo From(ValueChange valueChange, TempoMap map) + { + var seconds = TimeConverter.ConvertTo(valueChange.Time, map); + + Time = seconds.TotalSeconds; + BPM = valueChange.Value.BeatsPerMinute; + + return this; + } + } +} \ No newline at end of file diff --git a/Utility/MetronomeUtility.cs.meta b/Utility/MetronomeUtility.cs.meta new file mode 100644 index 0000000..bbcc162 --- /dev/null +++ b/Utility/MetronomeUtility.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 40ee315349d02cd4b912b6ace7a07852 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: