Skip to content

Commit

Permalink
Excon stuff (#282)
Browse files Browse the repository at this point in the history
* Expanded upon ExtractedCONSongEntry class (#265)

* add hopo_threshold support to please jnack

* fix DXT3 image byte parsing

* DXT3 loop cleanup

* hopo threshold fix

* actually reference hopo_threshold this time

* small RB fixes

* expand ExtractedCONSongEntry class

* improved dta parsing (#267)

* add hopo_threshold support to please jnack

* fix DXT3 image byte parsing

* DXT3 loop cleanup

* hopo threshold fix

* actually reference hopo_threshold this time

* small RB fixes

* expand ExtractedCONSongEntry class

* Fixed icons

* "Reset Camera Settings" button

* Did someone say UPDATE?

* improve dta parsing

---------

Co-authored-by: EliteAsian <lavasnakegaming@gmail.com>

* (maybe) fix issue with dta files containing brackets in symbols (#268)

* ExtractedCONSongEntry full integration (#275)

* modify ExtractedCONSongEntry to not use Xbox classes

* remove XboxSong scanner

* remove unused Xbox classes

* add notes for songs.dta members

* Fixed hopo threshold bug (#280)

* modify ExtractedCONSongEntry to not use Xbox classes

* remove XboxSong scanner

* remove unused Xbox classes

* add notes for songs.dta members

* begin con integration with CONSongEntry class and CON file detection

* begin creating ConSongEntry

* CON scanning now returns a List of ConSongEntry objects

* CONSongEntry validator implemented

* clean up mogg BASS function, fix hopo threshold bug

* edit mogg and png_xbox loaders to accept byte arrays

---------

Co-authored-by: rjkiv <76180273+rjkiv@users.noreply.github.com>
Co-authored-by: Emma <webmaster@invoxiplaygames.uk>
  • Loading branch information
3 people authored May 8, 2023
1 parent dbcdc26 commit 1930fa6
Show file tree
Hide file tree
Showing 30 changed files with 835 additions and 1,124 deletions.
12 changes: 4 additions & 8 deletions Assets/Script/Audio/Bass/BassAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,22 +204,18 @@ public void LoadSong(ICollection<string> stems, bool isSpeedUp) {
IsAudioLoaded = true;
}

public void LoadMogg(XboxMoggData moggData, bool isSpeedUp) {
public void LoadMogg(byte[] moggArray,
Dictionary<SongStem, int[]> stemMaps, float[,] matrixRatios, bool isSpeedUp) {
Debug.Log("Loading mogg song");
UnloadSong();

int moggOffset = moggData.MoggAddressAudioOffset;
long moggLength = moggData.MoggAudioLength;

byte[] moggArray = moggData.GetOggDataFromMogg();

int moggStreamHandle = Bass.CreateStream(moggArray, 0, moggLength, BassFlags.Prescan | BassFlags.Decode | BassFlags.AsyncFile);
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}");
return;
}

_mixer = new BassStemMixer(this, moggStreamHandle, moggData);
_mixer = new BassStemMixer(this, moggStreamHandle, stemMaps, matrixRatios);
if (!_mixer.Create()) {
throw new Exception($"Failed to create mixer: {Bass.LastError}");
}
Expand Down
17 changes: 10 additions & 7 deletions Assets/Script/Audio/Bass/BassStemMixer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ public class BassStemMixer : IStemMixer {

private readonly IAudioManager _manager;
private readonly Dictionary<SongStem, IStemChannel> _channels;
private readonly XboxMoggData _moggData;
private readonly bool _isMogg;

private readonly Dictionary<SongStem, int[]> _stemMaps;
private readonly float[,] _matrixRatios;

private int _mixerHandle;

private int _moggSourceHandle;
Expand All @@ -36,10 +38,11 @@ public BassStemMixer(IAudioManager manager) {
IsPlaying = false;
}

public BassStemMixer(IAudioManager manager, int moggHandle, XboxMoggData moggData) : this(manager) {
public BassStemMixer(IAudioManager manager, int moggHandle, Dictionary<SongStem, int[]> maps, float[,] ratios) : this(manager) {
_isMogg = true;
_moggSourceHandle = moggHandle;
_moggData = moggData;
_stemMaps = maps;
_matrixRatios = ratios;
}

~BassStemMixer() {
Expand Down Expand Up @@ -76,7 +79,7 @@ public bool SetupMogg(bool isSpeedUp) {
return false;
}

foreach((var stem, int[] channelIndexes) in _moggData.StemMaps) {
foreach((var stem, int[] channelIndexes) in _stemMaps) {
// For every channel index in this stem, add it to the list of channels
int[] channelStreams = channelIndexes.Select(i => splitStreams[i]).ToArray();
var channel = new BassMoggStem(_manager, stem, channelStreams);
Expand All @@ -87,8 +90,8 @@ public bool SetupMogg(bool isSpeedUp) {
var matrixes = new List<float[]>();
foreach (var channelIndex in channelIndexes) {
var matrix = new float[2];
matrix[0] = _moggData.MatrixRatios[channelIndex, 0];
matrix[1] = _moggData.MatrixRatios[channelIndex, 1];
matrix[0] = _matrixRatios[channelIndex, 0];
matrix[1] = _matrixRatios[channelIndex, 1];
matrixes.Add(matrix);
}

Expand Down Expand Up @@ -304,7 +307,7 @@ private void Dispose(bool disposing) {
}

private int[] SplitMoggIntoChannels() {
var channels = new int[_moggData.ChannelCount];
var channels = new int[_matrixRatios.GetLength(0)];

var channelMap = new int[2];
channelMap[1] = -1;
Expand Down
3 changes: 2 additions & 1 deletion Assets/Script/Audio/Interfaces/IAudioManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public interface IAudioManager {
public void LoadSfx();

public void LoadSong(ICollection<string> stems, bool isSpeedUp);
public void LoadMogg(XboxMoggData moggData, bool isSpeedUp);
// public void LoadMogg(XboxMoggData moggData, bool isSpeedUp);
public void LoadMogg(byte[] moggArray, Dictionary<SongStem, int[]> stemMaps, float[,] matrixRatios, bool isSpeedUp);
public void UnloadSong();

public void LoadPreviewAudio(SongEntry song);
Expand Down
11 changes: 0 additions & 11 deletions Assets/Script/DtxCs/DTX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -304,17 +304,6 @@ private static void ParseString(string data, DataArray root)
case '\n':
case '\t':
throw new Exception("Whitespace encountered in symbol.");
case '}':
case ')':
case ']':
current.AddNode(DataSymbol.Symbol(tmp_literal));
if (data[i] != current.ClosingChar)
{
throw new Exception("Mismatched brace types encountered.");
}
current = current.Parent;
state = ParseState.whitespace;
break;
case '\'':
current.AddNode(DataSymbol.Symbol(tmp_literal));
state = ParseState.whitespace;
Expand Down
18 changes: 14 additions & 4 deletions Assets/Script/PlayMode/Play.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using UnityEngine.InputSystem;
using YARG.Chart;
using YARG.Data;
using YARG.Serialization;
using YARG.Serialization.Parser;
using YARG.Settings;
using YARG.Song;
Expand Down Expand Up @@ -113,12 +114,21 @@ private void StartSong() {
// Determine if speed is not 1
bool isSpeedUp = Math.Abs(speed - 1) > float.Epsilon;

// Load MOGG if RB_CON, otherwise load stems
// Load MOGG if CON, otherwise load stems
if (song is ExtractedConSongEntry rawConSongEntry) {
Debug.Log(rawConSongEntry.MoggInfo.ChannelCount);
Debug.Log(rawConSongEntry.MatrixRatios.GetLength(0));

GameManager.AudioManager.LoadMogg(rawConSongEntry.MoggInfo, isSpeedUp);
} else {
GameManager.AudioManager.LoadMogg(File.ReadAllBytes(rawConSongEntry.MoggPath)[rawConSongEntry.MoggAddressAudioOffset..],
rawConSongEntry.StemMaps, rawConSongEntry.MatrixRatios, isSpeedUp);
}
else if(song is ConSongEntry conSongEntry){
Debug.Log(conSongEntry.MatrixRatios.GetLength(0));

GameManager.AudioManager.LoadMogg(XboxCONInnerFileRetriever.RetrieveFile(conSongEntry.Location, conSongEntry.MoggPath,
conSongEntry.MoggFileSize, conSongEntry.MoggFileMemBlockOffsets)[conSongEntry.MoggAddressAudioOffset..],
conSongEntry.StemMaps, conSongEntry.MatrixRatios, isSpeedUp);
}
else {
var stems = AudioHelpers.GetSupportedStems(song.Location);

GameManager.AudioManager.LoadSong(stems, isSpeedUp);
Expand Down
174 changes: 174 additions & 0 deletions Assets/Script/Serialization/Xbox/MoggBassInfoGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using DtxCS;
using DtxCS.DataTypes;
using UnityEngine;
using YARG.Data;
using YARG.Song;

namespace YARG.Serialization {
public static class MoggBASSInfoGenerator {
public static void Generate(ConSongEntry song, DataArray dta){
var Tracks = new Dictionary<string, int[]>();
float[] PanData = null, VolumeData = null;
int[] CrowdChannels = null;
int ChannelCount = 0;

for (int i = 1; i < dta.Count; i++) {
var dtaArray = (DataArray) dta[i];
switch (dtaArray[0].ToString()) {
case "tracks":
var trackArray = (DataArray) dtaArray[1];
for (int x = 0; x < trackArray.Count; x++) {
if (trackArray[x] is not DataArray instrArray) continue;
string key = ((DataSymbol) instrArray[0]).Name;
int[] val;
if (instrArray[1] is DataArray trackNums) {
if (trackNums.Count <= 0) continue;
val = new int[trackNums.Count];
for (int y = 0; y < trackNums.Count; y++)
val[y] = ((DataAtom) trackNums[y]).Int;
Tracks.Add(key, val);
} else if (instrArray[1] is DataAtom trackNum) {
val = new int[1];
val[0] = trackNum.Int;
Tracks.Add(key, val);
}
}
break;
case "pans":
var panArray = dtaArray[1] as DataArray;
PanData = new float[panArray.Count];
for (int p = 0; p < panArray.Count; p++) PanData[p] = ((DataAtom) panArray[p]).Float;
ChannelCount = panArray.Count;
break;
case "vols":
var volArray = dtaArray[1] as DataArray;
VolumeData = new float[volArray.Count];
for (int v = 0; v < volArray.Count; v++){
var volAtom = (DataAtom) volArray[v];
if(volAtom.Type == DataType.FLOAT) VolumeData[v] = ((DataAtom) volArray[v]).Float;
else VolumeData[v] = ((DataAtom) volArray[v]).Int;
}
break;
case "crowd_channels":
CrowdChannels = new int[dtaArray.Count - 1];
for (int cc = 1; cc < dtaArray.Count; cc++)
CrowdChannels[cc - 1] = ((DataAtom) dtaArray[cc]).Int;
break;
}
}

// now that we have all the info we need from dta, calculate BASS info
var mapped = new bool[ChannelCount];

// BEGIN BASS Stem Mapping ----------------------------------------------------------------------

if (Tracks.TryGetValue("drum", out var drumArray)) {
switch (drumArray.Length) {
//drum (0 1): stereo kit --> (0 1)
case 2:
song.StemMaps[SongStem.Drums] = new[] { drumArray[0], drumArray[1] };
break;
//drum (0 1 2): mono kick, stereo snare/kit --> (0) (1 2)
case 3:
song.StemMaps[SongStem.Drums1] = new[] { drumArray[0] };
song.StemMaps[SongStem.Drums2] = new[] { drumArray[1], drumArray[2] };
break;
//drum (0 1 2 3): mono kick, mono snare, stereo kit --> (0) (1) (2 3)
case 4:
song.StemMaps[SongStem.Drums1] = new[] { drumArray[0] };
song.StemMaps[SongStem.Drums2] = new[] { drumArray[1] };
song.StemMaps[SongStem.Drums3] = new[] { drumArray[2], drumArray[3] };
break;
//drum (0 1 2 3 4): mono kick, stereo snare, stereo kit --> (0) (1 2) (3 4)
case 5:
song.StemMaps[SongStem.Drums1] = new[] { drumArray[0] };
song.StemMaps[SongStem.Drums2] = new[] { drumArray[1], drumArray[2] };
song.StemMaps[SongStem.Drums3] = new[] { drumArray[3], drumArray[4] };
break;
//drum (0 1 2 3 4 5): stereo kick, stereo snare, stereo kit --> (0 1) (2 3) (4 5)
case 6:
song.StemMaps[SongStem.Drums1] = new[] { drumArray[0], drumArray[1] };
song.StemMaps[SongStem.Drums2] = new[] { drumArray[2], drumArray[3] };
song.StemMaps[SongStem.Drums3] = new[] { drumArray[4], drumArray[5] };
break;
}

foreach (int arr in drumArray) {
mapped[arr] = true;
}
}

if (Tracks.TryGetValue("bass", out var bassArray)) {
song.StemMaps[SongStem.Bass] = new int[bassArray.Length];
for (int i = 0; i < bassArray.Length; i++) {
song.StemMaps[SongStem.Bass][i] = bassArray[i];
mapped[bassArray[i]] = true;
}
}

if (Tracks.TryGetValue("guitar", out var gtrArray)) {
song.StemMaps[SongStem.Guitar] = new int[gtrArray.Length];
for (int i = 0; i < gtrArray.Length; i++) {
song.StemMaps[SongStem.Guitar][i] = gtrArray[i];
mapped[gtrArray[i]] = true;
}
}

if (Tracks.TryGetValue("vocals", out var voxArray)) {
song.StemMaps[SongStem.Vocals] = new int[voxArray.Length];
for (int i = 0; i < voxArray.Length; i++) {
song.StemMaps[SongStem.Vocals][i] = voxArray[i];
mapped[voxArray[i]] = true;
}
}

if (Tracks.TryGetValue("keys", out var keysArray)) {
song.StemMaps[SongStem.Keys] = new int[keysArray.Length];
for (int i = 0; i < keysArray.Length; i++) {
song.StemMaps[SongStem.Keys][i] = keysArray[i];
mapped[keysArray[i]] = true;
}
}

if (CrowdChannels != null) {
song.StemMaps[SongStem.Crowd] = new int[CrowdChannels.Length];
for (int i = 0; i < CrowdChannels.Length; i++) {
song.StemMaps[SongStem.Crowd][i] = CrowdChannels[i];
mapped[CrowdChannels[i]] = true;
}
}

// every index in mapped that is still false, goes in the backing
var fakeIndices = Enumerable.Range(0, mapped.Length).Where(i => !mapped[i]).ToList();
song.StemMaps[SongStem.Song] = new int[fakeIndices.Count];
for (int i = 0; i < fakeIndices.Count; i++) {
song.StemMaps[SongStem.Song][i] = fakeIndices[i];
}

// END BASS Stem Mapping ------------------------------------------------------------------------

// BEGIN BASS Matrix calculation ----------------------------------------------------------------

song.MatrixRatios = new float[PanData.Length, 2];

for(int i = 0; i < PanData.Length; i++){
float theta = PanData[i] * ((float) Math.PI / 4);
float ratioL = (float) (Math.Sqrt(2) / 2) * ((float) Math.Cos(theta) - (float) Math.Sin(theta));
float ratioR = (float) (Math.Sqrt(2) / 2) * ((float) Math.Cos(theta) + (float) Math.Sin(theta));

float volRatio = (float) Math.Pow(10, VolumeData[i] / 20);

song.MatrixRatios[i, 0] = volRatio * ratioL;
song.MatrixRatios[i, 1] = volRatio * ratioR;
}

// END BASS Matrix calculation ------------------------------------------------------------------

}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 1930fa6

Please sign in to comment.