#include "CSNG.hpp" #include "amuse/SongConverter.hpp" namespace DataSpec::DNAMP1 { bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { hecl::ProjectPath midPath = outPath.getWithExtension(_SYS_STR(".mid"), true); hecl::ProjectPath yamlPath = outPath.getWithExtension(_SYS_STR(".yaml"), true); Header head; head.read(rs); { athena::io::YAMLDocWriter dw("CSNG"); dw.writeUint32("midiSetupId", head.midiSetupId); dw.writeUint32("songGroupId", head.songGroupId); if (auto rec = dw.enterSubRecord("agscId")) head.agscId.write(dw); athena::io::FileWriter w(yamlPath.getAbsolutePath()); if (w.hasError()) return false; dw.finish(&w); } { auto sng = rs.readUBytes(head.sngLength); int version; bool isBig; auto midi = amuse::SongConverter::SongToMIDI(sng.get(), version, isBig); athena::io::FileWriter w(midPath.getAbsolutePath()); if (w.hasError()) return false; w.writeUBytes(midi.data(), midi.size()); } /* Update !songs.yaml for Amuse editor */ hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), _SYS_STR("AudioGrp")); audGrp.makeDirChain(true); hecl::ProjectPath songsPath(audGrp, _SYS_STR("!songs.yaml")); std::optional r; if (songsPath.isFile()) r.emplace(songsPath.getAbsolutePath()); athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr); r = std::nullopt; ydw.writeString(fmt::format(FMT_STRING("{:04X}"), head.midiSetupId), fmt::format(FMT_STRING("../MidiData/{}"), midPath.getLastComponentUTF8())); athena::io::FileWriter w(songsPath.getAbsolutePath()); ydw.finish(&w); return true; } bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { hecl::ProjectPath midPath = inPath.getWithExtension(_SYS_STR(".mid"), true); hecl::ProjectPath yamlPath = inPath.getWithExtension(_SYS_STR(".yaml"), true); std::vector sngData; { athena::io::FileReader midR(midPath.getAbsolutePath()); if (midR.hasError()) return false; uint32_t midLen = midR.length(); std::vector midData; midData.resize(midLen); midR.readUBytesToBuf(midData.data(), midLen); sngData = amuse::SongConverter::MIDIToSong(midData, 1, true); } athena::io::FileWriter w(outPath.getAbsolutePath()); if (w.hasError()) return false; { athena::io::FileReader yamlR(yamlPath.getAbsolutePath()); if (yamlR.hasError()) return false; athena::io::YAMLDocReader dr; if (!dr.parse(&yamlR)) return false; Header head; head.midiSetupId = dr.readUint32("midiSetupId"); head.songGroupId = dr.readUint32("songGroupId"); if (auto rec = dr.enterSubRecord("agscId")) head.agscId.read(dr); head.sngLength = sngData.size(); head.write(w); } w.writeUBytes(sngData.data(), sngData.size()); return true; } } // namespace DataSpec::DNAMP1