From f9c7e5ce0591359abb207a64527a571d41f27516 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 25 Oct 2021 13:24:14 -0700 Subject: [PATCH] intial commit --- .gitignore | 3 ++ GMSAudioConverter.csproj | 18 ++++++++ GMSAudioConverter.sln | 22 +++++++++ src/GMProject.cs | 20 ++++++++ src/GMSound.cs | 33 ++++++++++++++ src/Importer.cs | 35 ++++++++++++++ src/Program.cs | 98 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 229 insertions(+) create mode 100644 .gitignore create mode 100644 GMSAudioConverter.csproj create mode 100644 GMSAudioConverter.sln create mode 100644 src/GMProject.cs create mode 100644 src/GMSound.cs create mode 100644 src/Importer.cs create mode 100644 src/Program.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e4ab67 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +bin/ +obj/ +output/ diff --git a/GMSAudioConverter.csproj b/GMSAudioConverter.csproj new file mode 100644 index 0000000..52abe02 --- /dev/null +++ b/GMSAudioConverter.csproj @@ -0,0 +1,18 @@ + + + + Exe + net5.0 + 8.0 + false + false + + + + + + + + + + diff --git a/GMSAudioConverter.sln b/GMSAudioConverter.sln new file mode 100644 index 0000000..0807725 --- /dev/null +++ b/GMSAudioConverter.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GMSAudioConverter", "GMSAudioConverter.csproj", "{CC59DC79-B418-411E-BA42-017422F30821}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CC59DC79-B418-411E-BA42-017422F30821}.Debug|x64.ActiveCfg = Debug|x64 + {CC59DC79-B418-411E-BA42-017422F30821}.Debug|x64.Build.0 = Debug|x64 + {CC59DC79-B418-411E-BA42-017422F30821}.Release|x64.ActiveCfg = Release|x86 + {CC59DC79-B418-411E-BA42-017422F30821}.Release|x64.Build.0 = Release|x86 + EndGlobalSection +EndGlobal diff --git a/src/GMProject.cs b/src/GMProject.cs new file mode 100644 index 0000000..aef5522 --- /dev/null +++ b/src/GMProject.cs @@ -0,0 +1,20 @@ +namespace GMSAudioConverter +{ + public struct GMProjectResourceValue + { + public string Name { get; set; } + public string Path { get; set; } + } + + public struct GMProjectResource + { + public GMProjectResourceValue ID { get; set; } + public uint Order { get; set; } + } + + public struct GMProject + { + public GMProjectResource[] Resources { get; set; } + public string Name { get; set; } + } +} diff --git a/src/GMSound.cs b/src/GMSound.cs new file mode 100644 index 0000000..5d5dcf4 --- /dev/null +++ b/src/GMSound.cs @@ -0,0 +1,33 @@ +namespace GMSAudioConverter +{ + public struct AudioGroupID + { + public string Name { get; set; } + public string Path { get; set; } + } + + public struct Parent + { + public string Name { get; set; } + public string Path { get; set; } + } + + public struct GMSound + { + public uint Compression { get; set; } + public float Volume { get; set; } + public bool Preload { get; set; } + public uint BitRate { get; set; } + public uint SampleRate { get; set; } + public uint Type { get; set; } + public uint BitDepth { get; set; } + public AudioGroupID AudioGroupID { get; set; } + public string SoundFile { get; set; } + public float Duration { get; set; } + public Parent Parent { get; set; } + public string ResourceVersion { get; set; } + public string Name { get; set; } + public string[] Tags { get; set; } + public string ResourceType { get; set; } + } +} diff --git a/src/Importer.cs b/src/Importer.cs new file mode 100644 index 0000000..0438160 --- /dev/null +++ b/src/Importer.cs @@ -0,0 +1,35 @@ +using System.IO; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace GMSAudioConverter +{ + public static class Importer + { + static JsonSerializerOptions options = new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + AllowTrailingCommas = true + }; + + static Importer() + { + options.Converters.Add(new JsonStringEnumConverter()); + } + + public static GMProject ImportProject(FileInfo projectFile) + { + return ImportResource(projectFile); + } + + public static GMSound ImportSound(FileInfo soundFile) + { + return ImportResource(soundFile); + } + + private static T ImportResource(FileInfo resourceFile) + { + return JsonSerializer.Deserialize(File.ReadAllText(resourceFile.FullName), options); + } + } +} diff --git a/src/Program.cs b/src/Program.cs new file mode 100644 index 0000000..190f71a --- /dev/null +++ b/src/Program.cs @@ -0,0 +1,98 @@ +using System.CommandLine; +using System.CommandLine.Invocation; +using System.IO; +using System.Text; +using System.Text.Json; + +namespace GMSAudioConverter +{ + class Program + { + static int Main(string[] args) + { + var project = new Command("project") + { + new Argument( + "project", + "Path to a GMS2.3 yyp file." + ) + }; + + var root = new RootCommand{ + project + }; + + project.Handler = CommandHandler.Create(HandleProject); + return root.Invoke(args); + } + + static void HandleProject(FileInfo project, IConsole console) + { + var jsonReaderOptions = new JsonDocumentOptions(); + jsonReaderOptions.AllowTrailingCommas = true; + + var gmProject = Importer.ImportProject(project); + var projectDir = project.Directory; + + console.Out.Write("Parsing: " + gmProject.Name); + + if (Directory.Exists("output")) + { + Directory.Delete("output", true); + } + var outputDir = Directory.CreateDirectory("output"); + var musicDir = outputDir.CreateSubdirectory("music"); + var soundDir = outputDir.CreateSubdirectory("sound"); + + foreach (var resource in gmProject.Resources) + { + var path = Path.Combine(projectDir.FullName, resource.ID.Path); + var file = new FileInfo(path); + var resourceJsonString = File.ReadAllText(path); + + var document = JsonDocument.Parse(resourceJsonString, jsonReaderOptions); + if (document.RootElement.GetProperty("resourceType").GetString() == "GMSound") + { + var soundMetadata = Importer.ImportSound(file); + var soundName = soundMetadata.Name; + var soundPath = path.Replace(".yy", ""); + + /* it's a WAV file! */ + if (File.Exists(soundPath + ".wav")) + { + File.Copy(soundPath + ".wav", Path.Combine(soundDir.FullName, soundName + ".wav"), false); + } + /* it's an OGG file! */ + else if (File.Exists(soundPath + ".ogg")) + { + File.Copy(soundPath + ".ogg", Path.Combine(musicDir.FullName, soundName + ".ogg"), false); + } + else + { + /* time to do some detection */ + var header = new byte[4]; + var stream = File.OpenRead(soundPath); + stream.Read(header, 0, 4); + + var headerString = Encoding.UTF8.GetString(header, 0, 4); + + if (headerString.Contains("RIFF")) + { + /* it's a WAV file! */ + File.Copy(soundPath, Path.Combine(soundDir.FullName, soundName + ".wav"), false); + } + else if (headerString.Contains("OggS")) + { + /* it's an OGG file! */ + File.Copy(soundPath, Path.Combine(musicDir.FullName, soundName + ".ogg"), false); + } + else + { + console.Out.Write("unrecognized header: " + headerString + "\n"); + } + } + } + } + } + } +}