#include "amuse/AudioGroupPool.hpp" #include "amuse/Common.hpp" #include "amuse/Entity.hpp" #include "amuse/AudioGroupData.hpp" #include "athena/MemoryReader.hpp" #include "logvisor/logvisor.hpp" namespace amuse { static logvisor::Module Log("amuse::AudioGroupPool"); static bool AtEnd(athena::io::IStreamReader& r) { uint32_t v = r.readUint32Big(); r.seek(-4, athena::Current); return v == 0xffffffff; } template AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) { AudioGroupPool ret; PoolHeader head; head.read(r); if (head.soundMacrosOffset) { r.seek(head.soundMacrosOffset, athena::Begin); while (!AtEnd(r)) { ObjectHeader objHead; atInt64 startPos = r.position(); objHead.read(r); SoundMacro& macro = ret.m_soundMacros[objHead.objectId.id]; macro.readCmds(r, objHead.size - 8); r.seek(startPos + objHead.size, athena::Begin); } } if (head.tablesOffset) { r.seek(head.tablesOffset, athena::Begin); while (!AtEnd(r)) { ObjectHeader objHead; atInt64 startPos = r.position(); objHead.read(r); auto& ptr = ret.m_tables[objHead.objectId.id]; switch (objHead.size) { case 8: ptr = std::make_unique(); static_cast(*ptr).read(r); break; case 0x14: ptr = std::make_unique(); static_cast(*ptr).read(r); break; default: ptr = std::make_unique(); static_cast(*ptr).data.resize(objHead.size - 8); r.readUBytesToBuf(&static_cast(*ptr).data[0], objHead.size - 8); break; } r.seek(startPos + objHead.size, athena::Begin); } } if (head.keymapsOffset) { r.seek(head.keymapsOffset, athena::Begin); while (!AtEnd(r)) { ObjectHeader objHead; atInt64 startPos = r.position(); objHead.read(r); Keymap& km = ret.m_keymaps[objHead.objectId.id]; km.read(r); r.seek(startPos + objHead.size, athena::Begin); } } if (head.layersOffset) { r.seek(head.layersOffset, athena::Begin); while (!AtEnd(r)) { ObjectHeader objHead; atInt64 startPos = r.position(); objHead.read(r); std::vector& lm = ret.m_layers[objHead.objectId.id]; uint32_t count; athena::io::Read::Do({}, count, r); lm.reserve(count); for (uint32_t i = 0; i < count; ++i) { lm.emplace_back(); lm.back().read(r); } r.seek(startPos + objHead.size, athena::Begin); } } return ret; } template AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r); template AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r); AudioGroupPool AudioGroupPool::CreateAudioGroupPool(const AudioGroupData& data) { athena::io::MemoryReader r(data.getPool(), data.getPoolSize()); switch (data.getDataFormat()) { case DataFormat::PC: return _AudioGroupPool(r); default: return _AudioGroupPool(r); } } template static std::unique_ptr MakeCmd(athena::io::MemoryReader& r) { std::unique_ptr ret = std::make_unique(); static_cast(*ret).read(r); return ret; } int SoundMacro::assertPC(int pc) const { if (pc == -1) return -1; if (pc >= m_cmds.size()) { fprintf(stderr, "SoundMacro PC bounds exceeded [%d/%d]\n", pc, int(m_cmds.size())); abort(); } return pc; } template void SoundMacro::readCmds(athena::io::IStreamReader& r, uint32_t size) { uint32_t numCmds = size / 8; m_cmds.reserve(numCmds); for (int i = 0; i < numCmds; ++i) { uint32_t data[2]; athena::io::Read::Do({}, data, r); athena::io::MemoryReader r(data, 8); std::unique_ptr cmd; switch (CmdOp(r.readUByte())) { case CmdOp::End: cmd = MakeCmd(r); break; case CmdOp::Stop: cmd = MakeCmd(r); break; case CmdOp::SplitKey: cmd = MakeCmd(r); break; case CmdOp::SplitVel: cmd = MakeCmd(r); break; case CmdOp::WaitTicks: cmd = MakeCmd(r); break; case CmdOp::Loop: cmd = MakeCmd(r); break; case CmdOp::Goto: cmd = MakeCmd(r); break; case CmdOp::WaitMs: cmd = MakeCmd(r); break; case CmdOp::PlayMacro: cmd = MakeCmd(r); break; case CmdOp::SendKeyOff: cmd = MakeCmd(r); break; case CmdOp::SplitMod: cmd = MakeCmd(r); break; case CmdOp::PianoPan: cmd = MakeCmd(r); break; case CmdOp::SetAdsr: cmd = MakeCmd(r); break; case CmdOp::ScaleVolume: cmd = MakeCmd(r); break; case CmdOp::Panning: cmd = MakeCmd(r); break; case CmdOp::Envelope: cmd = MakeCmd(r); break; case CmdOp::StartSample: cmd = MakeCmd(r); break; case CmdOp::StopSample: cmd = MakeCmd(r); break; case CmdOp::KeyOff: cmd = MakeCmd(r); break; case CmdOp::SplitRnd: cmd = MakeCmd(r); break; case CmdOp::FadeIn: cmd = MakeCmd(r); break; case CmdOp::Spanning: cmd = MakeCmd(r); break; case CmdOp::SetAdsrCtrl: cmd = MakeCmd(r); break; case CmdOp::RndNote: cmd = MakeCmd(r); break; case CmdOp::AddNote: cmd = MakeCmd(r); break; case CmdOp::SetNote: cmd = MakeCmd(r); break; case CmdOp::LastNote: cmd = MakeCmd(r); break; case CmdOp::Portamento: cmd = MakeCmd(r); break; case CmdOp::Vibrato: cmd = MakeCmd(r); break; case CmdOp::PitchSweep1: cmd = MakeCmd(r); break; case CmdOp::PitchSweep2: cmd = MakeCmd(r); break; case CmdOp::SetPitch: cmd = MakeCmd(r); break; case CmdOp::SetPitchAdsr: cmd = MakeCmd(r); break; case CmdOp::ScaleVolumeDLS: cmd = MakeCmd(r); break; case CmdOp::Mod2Vibrange: cmd = MakeCmd(r); break; case CmdOp::SetupTremolo: cmd = MakeCmd(r); break; case CmdOp::Return: cmd = MakeCmd(r); break; case CmdOp::GoSub: cmd = MakeCmd(r); break; case CmdOp::TrapEvent: cmd = MakeCmd(r); break; case CmdOp::UntrapEvent: cmd = MakeCmd(r); break; case CmdOp::SendMessage: cmd = MakeCmd(r); break; case CmdOp::GetMessage: cmd = MakeCmd(r); break; case CmdOp::GetVid: cmd = MakeCmd(r); break; case CmdOp::AddAgeCount: cmd = MakeCmd(r); break; case CmdOp::SetAgeCount: cmd = MakeCmd(r); break; case CmdOp::SendFlag: cmd = MakeCmd(r); break; case CmdOp::PitchWheelR: cmd = MakeCmd(r); break; case CmdOp::SetPriority: cmd = MakeCmd(r); break; case CmdOp::AddPriority: cmd = MakeCmd(r); break; case CmdOp::AgeCntSpeed: cmd = MakeCmd(r); break; case CmdOp::AgeCntVel: cmd = MakeCmd(r); break; case CmdOp::VolSelect: cmd = MakeCmd(r); break; case CmdOp::PanSelect: cmd = MakeCmd(r); break; case CmdOp::PitchWheelSelect: cmd = MakeCmd(r); break; case CmdOp::ModWheelSelect: cmd = MakeCmd(r); break; case CmdOp::PedalSelect: cmd = MakeCmd(r); break; case CmdOp::PortamentoSelect: cmd = MakeCmd(r); break; case CmdOp::ReverbSelect: cmd = MakeCmd(r); break; case CmdOp::SpanSelect: cmd = MakeCmd(r); break; case CmdOp::DopplerSelect: cmd = MakeCmd(r); break; case CmdOp::TremoloSelect: cmd = MakeCmd(r); break; case CmdOp::PreASelect: cmd = MakeCmd(r); break; case CmdOp::PreBSelect: cmd = MakeCmd(r); break; case CmdOp::PostBSelect: cmd = MakeCmd(r); break; case CmdOp::AuxAFXSelect: cmd = MakeCmd(r); break; case CmdOp::AuxBFXSelect: cmd = MakeCmd(r); break; case CmdOp::SetupLFO: cmd = MakeCmd(r); break; case CmdOp::ModeSelect: cmd = MakeCmd(r); break; case CmdOp::SetKeygroup: cmd = MakeCmd(r); break; case CmdOp::SRCmodeSelect: cmd = MakeCmd(r); break; case CmdOp::AddVars: cmd = MakeCmd(r); break; case CmdOp::SubVars: cmd = MakeCmd(r); break; case CmdOp::MulVars: cmd = MakeCmd(r); break; case CmdOp::DivVars: cmd = MakeCmd(r); break; case CmdOp::AddIVars: cmd = MakeCmd(r); break; case CmdOp::IfEqual: cmd = MakeCmd(r); break; case CmdOp::IfLess: cmd = MakeCmd(r); break; default: break; } m_cmds.push_back(std::move(cmd)); } } template void SoundMacro::readCmds(athena::io::IStreamReader& r, uint32_t size); template void SoundMacro::readCmds(athena::io::IStreamReader& r, uint32_t size); const SoundMacro* AudioGroupPool::soundMacro(ObjectId id) const { auto search = m_soundMacros.find(id); if (search == m_soundMacros.cend()) return nullptr; return &search->second; } const Keymap* AudioGroupPool::keymap(ObjectId id) const { auto search = m_keymaps.find(id); if (search == m_keymaps.cend()) return nullptr; return &search->second; } const std::vector* AudioGroupPool::layer(ObjectId id) const { auto search = m_layers.find(id); if (search == m_layers.cend()) return nullptr; return &search->second; } const ADSR* AudioGroupPool::tableAsAdsr(ObjectId id) const { auto search = m_tables.find(id); if (search == m_tables.cend()) return nullptr; return static_cast(search->second.get()); } template <> void amuse::Curve::Enumerate(athena::io::IStreamReader& r) { Log.report(logvisor::Fatal, "Curve binary DNA read not supported"); } template <> void amuse::Curve::Enumerate(athena::io::IStreamWriter& w) { Log.report(logvisor::Fatal, "Curve binary DNA write not supported"); } template <> void amuse::Curve::Enumerate(size_t& sz) { Log.report(logvisor::Fatal, "Curve binary DNA size not supported"); } template <> void amuse::Curve::Enumerate(athena::io::YAMLDocReader& r) { r.enumerate(nullptr, data); } template <> void amuse::Curve::Enumerate(athena::io::YAMLDocWriter& w) { w.enumerate(nullptr, data); } const char* amuse::Curve::DNAType() { return "amuse::ADSR"; } }