Modding talk:Audio
Jump to navigation
Jump to search
Track list export
The initial track list was exported with this code, which can be run as a C# mod in Stardew Valley 1.5.5+:
source code |
---|
/// <summary>The main entry point for the mod.</summary>
public class ModEntry : Mod
{
/*********
** Public methods
*********/
/// <inheritdoc />
public override void Entry(IModHelper helper)
{
helper.Events.GameLoop.GameLaunched += (_, _) =>
{
StringBuilder output = new();
foreach (var categoryGroup in this.GetTracks().GroupBy(p => p.GetCategoryName()).OrderBy(p => p.Key))
{
output.AppendLine($"==={categoryGroup.Key}===");
output.AppendLine("{| class=\"wikitable sortable\"");
output.AppendLine("|-\n!rowspan=\"2\"| name\n!rowspan=\"2\"| wavebank\n!colspan=\"2\"| soundbank index\n!rowspan=\"2\"| description");
output.AppendLine("|-\n! decimal\n! hexadecimal");
foreach (TrackInfo track in categoryGroup.OrderBy(p => p.Name).ThenBy(p => p.Index))
output.AppendLine($"|-\n| <samp>{track.Name}</samp>\n| <samp>{track.GetWavebankName()}</samp>\n| <samp>{track.Index}</samp>\n| data-sort-value=\"{track.Index}\"| <samp>{track.GetSoundbankId()}</samp>\n| ");
output.AppendLine("|}");
output.AppendLine();
}
string result = output.ToString();
this.Monitor.Log(result, LogLevel.Info);
};
}
/*********
** Private methods
*********/
/// <summary>Extract the music/sound tracks from the game's soundbank.</summary>
private IEnumerable<TrackInfo> GetTracks()
{
SoundBank soundBank = this.Helper.Reflection.GetField<SoundBank>(Game1.soundBank, "soundBank").GetValue();
IEnumerable<CueDefinition> cues = this.Helper.Reflection.GetField<Dictionary<string, CueDefinition>>(soundBank, "_cues").GetValue().Values;
foreach (CueDefinition cue in cues)
{
foreach (XactSoundBankSound sound in cue.sounds)
{
// simple sound
if (!sound.complexSound)
{
yield return new TrackInfo(
WavebankIndex: sound.waveBankIndex,
CategoryId: sound.categoryID,
Name: cue.name,
Index: sound.trackIndex
);
continue;
}
// complex sound
bool hasVariants = false;
if (sound.soundClips != null)
{
foreach (XactClip clip in sound.soundClips)
{
foreach (ClipEvent rawClipEvent in clip.clipEvents)
{
if (rawClipEvent is not PlayWaveEvent clipEvent)
{
this.Monitor.Log($"Unexpected clip event type '{rawClipEvent.GetType().FullName}'.", LogLevel.Error);
continue;
}
foreach (PlayWaveVariant variant in clipEvent.GetVariants())
{
hasVariants = true;
yield return new TrackInfo(
WavebankIndex: variant.waveBank,
CategoryId: sound.categoryID,
Name: cue.name,
Index: variant.track
);
}
}
}
}
// invalid sound, should never happen
if (!hasVariants)
this.Monitor.Log($"Complex sound '{cue.name}' unexpectedly has no variants.", LogLevel.Error);
}
}
}
}
/// <summary>A sound or music track in a wavebank.</summary>
/// <param name="WavebankIndex">The wavebank which contains the track.</param>
/// <param name="CategoryId">The sound or music category.</param>
/// <param name="Name">The sound name used in the game code.</param>
/// <param name="Index">The offset index in the raw soundbank.</param>
public record TrackInfo(int WavebankIndex, uint CategoryId, string Name, int Index)
{
/// <summary>Get a human-readable name for the category ID.</summary>
public string GetCategoryName()
{
return this.CategoryId switch
{
2 => "Music",
3 => "Sound",
4 => "Music (ambient)",
5 => "Footsteps",
_ => this.CategoryId.ToString()
};
}
/// <summary>Get a human-readable for the wavebank index.</summary>
public string GetWavebankName()
{
return this.WavebankIndex switch
{
0 => "Wavebank",
1 => "Wavebank(1.4)",
_ => this.WavebankIndex.ToString()
};
}
/// <summary>Get the hexadecimal soundbank ID which matches the filenames exported by unxwb.</summary>
public string GetSoundbankId()
{
return this.Index
.ToString("X")
.ToLower()
.PadLeft(8, '0');
}
}
|
The game data only has the numerical category IDs, but I confirmed the internal category names with one of the game developers:
id | name | my notes |
---|---|---|
1 | Default | seems to be unused. |
2 | Music | |
3 | Sound | |
4 | Ambient | listed on the wiki as "Music (ambient)" just to group the music tracks. |
5 | Footsteps |
—Pathoschild (talk) 05:21, 17 October 2021 (UTC) (updated 00:12, 20 October 2021 (UTC))