Skip to content

Commit

Permalink
Album cover optimizations and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
EliteAsian123 committed May 9, 2023
1 parent ce94cee commit 9826116
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 125 deletions.
39 changes: 19 additions & 20 deletions Assets/Script/Audio/Bass/BassAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

namespace YARG {
public class BassAudioManager : MonoBehaviour, IAudioManager {
public bool UseStarpowerFx { get; set; }
public bool UseStarpowerFx { get; set; }
public bool IsChipmunkSpeedup { get; set; }

public IList<string> SupportedFormats { get; private set; }

public bool IsAudioLoaded { get; private set; }
public bool IsPlaying { get; private set; }

public double MasterVolume { get; private set; }
public double SfxVolume { get; private set; }

Expand Down Expand Up @@ -134,7 +134,7 @@ public void LoadSfx() {
sfxPath += format;
break;
}


if (!File.Exists(sfxPath)) {
Debug.LogError($"SFX path does not exist! {sfxPath}");
Expand All @@ -149,7 +149,7 @@ public void LoadSfx() {
continue;
}

_sfxSamples[(int)sfxSample] = sfx;
_sfxSamples[(int) sfxSample] = sfx;
Debug.Log($"Loaded {sfxFile}");
}

Expand All @@ -171,7 +171,7 @@ public void LoadSong(ICollection<string> stems, bool isSpeedUp) {

// Gets the index (SongStem to int) from the name
var songStem = AudioHelpers.GetStemFromName(stemName);

// Assign 1 stem songs to the song stem
if (stems.Count == 1) {
songStem = SongStem.Song;
Expand Down Expand Up @@ -203,19 +203,19 @@ public void LoadSong(ICollection<string> stems, bool isSpeedUp) {

IsAudioLoaded = true;
}

public void LoadMogg(ExtractedConSongEntry exConSong, bool isSpeedUp) {
Debug.Log("Loading mogg song");
UnloadSong();

byte[] moggArray;
if (exConSong is ConSongEntry conSong) {
moggArray = XboxCONInnerFileRetriever.RetrieveFile(conSong.Location, conSong.MoggPath,
moggArray = XboxCONInnerFileRetriever.RetrieveFile(conSong.Location,
conSong.MoggFileSize, conSong.MoggFileMemBlockOffsets)[conSong.MoggAddressAudioOffset..];
} else {
moggArray = File.ReadAllBytes(exConSong.MoggPath)[exConSong.MoggAddressAudioOffset..];
}

int moggStreamHandle = Bass.CreateStream(moggArray, 0, moggArray.Length, BassFlags.Prescan | BassFlags.Decode | BassFlags.AsyncFile);
if (moggStreamHandle == 0) {
Debug.LogError($"Failed to load mogg file or position: {Bass.LastError}");
Expand All @@ -230,13 +230,13 @@ public void LoadMogg(ExtractedConSongEntry exConSong, bool isSpeedUp) {
if (!_mixer.SetupMogg(isSpeedUp)) {
throw new Exception($"Failed to setup MOGG channels: {Bass.LastError}");
}

Debug.Log($"Loaded {_mixer.StemsLoaded} stems");

// Setup audio length
AudioLengthD = _mixer.LeadChannel.LengthD;
AudioLengthF = (float) AudioLengthD;

IsAudioLoaded = true;
}

Expand All @@ -255,12 +255,12 @@ public void LoadPreviewAudio(SongEntry song) {
} else {
LoadSong(AudioHelpers.GetSupportedStems(song.Location), false);
}

SetPosition(song.PreviewStartTimeSpan.TotalSeconds);
}

public void Play() => Play(false);

private void Play(bool fadeIn) {
// Don't try to play if there's no audio loaded or if it's already playing
if (!IsAudioLoaded || IsPlaying) {
Expand All @@ -277,7 +277,7 @@ private void Play(bool fadeIn) {
if (_mixer.Play() != 0) {
Debug.Log($"Play error: {Bass.LastError}");
}

IsPlaying = _mixer.IsPlaying;
}

Expand All @@ -289,14 +289,14 @@ public void Pause() {
if (_mixer.Pause() != 0) {
Debug.Log($"Pause error: {Bass.LastError}");
}

IsPlaying = _mixer.IsPlaying;
}

public void FadeIn() {
Play(true);
if (IsPlaying) {
_mixer?.FadeIn();
_mixer?.FadeIn();
}
}

Expand All @@ -319,8 +319,7 @@ public void SetStemVolume(SongStem stem, double volume) {
}

public void UpdateVolumeSetting(SongStem stem, double volume) {
switch (stem)
{
switch (stem) {
case SongStem.Master:
MasterVolume = volume;
Bass.GlobalStreamVolume = (int) (10_000 * MasterVolume);
Expand All @@ -337,8 +336,8 @@ public void UpdateVolumeSetting(SongStem stem, double volume) {
public double GetVolumeSetting(SongStem stem) {
return stem switch {
SongStem.Master => MasterVolume,
SongStem.Sfx => SfxVolume,
_ => _stemVolumes[(int) stem]
SongStem.Sfx => SfxVolume,
_ => _stemVolumes[(int) stem]
};
}

Expand Down
19 changes: 9 additions & 10 deletions Assets/Script/Serialization/Parser/MidiParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ private struct EventIR {
public MidiFile midi;

public MidiParser(SongEntry songEntry, string[] files) : base(songEntry, files) {
if(songEntry.SongType == SongType.RbCon){
var conSong = (ConSongEntry)songEntry;
if (songEntry.SongType == SongType.RbCon) {
var conSong = (ConSongEntry) songEntry;
using var stream = new MemoryStream(XboxCONInnerFileRetriever.RetrieveFile(
conSong.Location, conSong.NotesFile, conSong.MidiFileSize, conSong.MidiFileMemBlockOffsets
conSong.Location, conSong.MidiFileSize, conSong.MidiFileMemBlockOffsets
));
midi = MidiFile.Read(stream, new ReadingSettings() { TextEncoding = System.Text.Encoding.UTF8 });
}
else midi = MidiFile.Read(files[0], new ReadingSettings() { TextEncoding = System.Text.Encoding.UTF8 });
} else midi = MidiFile.Read(files[0], new ReadingSettings() { TextEncoding = System.Text.Encoding.UTF8 });

// TODO: fix this to account for upgrade CONs/ExCONs
// Merge midi files
Expand Down Expand Up @@ -236,7 +235,7 @@ public override void Parse(YargChart chart) {

// Add delay
foreach (var note in difficulty) {
note.time += (float)songEntry.Delay;
note.time += (float) songEntry.Delay;
}

// Last note time
Expand All @@ -249,16 +248,16 @@ public override void Parse(YargChart chart) {
// Add delay to vocals

foreach (var lyric in chart.genericLyrics) {
lyric.time += (float)songEntry.Delay;
lyric.time += (float) songEntry.Delay;
}

foreach (var lyric in chart.realLyrics) {
lyric.time += (float)songEntry.Delay;
lyric.time += (float) songEntry.Delay;
}

foreach (var lyricList in chart.harmLyrics) {
foreach (var lyric in lyricList) {
lyric.time += (float)songEntry.Delay;
lyric.time += (float) songEntry.Delay;
}
}

Expand Down Expand Up @@ -288,7 +287,7 @@ public override void Parse(YargChart chart) {

chart.events.Sort(new Comparison<EventInfo>((a, b) => a.time.CompareTo(b.time)));
foreach (var ev in chart.events) {
ev.time += (float)songEntry.Delay;
ev.time += (float) songEntry.Delay;
}

// Add beats to chart
Expand Down
43 changes: 25 additions & 18 deletions Assets/Script/Serialization/Xbox/XboxCONInnerFileRetriever.cs
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.Threading;
using Cysharp.Threading.Tasks;

namespace YARG.Serialization {
public static class XboxCONInnerFileRetriever {
public static byte[] RetrieveFile(string CONname, string filename, uint filesize, uint[] fileOffsets){
public static class XboxCONInnerFileRetriever {
public static async UniTask<byte[]> RetrieveFile(string location, uint filesize, uint[] fileOffsets, CancellationToken? ct) {
byte[] f = new byte[filesize];

byte[] f = new byte[filesize];
uint lastSize = filesize % 0x1000;
await UniTask.RunOnThreadPool(() => {
uint lastSize = filesize % 0x1000;

Parallel.For(0, fileOffsets.Length, i => {
uint ReadLen = (i == fileOffsets.Length - 1) ? lastSize : 0x1000;
using var fs = new FileStream(CONname, FileMode.Open, FileAccess.Read);
using var br = new BinaryReader(fs, new ASCIIEncoding());
fs.Seek(fileOffsets[i], SeekOrigin.Begin);
Array.Copy(br.ReadBytes((int)ReadLen), 0, f, i*0x1000, (int)ReadLen);
});
for (int i = 0; i < fileOffsets.Length; i++) {
ct?.ThrowIfCancellationRequested();

return f;
}
}
// TODO: This is unoptimized
uint ReadLen = (i == fileOffsets.Length - 1) ? lastSize : 0x1000;
using var fs = new FileStream(location, FileMode.Open, FileAccess.Read);
using var br = new BinaryReader(fs, new ASCIIEncoding());
fs.Seek(fileOffsets[i], SeekOrigin.Begin);
Array.Copy(br.ReadBytes((int) ReadLen), 0, f, i * 0x1000, (int) ReadLen);
}
});

return f;
}

public static byte[] RetrieveFile(string location, uint filesize, uint[] fileOffsets) {
return RetrieveFile(location, filesize, fileOffsets, null).AsTask().Result;
}
}
}
95 changes: 53 additions & 42 deletions Assets/Script/Serialization/Xbox/XboxImageGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,50 +1,61 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Experimental.Rendering;

namespace YARG.Serialization {
public static class XboxImageTextureGenerator {
public static Texture2D GetTexture(byte[] xboxImageBytes){
var ms = new MemoryStream(xboxImageBytes);

// Parse header
byte[] header = ms.ReadBytes(32);
byte BitsPerPixel = header[1];
int Format = BitConverter.ToInt32(header, 2);
short Width = BitConverter.ToInt16(header, 7);
short Height = BitConverter.ToInt16(header, 9);
byte[] DXTBlocks;

// Parse DXT-compressed blocks, depending on format
if ((BitsPerPixel == 0x04) && (Format == 0x08)) {
// If DXT-1 format already, read the bytes straight up
ms.Seek(32, SeekOrigin.Begin);
DXTBlocks = ms.ReadBytes((int) (ms.Length - 32));
} else {
// If DXT-3 format, we have to omit the alpha bytes
List<byte> extractedDXT3 = new List<byte>();
ms.ReadBytes(8); //skip the first 8 alpha bytes
for (int i = 8; i < (ms.Length - 32) / 2; i += 8) {
extractedDXT3.AddRange(ms.ReadBytes(8)); // We want to read these 8 bytes
ms.ReadBytes(8); // and skip these 8 bytes
}
DXTBlocks = extractedDXT3.ToArray();
}

// Swap bytes because xbox is weird like that
for(int i = 0; i < DXTBlocks.Length / 2; i++)
(DXTBlocks[i * 2], DXTBlocks[i * 2 + 1]) = (DXTBlocks[i * 2 + 1], DXTBlocks[i * 2]);

// apply DXT1 formatted bytes to a Texture2D
var tex = new Texture2D(Width, Height, GraphicsFormat.RGBA_DXT1_SRGB, TextureCreationFlags.None);
tex.LoadRawTextureData(DXTBlocks);
tex.Apply();

return tex;
}
}
public static class XboxImageTextureGenerator {
public static async UniTask<Texture2D> GetTexture(byte[] xboxImageBytes, CancellationToken ct) {
var ms = new MemoryStream(xboxImageBytes);

// Parse header
byte[] header = ms.ReadBytes(32);
byte BitsPerPixel = header[1];
int Format = BitConverter.ToInt32(header, 2);
short Width = BitConverter.ToInt16(header, 7);
short Height = BitConverter.ToInt16(header, 9);
byte[] DXTBlocks = null;

ct.ThrowIfCancellationRequested();

await UniTask.RunOnThreadPool(() => {
// Parse DXT-compressed blocks, depending on format
if ((BitsPerPixel == 0x04) && (Format == 0x08)) {
// If DXT-1 format already, read the bytes straight up
ms.Seek(32, SeekOrigin.Begin);
DXTBlocks = ms.ReadBytes((int) (ms.Length - 32));
} else {
// If DXT-3 format, we have to omit the alpha bytes
var extractedDXT3 = new List<byte>();
ms.ReadBytes(8); //skip the first 8 alpha bytes
for (int i = 8; i < (ms.Length - 32) / 2; i += 8) {
ct.ThrowIfCancellationRequested();

extractedDXT3.AddRange(ms.ReadBytes(8)); // We want to read these 8 bytes
ms.ReadBytes(8); // and skip these 8 bytes
}
DXTBlocks = extractedDXT3.ToArray();
}

// Swap bytes because xbox is weird like that
for (int i = 0; i < DXTBlocks.Length / 2; i++) {
ct.ThrowIfCancellationRequested();

(DXTBlocks[i * 2], DXTBlocks[i * 2 + 1]) = (DXTBlocks[i * 2 + 1], DXTBlocks[i * 2]);
}
});

ct.ThrowIfCancellationRequested();

// apply DXT1 formatted bytes to a Texture2D
var tex = new Texture2D(Width, Height, GraphicsFormat.RGBA_DXT1_SRGB, TextureCreationFlags.None);
tex.LoadRawTextureData(DXTBlocks);
tex.Apply();

return tex;
}
}
}
2 changes: 1 addition & 1 deletion Assets/Script/Song/Scanning/SongScanThread.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private static ScanResult ScanConSong(string cache, ConSongEntry file) {
// all good - go ahead and build the cache info

// construct the midi file
byte[] bytes = XboxCONInnerFileRetriever.RetrieveFile(file.Location, file.NotesFile, file.MidiFileSize, file.MidiFileMemBlockOffsets);
byte[] bytes = XboxCONInnerFileRetriever.RetrieveFile(file.Location, file.MidiFileSize, file.MidiFileMemBlockOffsets);

string checksum = BitConverter.ToString(SHA1.Create().ComputeHash(bytes)).Replace("-", "");

Expand Down
Loading

0 comments on commit 9826116

Please sign in to comment.