diff --git a/RhythmGameUtilities.Tests/Mocks/song.json b/RhythmGameUtilities.Tests/Mocks/song.json index a7e7303..1c444c6 100644 --- a/RhythmGameUtilities.Tests/Mocks/song.json +++ b/RhythmGameUtilities.Tests/Mocks/song.json @@ -1 +1 @@ -{"Name":"Example Song","Artist":"Example Artist","Album":"Example Album","Genre":"Example Genre","Year":", 2021","Charter":"Example Charter","Resolution":192,"Difficulty":4,"Offset":0.56,"PreviewStart":45.28,"PreviewEnd":75.28,"MusicStream":"Example Song.ogg","Lyrics":{},"Difficulties":{"Expert":[{"Position":768,"HandPosition":0,"Length":0},{"Position":864,"HandPosition":1,"Length":0},{"Position":864,"HandPosition":5,"Length":0},{"Position":960,"HandPosition":2,"Length":0},{"Position":960,"HandPosition":6,"Length":0},{"Position":1056,"HandPosition":3,"Length":0},{"Position":1152,"HandPosition":4,"Length":0},{"Position":1248,"HandPosition":7,"Length":0}]},"BPM":{"0":88000,"3840":112000,"9984":89600,"22272":112000,"33792":111500,"34560":112000,"42240":111980},"TimeSignatures":{"0":[4],"9984":[2,1],"22272":[4],"69120":[2,1]},"BeatBars":[{"Position":0,"BPM":88000,"TimeSignature":[4]},{"Position":96,"BPM":88000,"TimeSignature":[4]},{"Position":192,"BPM":88000,"TimeSignature":[4]},{"Position":288,"BPM":88000,"TimeSignature":[4]},{"Position":384,"BPM":88000,"TimeSignature":[4]},{"Position":480,"BPM":88000,"TimeSignature":[4]},{"Position":576,"BPM":88000,"TimeSignature":[4]},{"Position":672,"BPM":88000,"TimeSignature":[4]},{"Position":768,"BPM":88000,"TimeSignature":[4]},{"Position":864,"BPM":88000,"TimeSignature":[4]},{"Position":960,"BPM":88000,"TimeSignature":[4]},{"Position":1056,"BPM":88000,"TimeSignature":[4]},{"Position":1152,"BPM":88000,"TimeSignature":[4]},{"Position":1248,"BPM":88000,"TimeSignature":[4]},{"Position":1344,"BPM":88000,"TimeSignature":[4]},{"Position":1440,"BPM":88000,"TimeSignature":[4]},{"Position":1536,"BPM":88000,"TimeSignature":[4]},{"Position":1632,"BPM":88000,"TimeSignature":[4]},{"Position":1728,"BPM":88000,"TimeSignature":[4]},{"Position":1824,"BPM":88000,"TimeSignature":[4]},{"Position":1920,"BPM":88000,"TimeSignature":[4]},{"Position":2016,"BPM":88000,"TimeSignature":[4]},{"Position":2112,"BPM":88000,"TimeSignature":[4]},{"Position":2208,"BPM":88000,"TimeSignature":[4]},{"Position":2304,"BPM":88000,"TimeSignature":[4]},{"Position":2400,"BPM":88000,"TimeSignature":[4]},{"Position":2496,"BPM":88000,"TimeSignature":[4]},{"Position":2592,"BPM":88000,"TimeSignature":[4]},{"Position":2688,"BPM":88000,"TimeSignature":[4]},{"Position":2784,"BPM":88000,"TimeSignature":[4]},{"Position":2880,"BPM":88000,"TimeSignature":[4]},{"Position":2976,"BPM":88000,"TimeSignature":[4]},{"Position":3072,"BPM":88000,"TimeSignature":[4]},{"Position":3168,"BPM":88000,"TimeSignature":[4]},{"Position":3264,"BPM":88000,"TimeSignature":[4]},{"Position":3360,"BPM":88000,"TimeSignature":[4]},{"Position":3456,"BPM":88000,"TimeSignature":[4]},{"Position":3552,"BPM":88000,"TimeSignature":[4]},{"Position":3648,"BPM":88000,"TimeSignature":[4]},{"Position":3744,"BPM":88000,"TimeSignature":[4]},{"Position":3840,"BPM":88000,"TimeSignature":[4]},{"Position":3840,"BPM":112000,"TimeSignature":[4]},{"Position":3936,"BPM":112000,"TimeSignature":[4]},{"Position":4032,"BPM":112000,"TimeSignature":[4]},{"Position":4128,"BPM":112000,"TimeSignature":[4]},{"Position":4224,"BPM":112000,"TimeSignature":[4]},{"Position":4320,"BPM":112000,"TimeSignature":[4]},{"Position":4416,"BPM":112000,"TimeSignature":[4]},{"Position":4512,"BPM":112000,"TimeSignature":[4]},{"Position":4608,"BPM":112000,"TimeSignature":[4]},{"Position":4704,"BPM":112000,"TimeSignature":[4]},{"Position":4800,"BPM":112000,"TimeSignature":[4]},{"Position":4896,"BPM":112000,"TimeSignature":[4]},{"Position":4992,"BPM":112000,"TimeSignature":[4]},{"Position":5088,"BPM":112000,"TimeSignature":[4]},{"Position":5184,"BPM":112000,"TimeSignature":[4]},{"Position":5280,"BPM":112000,"TimeSignature":[4]},{"Position":5376,"BPM":112000,"TimeSignature":[4]},{"Position":5472,"BPM":112000,"TimeSignature":[4]},{"Position":5568,"BPM":112000,"TimeSignature":[4]},{"Position":5664,"BPM":112000,"TimeSignature":[4]},{"Position":5760,"BPM":112000,"TimeSignature":[4]},{"Position":5856,"BPM":112000,"TimeSignature":[4]},{"Position":5952,"BPM":112000,"TimeSignature":[4]},{"Position":6048,"BPM":112000,"TimeSignature":[4]},{"Position":6144,"BPM":112000,"TimeSignature":[4]},{"Position":6240,"BPM":112000,"TimeSignature":[4]},{"Position":6336,"BPM":112000,"TimeSignature":[4]},{"Position":6432,"BPM":112000,"TimeSignature":[4]},{"Position":6528,"BPM":112000,"TimeSignature":[4]},{"Position":6624,"BPM":112000,"TimeSignature":[4]},{"Position":6720,"BPM":112000,"TimeSignature":[4]},{"Position":6816,"BPM":112000,"TimeSignature":[4]},{"Position":6912,"BPM":112000,"TimeSignature":[4]},{"Position":7008,"BPM":112000,"TimeSignature":[4]},{"Position":7104,"BPM":112000,"TimeSignature":[4]},{"Position":7200,"BPM":112000,"TimeSignature":[4]},{"Position":7296,"BPM":112000,"TimeSignature":[4]},{"Position":7392,"BPM":112000,"TimeSignature":[4]},{"Position":7488,"BPM":112000,"TimeSignature":[4]},{"Position":7584,"BPM":112000,"TimeSignature":[4]},{"Position":7680,"BPM":112000,"TimeSignature":[4]},{"Position":7776,"BPM":112000,"TimeSignature":[4]},{"Position":7872,"BPM":112000,"TimeSignature":[4]},{"Position":7968,"BPM":112000,"TimeSignature":[4]},{"Position":8064,"BPM":112000,"TimeSignature":[4]},{"Position":8160,"BPM":112000,"TimeSignature":[4]},{"Position":8256,"BPM":112000,"TimeSignature":[4]},{"Position":8352,"BPM":112000,"TimeSignature":[4]},{"Position":8448,"BPM":112000,"TimeSignature":[4]},{"Position":8544,"BPM":112000,"TimeSignature":[4]},{"Position":8640,"BPM":112000,"TimeSignature":[4]},{"Position":8736,"BPM":112000,"TimeSignature":[4]},{"Position":8832,"BPM":112000,"TimeSignature":[4]},{"Position":8928,"BPM":112000,"TimeSignature":[4]},{"Position":9024,"BPM":112000,"TimeSignature":[4]},{"Position":9120,"BPM":112000,"TimeSignature":[4]},{"Position":9216,"BPM":112000,"TimeSignature":[4]},{"Position":9312,"BPM":112000,"TimeSignature":[4]},{"Position":9408,"BPM":112000,"TimeSignature":[4]},{"Position":9504,"BPM":112000,"TimeSignature":[4]},{"Position":9600,"BPM":112000,"TimeSignature":[4]},{"Position":9696,"BPM":112000,"TimeSignature":[4]},{"Position":9792,"BPM":112000,"TimeSignature":[4]},{"Position":9888,"BPM":112000,"TimeSignature":[4]},{"Position":9984,"BPM":112000,"TimeSignature":[4]},{"Position":9984,"BPM":89600,"TimeSignature":[4]},{"Position":10080,"BPM":89600,"TimeSignature":[4]},{"Position":10176,"BPM":89600,"TimeSignature":[4]},{"Position":10272,"BPM":89600,"TimeSignature":[4]},{"Position":10368,"BPM":89600,"TimeSignature":[4]},{"Position":10464,"BPM":89600,"TimeSignature":[4]},{"Position":10560,"BPM":89600,"TimeSignature":[4]},{"Position":10656,"BPM":89600,"TimeSignature":[4]},{"Position":10752,"BPM":89600,"TimeSignature":[4]},{"Position":10848,"BPM":89600,"TimeSignature":[4]},{"Position":10944,"BPM":89600,"TimeSignature":[4]},{"Position":11040,"BPM":89600,"TimeSignature":[4]},{"Position":11136,"BPM":89600,"TimeSignature":[4]},{"Position":11232,"BPM":89600,"TimeSignature":[4]},{"Position":11328,"BPM":89600,"TimeSignature":[4]},{"Position":11424,"BPM":89600,"TimeSignature":[4]},{"Position":11520,"BPM":89600,"TimeSignature":[4]},{"Position":11616,"BPM":89600,"TimeSignature":[4]},{"Position":11712,"BPM":89600,"TimeSignature":[4]},{"Position":11808,"BPM":89600,"TimeSignature":[4]},{"Position":11904,"BPM":89600,"TimeSignature":[4]},{"Position":12000,"BPM":89600,"TimeSignature":[4]},{"Position":12096,"BPM":89600,"TimeSignature":[4]},{"Position":12192,"BPM":89600,"TimeSignature":[4]},{"Position":12288,"BPM":89600,"TimeSignature":[4]},{"Position":12384,"BPM":89600,"TimeSignature":[4]},{"Position":12480,"BPM":89600,"TimeSignature":[4]},{"Position":12576,"BPM":89600,"TimeSignature":[4]},{"Position":12672,"BPM":89600,"TimeSignature":[4]},{"Position":12768,"BPM":89600,"TimeSignature":[4]},{"Position":12864,"BPM":89600,"TimeSignature":[4]},{"Position":12960,"BPM":89600,"TimeSignature":[4]},{"Position":13056,"BPM":89600,"TimeSignature":[4]},{"Position":13152,"BPM":89600,"TimeSignature":[4]},{"Position":13248,"BPM":89600,"TimeSignature":[4]},{"Position":13344,"BPM":89600,"TimeSignature":[4]},{"Position":13440,"BPM":89600,"TimeSignature":[4]},{"Position":13536,"BPM":89600,"TimeSignature":[4]},{"Position":13632,"BPM":89600,"TimeSignature":[4]},{"Position":13728,"BPM":89600,"TimeSignature":[4]},{"Position":13824,"BPM":89600,"TimeSignature":[4]},{"Position":13920,"BPM":89600,"TimeSignature":[4]},{"Position":14016,"BPM":89600,"TimeSignature":[4]},{"Position":14112,"BPM":89600,"TimeSignature":[4]},{"Position":14208,"BPM":89600,"TimeSignature":[4]},{"Position":14304,"BPM":89600,"TimeSignature":[4]},{"Position":14400,"BPM":89600,"TimeSignature":[4]},{"Position":14496,"BPM":89600,"TimeSignature":[4]},{"Position":14592,"BPM":89600,"TimeSignature":[4]},{"Position":14688,"BPM":89600,"TimeSignature":[4]},{"Position":14784,"BPM":89600,"TimeSignature":[4]},{"Position":14880,"BPM":89600,"TimeSignature":[4]},{"Position":14976,"BPM":89600,"TimeSignature":[4]},{"Position":15072,"BPM":89600,"TimeSignature":[4]},{"Position":15168,"BPM":89600,"TimeSignature":[4]},{"Position":15264,"BPM":89600,"TimeSignature":[4]},{"Position":15360,"BPM":89600,"TimeSignature":[4]},{"Position":15456,"BPM":89600,"TimeSignature":[4]},{"Position":15552,"BPM":89600,"TimeSignature":[4]},{"Position":15648,"BPM":89600,"TimeSignature":[4]},{"Position":15744,"BPM":89600,"TimeSignature":[4]},{"Position":15840,"BPM":89600,"TimeSignature":[4]},{"Position":15936,"BPM":89600,"TimeSignature":[4]},{"Position":16032,"BPM":89600,"TimeSignature":[4]},{"Position":16128,"BPM":89600,"TimeSignature":[4]},{"Position":16224,"BPM":89600,"TimeSignature":[4]},{"Position":16320,"BPM":89600,"TimeSignature":[4]},{"Position":16416,"BPM":89600,"TimeSignature":[4]},{"Position":16512,"BPM":89600,"TimeSignature":[4]},{"Position":16608,"BPM":89600,"TimeSignature":[4]},{"Position":16704,"BPM":89600,"TimeSignature":[4]},{"Position":16800,"BPM":89600,"TimeSignature":[4]},{"Position":16896,"BPM":89600,"TimeSignature":[4]},{"Position":16992,"BPM":89600,"TimeSignature":[4]},{"Position":17088,"BPM":89600,"TimeSignature":[4]},{"Position":17184,"BPM":89600,"TimeSignature":[4]},{"Position":17280,"BPM":89600,"TimeSignature":[4]},{"Position":17376,"BPM":89600,"TimeSignature":[4]},{"Position":17472,"BPM":89600,"TimeSignature":[4]},{"Position":17568,"BPM":89600,"TimeSignature":[4]},{"Position":17664,"BPM":89600,"TimeSignature":[4]},{"Position":17760,"BPM":89600,"TimeSignature":[4]},{"Position":17856,"BPM":89600,"TimeSignature":[4]},{"Position":17952,"BPM":89600,"TimeSignature":[4]},{"Position":18048,"BPM":89600,"TimeSignature":[4]},{"Position":18144,"BPM":89600,"TimeSignature":[4]},{"Position":18240,"BPM":89600,"TimeSignature":[4]},{"Position":18336,"BPM":89600,"TimeSignature":[4]},{"Position":18432,"BPM":89600,"TimeSignature":[4]},{"Position":18528,"BPM":89600,"TimeSignature":[4]},{"Position":18624,"BPM":89600,"TimeSignature":[4]},{"Position":18720,"BPM":89600,"TimeSignature":[4]},{"Position":18816,"BPM":89600,"TimeSignature":[4]},{"Position":18912,"BPM":89600,"TimeSignature":[4]},{"Position":19008,"BPM":89600,"TimeSignature":[4]},{"Position":19104,"BPM":89600,"TimeSignature":[4]},{"Position":19200,"BPM":89600,"TimeSignature":[4]},{"Position":19296,"BPM":89600,"TimeSignature":[4]},{"Position":19392,"BPM":89600,"TimeSignature":[4]},{"Position":19488,"BPM":89600,"TimeSignature":[4]},{"Position":19584,"BPM":89600,"TimeSignature":[4]},{"Position":19680,"BPM":89600,"TimeSignature":[4]},{"Position":19776,"BPM":89600,"TimeSignature":[4]},{"Position":19872,"BPM":89600,"TimeSignature":[4]},{"Position":19968,"BPM":89600,"TimeSignature":[4]},{"Position":20064,"BPM":89600,"TimeSignature":[4]},{"Position":20160,"BPM":89600,"TimeSignature":[4]},{"Position":20256,"BPM":89600,"TimeSignature":[4]},{"Position":20352,"BPM":89600,"TimeSignature":[4]},{"Position":20448,"BPM":89600,"TimeSignature":[4]},{"Position":20544,"BPM":89600,"TimeSignature":[4]},{"Position":20640,"BPM":89600,"TimeSignature":[4]},{"Position":20736,"BPM":89600,"TimeSignature":[4]},{"Position":20832,"BPM":89600,"TimeSignature":[4]},{"Position":20928,"BPM":89600,"TimeSignature":[4]},{"Position":21024,"BPM":89600,"TimeSignature":[4]},{"Position":21120,"BPM":89600,"TimeSignature":[4]},{"Position":21216,"BPM":89600,"TimeSignature":[4]},{"Position":21312,"BPM":89600,"TimeSignature":[4]},{"Position":21408,"BPM":89600,"TimeSignature":[4]},{"Position":21504,"BPM":89600,"TimeSignature":[4]},{"Position":21600,"BPM":89600,"TimeSignature":[4]},{"Position":21696,"BPM":89600,"TimeSignature":[4]},{"Position":21792,"BPM":89600,"TimeSignature":[4]},{"Position":21888,"BPM":89600,"TimeSignature":[4]},{"Position":21984,"BPM":89600,"TimeSignature":[4]},{"Position":22080,"BPM":89600,"TimeSignature":[4]},{"Position":22176,"BPM":89600,"TimeSignature":[4]},{"Position":22272,"BPM":89600,"TimeSignature":[4]},{"Position":22272,"BPM":112000,"TimeSignature":[4]},{"Position":22368,"BPM":112000,"TimeSignature":[4]},{"Position":22464,"BPM":112000,"TimeSignature":[4]},{"Position":22560,"BPM":112000,"TimeSignature":[4]},{"Position":22656,"BPM":112000,"TimeSignature":[4]},{"Position":22752,"BPM":112000,"TimeSignature":[4]},{"Position":22848,"BPM":112000,"TimeSignature":[4]},{"Position":22944,"BPM":112000,"TimeSignature":[4]},{"Position":23040,"BPM":112000,"TimeSignature":[4]},{"Position":23136,"BPM":112000,"TimeSignature":[4]},{"Position":23232,"BPM":112000,"TimeSignature":[4]},{"Position":23328,"BPM":112000,"TimeSignature":[4]},{"Position":23424,"BPM":112000,"TimeSignature":[4]},{"Position":23520,"BPM":112000,"TimeSignature":[4]},{"Position":23616,"BPM":112000,"TimeSignature":[4]},{"Position":23712,"BPM":112000,"TimeSignature":[4]},{"Position":23808,"BPM":112000,"TimeSignature":[4]},{"Position":23904,"BPM":112000,"TimeSignature":[4]},{"Position":24000,"BPM":112000,"TimeSignature":[4]},{"Position":24096,"BPM":112000,"TimeSignature":[4]},{"Position":24192,"BPM":112000,"TimeSignature":[4]},{"Position":24288,"BPM":112000,"TimeSignature":[4]},{"Position":24384,"BPM":112000,"TimeSignature":[4]},{"Position":24480,"BPM":112000,"TimeSignature":[4]},{"Position":24576,"BPM":112000,"TimeSignature":[4]},{"Position":24672,"BPM":112000,"TimeSignature":[4]},{"Position":24768,"BPM":112000,"TimeSignature":[4]},{"Position":24864,"BPM":112000,"TimeSignature":[4]},{"Position":24960,"BPM":112000,"TimeSignature":[4]},{"Position":25056,"BPM":112000,"TimeSignature":[4]},{"Position":25152,"BPM":112000,"TimeSignature":[4]},{"Position":25248,"BPM":112000,"TimeSignature":[4]},{"Position":25344,"BPM":112000,"TimeSignature":[4]},{"Position":25440,"BPM":112000,"TimeSignature":[4]},{"Position":25536,"BPM":112000,"TimeSignature":[4]},{"Position":25632,"BPM":112000,"TimeSignature":[4]},{"Position":25728,"BPM":112000,"TimeSignature":[4]},{"Position":25824,"BPM":112000,"TimeSignature":[4]},{"Position":25920,"BPM":112000,"TimeSignature":[4]},{"Position":26016,"BPM":112000,"TimeSignature":[4]},{"Position":26112,"BPM":112000,"TimeSignature":[4]},{"Position":26208,"BPM":112000,"TimeSignature":[4]},{"Position":26304,"BPM":112000,"TimeSignature":[4]},{"Position":26400,"BPM":112000,"TimeSignature":[4]},{"Position":26496,"BPM":112000,"TimeSignature":[4]},{"Position":26592,"BPM":112000,"TimeSignature":[4]},{"Position":26688,"BPM":112000,"TimeSignature":[4]},{"Position":26784,"BPM":112000,"TimeSignature":[4]},{"Position":26880,"BPM":112000,"TimeSignature":[4]},{"Position":26976,"BPM":112000,"TimeSignature":[4]},{"Position":27072,"BPM":112000,"TimeSignature":[4]},{"Position":27168,"BPM":112000,"TimeSignature":[4]},{"Position":27264,"BPM":112000,"TimeSignature":[4]},{"Position":27360,"BPM":112000,"TimeSignature":[4]},{"Position":27456,"BPM":112000,"TimeSignature":[4]},{"Position":27552,"BPM":112000,"TimeSignature":[4]},{"Position":27648,"BPM":112000,"TimeSignature":[4]},{"Position":27744,"BPM":112000,"TimeSignature":[4]},{"Position":27840,"BPM":112000,"TimeSignature":[4]},{"Position":27936,"BPM":112000,"TimeSignature":[4]},{"Position":28032,"BPM":112000,"TimeSignature":[4]},{"Position":28128,"BPM":112000,"TimeSignature":[4]},{"Position":28224,"BPM":112000,"TimeSignature":[4]},{"Position":28320,"BPM":112000,"TimeSignature":[4]},{"Position":28416,"BPM":112000,"TimeSignature":[4]},{"Position":28512,"BPM":112000,"TimeSignature":[4]},{"Position":28608,"BPM":112000,"TimeSignature":[4]},{"Position":28704,"BPM":112000,"TimeSignature":[4]},{"Position":28800,"BPM":112000,"TimeSignature":[4]},{"Position":28896,"BPM":112000,"TimeSignature":[4]},{"Position":28992,"BPM":112000,"TimeSignature":[4]},{"Position":29088,"BPM":112000,"TimeSignature":[4]},{"Position":29184,"BPM":112000,"TimeSignature":[4]},{"Position":29280,"BPM":112000,"TimeSignature":[4]},{"Position":29376,"BPM":112000,"TimeSignature":[4]},{"Position":29472,"BPM":112000,"TimeSignature":[4]},{"Position":29568,"BPM":112000,"TimeSignature":[4]},{"Position":29664,"BPM":112000,"TimeSignature":[4]},{"Position":29760,"BPM":112000,"TimeSignature":[4]},{"Position":29856,"BPM":112000,"TimeSignature":[4]},{"Position":29952,"BPM":112000,"TimeSignature":[4]},{"Position":30048,"BPM":112000,"TimeSignature":[4]},{"Position":30144,"BPM":112000,"TimeSignature":[4]},{"Position":30240,"BPM":112000,"TimeSignature":[4]},{"Position":30336,"BPM":112000,"TimeSignature":[4]},{"Position":30432,"BPM":112000,"TimeSignature":[4]},{"Position":30528,"BPM":112000,"TimeSignature":[4]},{"Position":30624,"BPM":112000,"TimeSignature":[4]},{"Position":30720,"BPM":112000,"TimeSignature":[4]},{"Position":30816,"BPM":112000,"TimeSignature":[4]},{"Position":30912,"BPM":112000,"TimeSignature":[4]},{"Position":31008,"BPM":112000,"TimeSignature":[4]},{"Position":31104,"BPM":112000,"TimeSignature":[4]},{"Position":31200,"BPM":112000,"TimeSignature":[4]},{"Position":31296,"BPM":112000,"TimeSignature":[4]},{"Position":31392,"BPM":112000,"TimeSignature":[4]},{"Position":31488,"BPM":112000,"TimeSignature":[4]},{"Position":31584,"BPM":112000,"TimeSignature":[4]},{"Position":31680,"BPM":112000,"TimeSignature":[4]},{"Position":31776,"BPM":112000,"TimeSignature":[4]},{"Position":31872,"BPM":112000,"TimeSignature":[4]},{"Position":31968,"BPM":112000,"TimeSignature":[4]},{"Position":32064,"BPM":112000,"TimeSignature":[4]},{"Position":32160,"BPM":112000,"TimeSignature":[4]},{"Position":32256,"BPM":112000,"TimeSignature":[4]},{"Position":32352,"BPM":112000,"TimeSignature":[4]},{"Position":32448,"BPM":112000,"TimeSignature":[4]},{"Position":32544,"BPM":112000,"TimeSignature":[4]},{"Position":32640,"BPM":112000,"TimeSignature":[4]},{"Position":32736,"BPM":112000,"TimeSignature":[4]},{"Position":32832,"BPM":112000,"TimeSignature":[4]},{"Position":32928,"BPM":112000,"TimeSignature":[4]},{"Position":33024,"BPM":112000,"TimeSignature":[4]},{"Position":33120,"BPM":112000,"TimeSignature":[4]},{"Position":33216,"BPM":112000,"TimeSignature":[4]},{"Position":33312,"BPM":112000,"TimeSignature":[4]},{"Position":33408,"BPM":112000,"TimeSignature":[4]},{"Position":33504,"BPM":112000,"TimeSignature":[4]},{"Position":33600,"BPM":112000,"TimeSignature":[4]},{"Position":33696,"BPM":112000,"TimeSignature":[4]},{"Position":33792,"BPM":112000,"TimeSignature":[4]},{"Position":33792,"BPM":111500,"TimeSignature":[4]},{"Position":33888,"BPM":111500,"TimeSignature":[4]},{"Position":33984,"BPM":111500,"TimeSignature":[4]},{"Position":34080,"BPM":111500,"TimeSignature":[4]},{"Position":34176,"BPM":111500,"TimeSignature":[4]},{"Position":34272,"BPM":111500,"TimeSignature":[4]},{"Position":34368,"BPM":111500,"TimeSignature":[4]},{"Position":34464,"BPM":111500,"TimeSignature":[4]},{"Position":34560,"BPM":111500,"TimeSignature":[4]},{"Position":34560,"BPM":112000,"TimeSignature":[4]},{"Position":34656,"BPM":112000,"TimeSignature":[4]},{"Position":34752,"BPM":112000,"TimeSignature":[4]},{"Position":34848,"BPM":112000,"TimeSignature":[4]},{"Position":34944,"BPM":112000,"TimeSignature":[4]},{"Position":35040,"BPM":112000,"TimeSignature":[4]},{"Position":35136,"BPM":112000,"TimeSignature":[4]},{"Position":35232,"BPM":112000,"TimeSignature":[4]},{"Position":35328,"BPM":112000,"TimeSignature":[4]},{"Position":35424,"BPM":112000,"TimeSignature":[4]},{"Position":35520,"BPM":112000,"TimeSignature":[4]},{"Position":35616,"BPM":112000,"TimeSignature":[4]},{"Position":35712,"BPM":112000,"TimeSignature":[4]},{"Position":35808,"BPM":112000,"TimeSignature":[4]},{"Position":35904,"BPM":112000,"TimeSignature":[4]},{"Position":36000,"BPM":112000,"TimeSignature":[4]},{"Position":36096,"BPM":112000,"TimeSignature":[4]},{"Position":36192,"BPM":112000,"TimeSignature":[4]},{"Position":36288,"BPM":112000,"TimeSignature":[4]},{"Position":36384,"BPM":112000,"TimeSignature":[4]},{"Position":36480,"BPM":112000,"TimeSignature":[4]},{"Position":36576,"BPM":112000,"TimeSignature":[4]},{"Position":36672,"BPM":112000,"TimeSignature":[4]},{"Position":36768,"BPM":112000,"TimeSignature":[4]},{"Position":36864,"BPM":112000,"TimeSignature":[4]},{"Position":36960,"BPM":112000,"TimeSignature":[4]},{"Position":37056,"BPM":112000,"TimeSignature":[4]},{"Position":37152,"BPM":112000,"TimeSignature":[4]},{"Position":37248,"BPM":112000,"TimeSignature":[4]},{"Position":37344,"BPM":112000,"TimeSignature":[4]},{"Position":37440,"BPM":112000,"TimeSignature":[4]},{"Position":37536,"BPM":112000,"TimeSignature":[4]},{"Position":37632,"BPM":112000,"TimeSignature":[4]},{"Position":37728,"BPM":112000,"TimeSignature":[4]},{"Position":37824,"BPM":112000,"TimeSignature":[4]},{"Position":37920,"BPM":112000,"TimeSignature":[4]},{"Position":38016,"BPM":112000,"TimeSignature":[4]},{"Position":38112,"BPM":112000,"TimeSignature":[4]},{"Position":38208,"BPM":112000,"TimeSignature":[4]},{"Position":38304,"BPM":112000,"TimeSignature":[4]},{"Position":38400,"BPM":112000,"TimeSignature":[4]},{"Position":38496,"BPM":112000,"TimeSignature":[4]},{"Position":38592,"BPM":112000,"TimeSignature":[4]},{"Position":38688,"BPM":112000,"TimeSignature":[4]},{"Position":38784,"BPM":112000,"TimeSignature":[4]},{"Position":38880,"BPM":112000,"TimeSignature":[4]},{"Position":38976,"BPM":112000,"TimeSignature":[4]},{"Position":39072,"BPM":112000,"TimeSignature":[4]},{"Position":39168,"BPM":112000,"TimeSignature":[4]},{"Position":39264,"BPM":112000,"TimeSignature":[4]},{"Position":39360,"BPM":112000,"TimeSignature":[4]},{"Position":39456,"BPM":112000,"TimeSignature":[4]},{"Position":39552,"BPM":112000,"TimeSignature":[4]},{"Position":39648,"BPM":112000,"TimeSignature":[4]},{"Position":39744,"BPM":112000,"TimeSignature":[4]},{"Position":39840,"BPM":112000,"TimeSignature":[4]},{"Position":39936,"BPM":112000,"TimeSignature":[4]},{"Position":40032,"BPM":112000,"TimeSignature":[4]},{"Position":40128,"BPM":112000,"TimeSignature":[4]},{"Position":40224,"BPM":112000,"TimeSignature":[4]},{"Position":40320,"BPM":112000,"TimeSignature":[4]},{"Position":40416,"BPM":112000,"TimeSignature":[4]},{"Position":40512,"BPM":112000,"TimeSignature":[4]},{"Position":40608,"BPM":112000,"TimeSignature":[4]},{"Position":40704,"BPM":112000,"TimeSignature":[4]},{"Position":40800,"BPM":112000,"TimeSignature":[4]},{"Position":40896,"BPM":112000,"TimeSignature":[4]},{"Position":40992,"BPM":112000,"TimeSignature":[4]},{"Position":41088,"BPM":112000,"TimeSignature":[4]},{"Position":41184,"BPM":112000,"TimeSignature":[4]},{"Position":41280,"BPM":112000,"TimeSignature":[4]},{"Position":41376,"BPM":112000,"TimeSignature":[4]},{"Position":41472,"BPM":112000,"TimeSignature":[4]},{"Position":41568,"BPM":112000,"TimeSignature":[4]},{"Position":41664,"BPM":112000,"TimeSignature":[4]},{"Position":41760,"BPM":112000,"TimeSignature":[4]},{"Position":41856,"BPM":112000,"TimeSignature":[4]},{"Position":41952,"BPM":112000,"TimeSignature":[4]},{"Position":42048,"BPM":112000,"TimeSignature":[4]},{"Position":42144,"BPM":112000,"TimeSignature":[4]},{"Position":42240,"BPM":112000,"TimeSignature":[4]}]} \ No newline at end of file +{"Name":"Example Song","Artist":"Example Artist","Album":"Example Album","Genre":"Example Genre","Year":", 2021","Charter":"Example Charter","Resolution":192,"Difficulty":4,"Offset":0.56,"PreviewStart":45.28,"PreviewEnd":75.28,"MusicStream":"Example Song.ogg","Lyrics":{},"Difficulties":{"Expert":[{"Position":768,"HandPosition":0,"Length":0},{"Position":864,"HandPosition":1,"Length":0},{"Position":864,"HandPosition":5,"Length":0},{"Position":960,"HandPosition":2,"Length":0},{"Position":960,"HandPosition":6,"Length":0},{"Position":1056,"HandPosition":3,"Length":0},{"Position":1152,"HandPosition":4,"Length":0},{"Position":1248,"HandPosition":7,"Length":0}]},"BPM":{"0":88000,"3840":112000,"9984":89600,"22272":112000,"33792":111500,"34560":112000,"42240":111980},"TimeSignatures":{"0":[4],"9984":[2,1],"22272":[4],"69120":[2,1]},"BeatBars":[{"Position":0,"BPM":88000},{"Position":96,"BPM":88000},{"Position":192,"BPM":88000},{"Position":288,"BPM":88000},{"Position":384,"BPM":88000},{"Position":480,"BPM":88000},{"Position":576,"BPM":88000},{"Position":672,"BPM":88000},{"Position":768,"BPM":88000},{"Position":864,"BPM":88000},{"Position":960,"BPM":88000},{"Position":1056,"BPM":88000},{"Position":1152,"BPM":88000},{"Position":1248,"BPM":88000},{"Position":1344,"BPM":88000},{"Position":1440,"BPM":88000},{"Position":1536,"BPM":88000},{"Position":1632,"BPM":88000},{"Position":1728,"BPM":88000},{"Position":1824,"BPM":88000},{"Position":1920,"BPM":88000},{"Position":2016,"BPM":88000},{"Position":2112,"BPM":88000},{"Position":2208,"BPM":88000},{"Position":2304,"BPM":88000},{"Position":2400,"BPM":88000},{"Position":2496,"BPM":88000},{"Position":2592,"BPM":88000},{"Position":2688,"BPM":88000},{"Position":2784,"BPM":88000},{"Position":2880,"BPM":88000},{"Position":2976,"BPM":88000},{"Position":3072,"BPM":88000},{"Position":3168,"BPM":88000},{"Position":3264,"BPM":88000},{"Position":3360,"BPM":88000},{"Position":3456,"BPM":88000},{"Position":3552,"BPM":88000},{"Position":3648,"BPM":88000},{"Position":3744,"BPM":88000},{"Position":3840,"BPM":88000},{"Position":3840,"BPM":112000},{"Position":3936,"BPM":112000},{"Position":4032,"BPM":112000},{"Position":4128,"BPM":112000},{"Position":4224,"BPM":112000},{"Position":4320,"BPM":112000},{"Position":4416,"BPM":112000},{"Position":4512,"BPM":112000},{"Position":4608,"BPM":112000},{"Position":4704,"BPM":112000},{"Position":4800,"BPM":112000},{"Position":4896,"BPM":112000},{"Position":4992,"BPM":112000},{"Position":5088,"BPM":112000},{"Position":5184,"BPM":112000},{"Position":5280,"BPM":112000},{"Position":5376,"BPM":112000},{"Position":5472,"BPM":112000},{"Position":5568,"BPM":112000},{"Position":5664,"BPM":112000},{"Position":5760,"BPM":112000},{"Position":5856,"BPM":112000},{"Position":5952,"BPM":112000},{"Position":6048,"BPM":112000},{"Position":6144,"BPM":112000},{"Position":6240,"BPM":112000},{"Position":6336,"BPM":112000},{"Position":6432,"BPM":112000},{"Position":6528,"BPM":112000},{"Position":6624,"BPM":112000},{"Position":6720,"BPM":112000},{"Position":6816,"BPM":112000},{"Position":6912,"BPM":112000},{"Position":7008,"BPM":112000},{"Position":7104,"BPM":112000},{"Position":7200,"BPM":112000},{"Position":7296,"BPM":112000},{"Position":7392,"BPM":112000},{"Position":7488,"BPM":112000},{"Position":7584,"BPM":112000},{"Position":7680,"BPM":112000},{"Position":7776,"BPM":112000},{"Position":7872,"BPM":112000},{"Position":7968,"BPM":112000},{"Position":8064,"BPM":112000},{"Position":8160,"BPM":112000},{"Position":8256,"BPM":112000},{"Position":8352,"BPM":112000},{"Position":8448,"BPM":112000},{"Position":8544,"BPM":112000},{"Position":8640,"BPM":112000},{"Position":8736,"BPM":112000},{"Position":8832,"BPM":112000},{"Position":8928,"BPM":112000},{"Position":9024,"BPM":112000},{"Position":9120,"BPM":112000},{"Position":9216,"BPM":112000},{"Position":9312,"BPM":112000},{"Position":9408,"BPM":112000},{"Position":9504,"BPM":112000},{"Position":9600,"BPM":112000},{"Position":9696,"BPM":112000},{"Position":9792,"BPM":112000},{"Position":9888,"BPM":112000},{"Position":9984,"BPM":112000},{"Position":9984,"BPM":89600},{"Position":10080,"BPM":89600},{"Position":10176,"BPM":89600},{"Position":10272,"BPM":89600},{"Position":10368,"BPM":89600},{"Position":10464,"BPM":89600},{"Position":10560,"BPM":89600},{"Position":10656,"BPM":89600},{"Position":10752,"BPM":89600},{"Position":10848,"BPM":89600},{"Position":10944,"BPM":89600},{"Position":11040,"BPM":89600},{"Position":11136,"BPM":89600},{"Position":11232,"BPM":89600},{"Position":11328,"BPM":89600},{"Position":11424,"BPM":89600},{"Position":11520,"BPM":89600},{"Position":11616,"BPM":89600},{"Position":11712,"BPM":89600},{"Position":11808,"BPM":89600},{"Position":11904,"BPM":89600},{"Position":12000,"BPM":89600},{"Position":12096,"BPM":89600},{"Position":12192,"BPM":89600},{"Position":12288,"BPM":89600},{"Position":12384,"BPM":89600},{"Position":12480,"BPM":89600},{"Position":12576,"BPM":89600},{"Position":12672,"BPM":89600},{"Position":12768,"BPM":89600},{"Position":12864,"BPM":89600},{"Position":12960,"BPM":89600},{"Position":13056,"BPM":89600},{"Position":13152,"BPM":89600},{"Position":13248,"BPM":89600},{"Position":13344,"BPM":89600},{"Position":13440,"BPM":89600},{"Position":13536,"BPM":89600},{"Position":13632,"BPM":89600},{"Position":13728,"BPM":89600},{"Position":13824,"BPM":89600},{"Position":13920,"BPM":89600},{"Position":14016,"BPM":89600},{"Position":14112,"BPM":89600},{"Position":14208,"BPM":89600},{"Position":14304,"BPM":89600},{"Position":14400,"BPM":89600},{"Position":14496,"BPM":89600},{"Position":14592,"BPM":89600},{"Position":14688,"BPM":89600},{"Position":14784,"BPM":89600},{"Position":14880,"BPM":89600},{"Position":14976,"BPM":89600},{"Position":15072,"BPM":89600},{"Position":15168,"BPM":89600},{"Position":15264,"BPM":89600},{"Position":15360,"BPM":89600},{"Position":15456,"BPM":89600},{"Position":15552,"BPM":89600},{"Position":15648,"BPM":89600},{"Position":15744,"BPM":89600},{"Position":15840,"BPM":89600},{"Position":15936,"BPM":89600},{"Position":16032,"BPM":89600},{"Position":16128,"BPM":89600},{"Position":16224,"BPM":89600},{"Position":16320,"BPM":89600},{"Position":16416,"BPM":89600},{"Position":16512,"BPM":89600},{"Position":16608,"BPM":89600},{"Position":16704,"BPM":89600},{"Position":16800,"BPM":89600},{"Position":16896,"BPM":89600},{"Position":16992,"BPM":89600},{"Position":17088,"BPM":89600},{"Position":17184,"BPM":89600},{"Position":17280,"BPM":89600},{"Position":17376,"BPM":89600},{"Position":17472,"BPM":89600},{"Position":17568,"BPM":89600},{"Position":17664,"BPM":89600},{"Position":17760,"BPM":89600},{"Position":17856,"BPM":89600},{"Position":17952,"BPM":89600},{"Position":18048,"BPM":89600},{"Position":18144,"BPM":89600},{"Position":18240,"BPM":89600},{"Position":18336,"BPM":89600},{"Position":18432,"BPM":89600},{"Position":18528,"BPM":89600},{"Position":18624,"BPM":89600},{"Position":18720,"BPM":89600},{"Position":18816,"BPM":89600},{"Position":18912,"BPM":89600},{"Position":19008,"BPM":89600},{"Position":19104,"BPM":89600},{"Position":19200,"BPM":89600},{"Position":19296,"BPM":89600},{"Position":19392,"BPM":89600},{"Position":19488,"BPM":89600},{"Position":19584,"BPM":89600},{"Position":19680,"BPM":89600},{"Position":19776,"BPM":89600},{"Position":19872,"BPM":89600},{"Position":19968,"BPM":89600},{"Position":20064,"BPM":89600},{"Position":20160,"BPM":89600},{"Position":20256,"BPM":89600},{"Position":20352,"BPM":89600},{"Position":20448,"BPM":89600},{"Position":20544,"BPM":89600},{"Position":20640,"BPM":89600},{"Position":20736,"BPM":89600},{"Position":20832,"BPM":89600},{"Position":20928,"BPM":89600},{"Position":21024,"BPM":89600},{"Position":21120,"BPM":89600},{"Position":21216,"BPM":89600},{"Position":21312,"BPM":89600},{"Position":21408,"BPM":89600},{"Position":21504,"BPM":89600},{"Position":21600,"BPM":89600},{"Position":21696,"BPM":89600},{"Position":21792,"BPM":89600},{"Position":21888,"BPM":89600},{"Position":21984,"BPM":89600},{"Position":22080,"BPM":89600},{"Position":22176,"BPM":89600},{"Position":22272,"BPM":89600},{"Position":22272,"BPM":112000},{"Position":22368,"BPM":112000},{"Position":22464,"BPM":112000},{"Position":22560,"BPM":112000},{"Position":22656,"BPM":112000},{"Position":22752,"BPM":112000},{"Position":22848,"BPM":112000},{"Position":22944,"BPM":112000},{"Position":23040,"BPM":112000},{"Position":23136,"BPM":112000},{"Position":23232,"BPM":112000},{"Position":23328,"BPM":112000},{"Position":23424,"BPM":112000},{"Position":23520,"BPM":112000},{"Position":23616,"BPM":112000},{"Position":23712,"BPM":112000},{"Position":23808,"BPM":112000},{"Position":23904,"BPM":112000},{"Position":24000,"BPM":112000},{"Position":24096,"BPM":112000},{"Position":24192,"BPM":112000},{"Position":24288,"BPM":112000},{"Position":24384,"BPM":112000},{"Position":24480,"BPM":112000},{"Position":24576,"BPM":112000},{"Position":24672,"BPM":112000},{"Position":24768,"BPM":112000},{"Position":24864,"BPM":112000},{"Position":24960,"BPM":112000},{"Position":25056,"BPM":112000},{"Position":25152,"BPM":112000},{"Position":25248,"BPM":112000},{"Position":25344,"BPM":112000},{"Position":25440,"BPM":112000},{"Position":25536,"BPM":112000},{"Position":25632,"BPM":112000},{"Position":25728,"BPM":112000},{"Position":25824,"BPM":112000},{"Position":25920,"BPM":112000},{"Position":26016,"BPM":112000},{"Position":26112,"BPM":112000},{"Position":26208,"BPM":112000},{"Position":26304,"BPM":112000},{"Position":26400,"BPM":112000},{"Position":26496,"BPM":112000},{"Position":26592,"BPM":112000},{"Position":26688,"BPM":112000},{"Position":26784,"BPM":112000},{"Position":26880,"BPM":112000},{"Position":26976,"BPM":112000},{"Position":27072,"BPM":112000},{"Position":27168,"BPM":112000},{"Position":27264,"BPM":112000},{"Position":27360,"BPM":112000},{"Position":27456,"BPM":112000},{"Position":27552,"BPM":112000},{"Position":27648,"BPM":112000},{"Position":27744,"BPM":112000},{"Position":27840,"BPM":112000},{"Position":27936,"BPM":112000},{"Position":28032,"BPM":112000},{"Position":28128,"BPM":112000},{"Position":28224,"BPM":112000},{"Position":28320,"BPM":112000},{"Position":28416,"BPM":112000},{"Position":28512,"BPM":112000},{"Position":28608,"BPM":112000},{"Position":28704,"BPM":112000},{"Position":28800,"BPM":112000},{"Position":28896,"BPM":112000},{"Position":28992,"BPM":112000},{"Position":29088,"BPM":112000},{"Position":29184,"BPM":112000},{"Position":29280,"BPM":112000},{"Position":29376,"BPM":112000},{"Position":29472,"BPM":112000},{"Position":29568,"BPM":112000},{"Position":29664,"BPM":112000},{"Position":29760,"BPM":112000},{"Position":29856,"BPM":112000},{"Position":29952,"BPM":112000},{"Position":30048,"BPM":112000},{"Position":30144,"BPM":112000},{"Position":30240,"BPM":112000},{"Position":30336,"BPM":112000},{"Position":30432,"BPM":112000},{"Position":30528,"BPM":112000},{"Position":30624,"BPM":112000},{"Position":30720,"BPM":112000},{"Position":30816,"BPM":112000},{"Position":30912,"BPM":112000},{"Position":31008,"BPM":112000},{"Position":31104,"BPM":112000},{"Position":31200,"BPM":112000},{"Position":31296,"BPM":112000},{"Position":31392,"BPM":112000},{"Position":31488,"BPM":112000},{"Position":31584,"BPM":112000},{"Position":31680,"BPM":112000},{"Position":31776,"BPM":112000},{"Position":31872,"BPM":112000},{"Position":31968,"BPM":112000},{"Position":32064,"BPM":112000},{"Position":32160,"BPM":112000},{"Position":32256,"BPM":112000},{"Position":32352,"BPM":112000},{"Position":32448,"BPM":112000},{"Position":32544,"BPM":112000},{"Position":32640,"BPM":112000},{"Position":32736,"BPM":112000},{"Position":32832,"BPM":112000},{"Position":32928,"BPM":112000},{"Position":33024,"BPM":112000},{"Position":33120,"BPM":112000},{"Position":33216,"BPM":112000},{"Position":33312,"BPM":112000},{"Position":33408,"BPM":112000},{"Position":33504,"BPM":112000},{"Position":33600,"BPM":112000},{"Position":33696,"BPM":112000},{"Position":33792,"BPM":112000},{"Position":33792,"BPM":111500},{"Position":33888,"BPM":111500},{"Position":33984,"BPM":111500},{"Position":34080,"BPM":111500},{"Position":34176,"BPM":111500},{"Position":34272,"BPM":111500},{"Position":34368,"BPM":111500},{"Position":34464,"BPM":111500},{"Position":34560,"BPM":111500},{"Position":34560,"BPM":112000},{"Position":34656,"BPM":112000},{"Position":34752,"BPM":112000},{"Position":34848,"BPM":112000},{"Position":34944,"BPM":112000},{"Position":35040,"BPM":112000},{"Position":35136,"BPM":112000},{"Position":35232,"BPM":112000},{"Position":35328,"BPM":112000},{"Position":35424,"BPM":112000},{"Position":35520,"BPM":112000},{"Position":35616,"BPM":112000},{"Position":35712,"BPM":112000},{"Position":35808,"BPM":112000},{"Position":35904,"BPM":112000},{"Position":36000,"BPM":112000},{"Position":36096,"BPM":112000},{"Position":36192,"BPM":112000},{"Position":36288,"BPM":112000},{"Position":36384,"BPM":112000},{"Position":36480,"BPM":112000},{"Position":36576,"BPM":112000},{"Position":36672,"BPM":112000},{"Position":36768,"BPM":112000},{"Position":36864,"BPM":112000},{"Position":36960,"BPM":112000},{"Position":37056,"BPM":112000},{"Position":37152,"BPM":112000},{"Position":37248,"BPM":112000},{"Position":37344,"BPM":112000},{"Position":37440,"BPM":112000},{"Position":37536,"BPM":112000},{"Position":37632,"BPM":112000},{"Position":37728,"BPM":112000},{"Position":37824,"BPM":112000},{"Position":37920,"BPM":112000},{"Position":38016,"BPM":112000},{"Position":38112,"BPM":112000},{"Position":38208,"BPM":112000},{"Position":38304,"BPM":112000},{"Position":38400,"BPM":112000},{"Position":38496,"BPM":112000},{"Position":38592,"BPM":112000},{"Position":38688,"BPM":112000},{"Position":38784,"BPM":112000},{"Position":38880,"BPM":112000},{"Position":38976,"BPM":112000},{"Position":39072,"BPM":112000},{"Position":39168,"BPM":112000},{"Position":39264,"BPM":112000},{"Position":39360,"BPM":112000},{"Position":39456,"BPM":112000},{"Position":39552,"BPM":112000},{"Position":39648,"BPM":112000},{"Position":39744,"BPM":112000},{"Position":39840,"BPM":112000},{"Position":39936,"BPM":112000},{"Position":40032,"BPM":112000},{"Position":40128,"BPM":112000},{"Position":40224,"BPM":112000},{"Position":40320,"BPM":112000},{"Position":40416,"BPM":112000},{"Position":40512,"BPM":112000},{"Position":40608,"BPM":112000},{"Position":40704,"BPM":112000},{"Position":40800,"BPM":112000},{"Position":40896,"BPM":112000},{"Position":40992,"BPM":112000},{"Position":41088,"BPM":112000},{"Position":41184,"BPM":112000},{"Position":41280,"BPM":112000},{"Position":41376,"BPM":112000},{"Position":41472,"BPM":112000},{"Position":41568,"BPM":112000},{"Position":41664,"BPM":112000},{"Position":41760,"BPM":112000},{"Position":41856,"BPM":112000},{"Position":41952,"BPM":112000},{"Position":42048,"BPM":112000},{"Position":42144,"BPM":112000},{"Position":42240,"BPM":112000}]} \ No newline at end of file diff --git a/RhythmGameUtilities.Tests/UtilitiesTest.cs b/RhythmGameUtilities.Tests/UtilitiesTest.cs index 7fe9c6e..b8835b9 100644 --- a/RhythmGameUtilities.Tests/UtilitiesTest.cs +++ b/RhythmGameUtilities.Tests/UtilitiesTest.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using NUnit.Framework; @@ -22,18 +23,19 @@ public void TestConvertSecondsToTicks() const int seconds = 5; const int resolution = 192; + var bpmChanges = new Dictionary + { + { 0, 88000 }, + { 3840, 112000 }, + { 9984, 89600 }, + { 22272, 112000 }, + { 33792, 111500 }, + { 34560, 112000 }, + { 42240, 111980 } + }; + Assert.That( - Utilities.ConvertSecondsToTicks(seconds, resolution, - new Dictionary - { - { 0, 88000 }, - { 3840, 112000 }, - { 9984, 89600 }, - { 22272, 112000 }, - { 33792, 111500 }, - { 34560, 112000 }, - { 42240, 111980 } - }), Is.EqualTo(1408)); + Utilities.ConvertSecondsToTicks(seconds, resolution, bpmChanges), Is.EqualTo(1408)); } [Test] @@ -66,6 +68,28 @@ public void TestInverseLerp() Assert.That(Utilities.InverseLerp(0, 10, 10), Is.EqualTo(1)); } + [Test] + public void TestCalculateBeatBars() + { + const int resolution = 192; + const int timeSignature = 4; + + var bpmChanges = new Dictionary + { + { 0, 88000 }, + { 3840, 112000 }, + { 9984, 89600 }, + { 22272, 112000 }, + { 33792, 111500 }, + { 34560, 112000 }, + { 42240, 111980 } + }; + + var beatBars = Utilities.CalculateBeatBars(bpmChanges, resolution, timeSignature, true); + + Assert.That(beatBars.Count, Is.EqualTo(446)); + } + } } diff --git a/RhythmGameUtilities/Scripts/Utilities.cs b/RhythmGameUtilities/Scripts/Utilities.cs index ecd511d..c8db2d5 100644 --- a/RhythmGameUtilities/Scripts/Utilities.cs +++ b/RhythmGameUtilities/Scripts/Utilities.cs @@ -64,6 +64,17 @@ public static extern int ConvertSecondsToTicksInternal(float seconds, int resolu #endif public static extern float InverseLerp(float a, float b, float v); +#if WINDOWS_BUILD || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN + [DllImport("libRhythmGameUtilities.dll", CallingConvention = CallingConvention.Cdecl)] +#elif MACOS_BUILD || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + [DllImport("libRhythmGameUtilities.dylib", CallingConvention = CallingConvention.Cdecl)] +#elif LINUX_BUILD || UNITY_EDITOR_LINUX || UNITY_STANDALONE_LINUX + [DllImport("libRhythmGameUtilities.so", CallingConvention = CallingConvention.Cdecl)] +#endif + public static extern IntPtr CalculateBeatBarsInternal(int[] bpmChangesKeys, + int[] bpmChangesValues, int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, out int size); + } public static class Utilities @@ -107,46 +118,21 @@ public static List CalculateBeatBars(Dictionary bpmChanges, i { var beatBars = new List(); - var keyValuePairs = GenerateAdjacentKeyPairs(bpmChanges); + var ptrArray = UtilitiesInternal.CalculateBeatBarsInternal(bpmChanges.Keys.ToArray(), + bpmChanges.Values.ToArray(), bpmChanges.Count, resolution, ts, includeHalfNotes, + out var size); - foreach (var (startTick, endTick) in keyValuePairs) - { - for (var tick = startTick; tick <= endTick; tick += resolution) - { - beatBars.Add(new BeatBar - { - Position = tick, BPM = bpmChanges[startTick], TimeSignature = new[] { ts } - }); - - if (includeHalfNotes && tick != endTick) - { - beatBars.Add(new BeatBar - { - Position = tick + resolution / 2, - BPM = bpmChanges[startTick], - TimeSignature = new[] { ts } - }); - } - } - } + var beatBarSize = Marshal.SizeOf(typeof(BeatBar)); - return beatBars; - } - - public static List> GenerateAdjacentKeyPairs(Dictionary dictionary) - { - var keys = dictionary.Keys.ToList(); - - keys.Sort(); - - var adjacentKeyPairs = new List>(); - - for (var i = 0; i < keys.Count - 1; i += 1) + for (var i = 0; i < size; i += 1) { - adjacentKeyPairs.Add(new Tuple(keys[i], keys[i + 1])); + var beatBarSizePtr = new IntPtr(ptrArray.ToInt64() + beatBarSize * i); + var beatBar = Marshal.PtrToStructure(beatBarSizePtr); + + beatBars.Add(beatBar); } - return adjacentKeyPairs; + return beatBars; } } diff --git a/RhythmGameUtilities/Structs/BeatBar.cs b/RhythmGameUtilities/Structs/BeatBar.cs index 2661119..6a018e2 100644 --- a/RhythmGameUtilities/Structs/BeatBar.cs +++ b/RhythmGameUtilities/Structs/BeatBar.cs @@ -11,8 +11,6 @@ public struct BeatBar public int BPM; - public int[] TimeSignature; - } } diff --git a/UnityPackage/Editor/Tests/UtilitiesTest.cs b/UnityPackage/Editor/Tests/UtilitiesTest.cs index 7fe9c6e..b8835b9 100644 --- a/UnityPackage/Editor/Tests/UtilitiesTest.cs +++ b/UnityPackage/Editor/Tests/UtilitiesTest.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using NUnit.Framework; @@ -22,18 +23,19 @@ public void TestConvertSecondsToTicks() const int seconds = 5; const int resolution = 192; + var bpmChanges = new Dictionary + { + { 0, 88000 }, + { 3840, 112000 }, + { 9984, 89600 }, + { 22272, 112000 }, + { 33792, 111500 }, + { 34560, 112000 }, + { 42240, 111980 } + }; + Assert.That( - Utilities.ConvertSecondsToTicks(seconds, resolution, - new Dictionary - { - { 0, 88000 }, - { 3840, 112000 }, - { 9984, 89600 }, - { 22272, 112000 }, - { 33792, 111500 }, - { 34560, 112000 }, - { 42240, 111980 } - }), Is.EqualTo(1408)); + Utilities.ConvertSecondsToTicks(seconds, resolution, bpmChanges), Is.EqualTo(1408)); } [Test] @@ -66,6 +68,28 @@ public void TestInverseLerp() Assert.That(Utilities.InverseLerp(0, 10, 10), Is.EqualTo(1)); } + [Test] + public void TestCalculateBeatBars() + { + const int resolution = 192; + const int timeSignature = 4; + + var bpmChanges = new Dictionary + { + { 0, 88000 }, + { 3840, 112000 }, + { 9984, 89600 }, + { 22272, 112000 }, + { 33792, 111500 }, + { 34560, 112000 }, + { 42240, 111980 } + }; + + var beatBars = Utilities.CalculateBeatBars(bpmChanges, resolution, timeSignature, true); + + Assert.That(beatBars.Count, Is.EqualTo(446)); + } + } } diff --git a/UnityPackage/Scripts/Utilities.cs b/UnityPackage/Scripts/Utilities.cs index ecd511d..c8db2d5 100644 --- a/UnityPackage/Scripts/Utilities.cs +++ b/UnityPackage/Scripts/Utilities.cs @@ -64,6 +64,17 @@ public static extern int ConvertSecondsToTicksInternal(float seconds, int resolu #endif public static extern float InverseLerp(float a, float b, float v); +#if WINDOWS_BUILD || UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN + [DllImport("libRhythmGameUtilities.dll", CallingConvention = CallingConvention.Cdecl)] +#elif MACOS_BUILD || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + [DllImport("libRhythmGameUtilities.dylib", CallingConvention = CallingConvention.Cdecl)] +#elif LINUX_BUILD || UNITY_EDITOR_LINUX || UNITY_STANDALONE_LINUX + [DllImport("libRhythmGameUtilities.so", CallingConvention = CallingConvention.Cdecl)] +#endif + public static extern IntPtr CalculateBeatBarsInternal(int[] bpmChangesKeys, + int[] bpmChangesValues, int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, out int size); + } public static class Utilities @@ -107,46 +118,21 @@ public static List CalculateBeatBars(Dictionary bpmChanges, i { var beatBars = new List(); - var keyValuePairs = GenerateAdjacentKeyPairs(bpmChanges); + var ptrArray = UtilitiesInternal.CalculateBeatBarsInternal(bpmChanges.Keys.ToArray(), + bpmChanges.Values.ToArray(), bpmChanges.Count, resolution, ts, includeHalfNotes, + out var size); - foreach (var (startTick, endTick) in keyValuePairs) - { - for (var tick = startTick; tick <= endTick; tick += resolution) - { - beatBars.Add(new BeatBar - { - Position = tick, BPM = bpmChanges[startTick], TimeSignature = new[] { ts } - }); - - if (includeHalfNotes && tick != endTick) - { - beatBars.Add(new BeatBar - { - Position = tick + resolution / 2, - BPM = bpmChanges[startTick], - TimeSignature = new[] { ts } - }); - } - } - } + var beatBarSize = Marshal.SizeOf(typeof(BeatBar)); - return beatBars; - } - - public static List> GenerateAdjacentKeyPairs(Dictionary dictionary) - { - var keys = dictionary.Keys.ToList(); - - keys.Sort(); - - var adjacentKeyPairs = new List>(); - - for (var i = 0; i < keys.Count - 1; i += 1) + for (var i = 0; i < size; i += 1) { - adjacentKeyPairs.Add(new Tuple(keys[i], keys[i + 1])); + var beatBarSizePtr = new IntPtr(ptrArray.ToInt64() + beatBarSize * i); + var beatBar = Marshal.PtrToStructure(beatBarSizePtr); + + beatBars.Add(beatBar); } - return adjacentKeyPairs; + return beatBars; } } diff --git a/UnityPackage/Structs/BeatBar.cs b/UnityPackage/Structs/BeatBar.cs index 2661119..6a018e2 100644 --- a/UnityPackage/Structs/BeatBar.cs +++ b/UnityPackage/Structs/BeatBar.cs @@ -11,8 +11,6 @@ public struct BeatBar public int BPM; - public int[] TimeSignature; - } } diff --git a/includes/RhythmGameUtilities/Structs/BeatBar.h b/includes/RhythmGameUtilities/Structs/BeatBar.h new file mode 100644 index 0000000..0335ca6 --- /dev/null +++ b/includes/RhythmGameUtilities/Structs/BeatBar.h @@ -0,0 +1,9 @@ +#pragma once + +struct BeatBar +{ + + int Position; + + int BPM; +}; diff --git a/includes/RhythmGameUtilities/Utilities.cpp b/includes/RhythmGameUtilities/Utilities.cpp index 1e99b4d..446e578 100644 --- a/includes/RhythmGameUtilities/Utilities.cpp +++ b/includes/RhythmGameUtilities/Utilities.cpp @@ -9,6 +9,7 @@ #include "Utilities.h" +#include "Structs/BeatBar.h" #include "Structs/Note.h" const float SECONDS_PER_MINUTE = 60.0f; @@ -111,6 +112,62 @@ std::vector Split(const char *contents, const char delimiter) return parts; } +std::vector CalculateBeatBars(std::map bpmChanges, + int resolution, int ts, + bool includeHalfNotes) +{ + std::vector beatBars; + + auto keyValuePairs = GenerateAdjacentKeyPairs(bpmChanges); + + for (const auto &keyValuePair : keyValuePairs) + { + auto startTick = std::get<0>(keyValuePair); + auto endTick = std::get<1>(keyValuePair); + + for (auto tick = startTick; tick <= endTick; tick += resolution) + { + beatBars.push_back( + {.Position = tick, .BPM = bpmChanges[startTick]}); + + if (includeHalfNotes && tick != endTick) + { + beatBars.push_back({.Position = tick + resolution / 2, + .BPM = bpmChanges[startTick]}); + } + } + } + + return beatBars; +} + +BeatBar *CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, + int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, int *outSize) +{ + auto bpmChanges = std::map(); + + for (auto i = 0; i < bpmChangesSize; i += 1) + { + bpmChanges[bpmChangesKeys[i]] = bpmChangesValues[i]; + } + + auto internalBeatBars = + CalculateBeatBars(bpmChanges, resolution, ts, includeHalfNotes); + + *outSize = internalBeatBars.size(); + + auto beatBars = + (BeatBar *)malloc(internalBeatBars.size() * sizeof(BeatBar)); + + for (auto i = 0; i < internalBeatBars.size(); i += 1) + { + beatBars[i] = internalBeatBars[i]; + } + + return beatBars; +} + std::vector> GenerateAdjacentKeyPairs(std::map keyValuePairs) { diff --git a/includes/RhythmGameUtilities/Utilities.h b/includes/RhythmGameUtilities/Utilities.h index 76429c4..716ce1e 100644 --- a/includes/RhythmGameUtilities/Utilities.h +++ b/includes/RhythmGameUtilities/Utilities.h @@ -5,6 +5,7 @@ #include #include +#include "Structs/BeatBar.h" #include "Structs/Note.h" #ifdef _WIN32 @@ -29,6 +30,11 @@ extern "C" PACKAGE_API float Lerp(float a, float b, float t); PACKAGE_API float InverseLerp(float a, float b, float v); + + PACKAGE_API BeatBar * + CalculateBeatBarsInternal(int *bpmChangesKeys, int *bpmChangesValues, + int bpmChangesSize, int resolution, int ts, + bool includeHalfNotes, int *outSize); } int ConvertSecondsToTicks(float seconds, int resolution, @@ -38,6 +44,10 @@ std::string Trim(const char *contents); std::vector Split(const char *contents, const char delimiter); +std::vector CalculateBeatBars(std::map bpmChanges, + int resolution, int ts, + bool includeHalfNotes); + std::vector> GenerateAdjacentKeyPairs(std::map keyValuePairs); diff --git a/tests/MusicGameUtilities/Utilities.cpp b/tests/MusicGameUtilities/Utilities.cpp index 273e52f..c7a7e81 100644 --- a/tests/MusicGameUtilities/Utilities.cpp +++ b/tests/MusicGameUtilities/Utilities.cpp @@ -77,12 +77,54 @@ void testSplit() void testGenerateAdjacentKeyPairs() { - auto adjacentKeyPairs = - GenerateAdjacentKeyPairs(std::map{{1, 2}, {3, 4}, {5, 6}}); + std::map bpmChanges = { + {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, + {33792, 111500}, {34560, 112000}, {42240, 111980}}; + + auto adjacentKeyPairs = GenerateAdjacentKeyPairs(bpmChanges); + + assert(adjacentKeyPairs.size() == 6); + assert(adjacentKeyPairs[0] == std::make_tuple(0, 3840)); + assert(adjacentKeyPairs[1] == std::make_tuple(3840, 9984)); + + std::cout << "."; +} + +void testCalculateBeatBars() +{ + std::map bpmChanges = { + {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, + {33792, 111500}, {34560, 112000}, {42240, 111980}}; + + auto beatBars = CalculateBeatBars(bpmChanges, 192, 4, true); + + assert(beatBars.size() == 446); + + std::cout << "."; +} + +void testCalculateBeatBarsInternal() +{ + std::map bpmChanges = { + {0, 88000}, {3840, 112000}, {9984, 89600}, {22272, 112000}, + {33792, 111500}, {34560, 112000}, {42240, 111980}}; + + std::vector bpmChangesKeys; + std::vector bpmChangesValues; + + for (const auto &[key, value] : bpmChanges) + { + bpmChangesKeys.push_back(key); + bpmChangesValues.push_back(value); + } + + int *outSize; + + auto beatBars = + CalculateBeatBarsInternal(&bpmChangesKeys[0], &bpmChangesValues[0], + size(bpmChanges), 192, 4, true, outSize); - assert(adjacentKeyPairs.size() == 2); - assert(adjacentKeyPairs[0] == std::make_tuple(1, 3)); - assert(adjacentKeyPairs[1] == std::make_tuple(3, 5)); + assert(*outSize == 446); std::cout << "."; } @@ -121,6 +163,8 @@ int main() testTrim(); testSplit(); testGenerateAdjacentKeyPairs(); + testCalculateBeatBars(); + testCalculateBeatBarsInternal(); testFindAllMatches(); testFindMatchGroups();