Bug fixes for MP2 extraction

This commit is contained in:
Jack Andersen
2018-09-02 14:43:05 -10:00
parent 9cc4bdefd0
commit 6a7f32a29d
16 changed files with 334 additions and 199 deletions

View File

@@ -175,6 +175,7 @@ void AudioGroupDatabase::_recursiveRenameMacro(SoundMacroId id, std::string_view
++sampleIdx;
renameSample(ss->sample.id, sampleName);
}
break;
}
case SoundMacro::CmdOp::SplitKey:
_recursiveRenameMacro(static_cast<SoundMacro::CmdSplitKey*>(cmd.get())->macro, str, macroIdx, renamedIds);
@@ -324,18 +325,23 @@ std::string AudioGroupDatabase::exportCHeader(std::string_view projectName, std:
ret += "\n"
" */\n\n\n"sv;
bool addLF = false;
for (const auto& sg : SortUnorderedMap(getProj().songGroups()))
{
auto name = amuse::GroupId::CurNameDB->resolveNameFromId(sg.first);
WriteDefineLine(ret, "GRP"sv, name, sg.first);
addLF = true;
}
for (const auto& sg : SortUnorderedMap(getProj().sfxGroups()))
{
auto name = amuse::GroupId::CurNameDB->resolveNameFromId(sg.first);
WriteDefineLine(ret, "GRP"sv, name, sg.first);
addLF = true;
}
ret += "\n\n"sv;
if (addLF)
ret += "\n\n"sv;
addLF = false;
std::unordered_set<amuse::SongId> songIds;
for (const auto& sg : getProj().songGroups())
@@ -345,9 +351,12 @@ std::string AudioGroupDatabase::exportCHeader(std::string_view projectName, std:
{
auto name = amuse::SongId::CurNameDB->resolveNameFromId(id);
WriteDefineLine(ret, "SNG"sv, name, id);
addLF = true;
}
ret += "\n\n"sv;
if (addLF)
ret += "\n\n"sv;
addLF = false;
for (const auto& sg : SortUnorderedMap(getProj().sfxGroups()))
{
@@ -355,9 +364,13 @@ std::string AudioGroupDatabase::exportCHeader(std::string_view projectName, std:
{
auto name = amuse::SFXId::CurNameDB->resolveNameFromId(sfx.first);
WriteDefineLine(ret, "SFX"sv, name, sfx.first.id);
addLF = true;
}
}
if (addLF)
ret += "\n\n"sv;
return ret;
}
}

View File

@@ -6,6 +6,7 @@
#include "logvisor/logvisor.hpp"
#include "athena/FileWriter.hpp"
#include "athena/FileReader.hpp"
#include "athena/VectorWriter.hpp"
using namespace std::literals;
@@ -204,6 +205,8 @@ template AudioGroupPool AudioGroupPool::_AudioGroupPool<athena::Little>(athena::
AudioGroupPool AudioGroupPool::CreateAudioGroupPool(const AudioGroupData& data)
{
if (data.getPoolSize() < 16)
return {};
athena::io::MemoryReader r(data.getPool(), data.getPoolSize());
switch (data.getDataFormat())
{
@@ -503,7 +506,8 @@ static SoundMacro::CmdOp _ReadCmdOp(const SoundMacro::ICmd& op)
template <class Op, class O, class... _Args>
O SoundMacro::CmdDo(_Args&&... args)
{
switch (_ReadCmdOp(std::forward<_Args>(args)...))
SoundMacro::CmdOp op = _ReadCmdOp(std::forward<_Args>(args)...);
switch (op)
{
case CmdOp::End:
return Op::template Do<CmdEnd>(std::forward<_Args>(args)...);
@@ -645,6 +649,10 @@ O SoundMacro::CmdDo(_Args&&... args)
return Op::template Do<CmdSetKeygroup>(std::forward<_Args>(args)...);
case CmdOp::SRCmodeSelect:
return Op::template Do<CmdSRCmodeSelect>(std::forward<_Args>(args)...);
case CmdOp::WiiUnknown:
return Op::template Do<CmdWiiUnknown>(std::forward<_Args>(args)...);
case CmdOp::WiiUnknown2:
return Op::template Do<CmdWiiUnknown2>(std::forward<_Args>(args)...);
case CmdOp::AddVars:
return Op::template Do<CmdAddVars>(std::forward<_Args>(args)...);
case CmdOp::SubVars:
@@ -824,6 +832,10 @@ std::string_view SoundMacro::CmdOpToStr(CmdOp op)
return "SetKeygroup"sv;
case CmdOp::SRCmodeSelect:
return "SRCmodeSelect"sv;
case CmdOp::WiiUnknown:
return "WiiUnknown"sv;
case CmdOp::WiiUnknown2:
return "WiiUnknown2"sv;
case CmdOp::AddVars:
return "AddVars"sv;
case CmdOp::SubVars:
@@ -987,6 +999,10 @@ SoundMacro::CmdOp SoundMacro::CmdStrToOp(std::string_view op)
return CmdOp::SetKeygroup;
else if (!CompareCaseInsensitive(op.data(), "SRCmodeSelect"))
return CmdOp::SRCmodeSelect;
else if (!CompareCaseInsensitive(op.data(), "WiiUnknown"))
return CmdOp::WiiUnknown;
else if (!CompareCaseInsensitive(op.data(), "WiiUnknown2"))
return CmdOp::WiiUnknown2;
else if (!CompareCaseInsensitive(op.data(), "AddVars"))
return CmdOp::AddVars;
else if (!CompareCaseInsensitive(op.data(), "SubVars"))
@@ -1006,7 +1022,7 @@ SoundMacro::CmdOp SoundMacro::CmdStrToOp(std::string_view op)
return CmdOp::Invalid;
}
bool AudioGroupPool::toYAML(SystemStringView groupPath) const
std::vector<uint8_t> AudioGroupPool::toYAML() const
{
athena::io::YAMLDocWriter w("amuse::Pool");
@@ -1081,20 +1097,15 @@ bool AudioGroupPool::toYAML(SystemStringView groupPath) const
}
}
SystemString poolPath(groupPath);
poolPath += _S("/!pool.yaml");
athena::io::FileWriter fo(poolPath);
return w.finish(&fo);
athena::io::VectorWriter fo;
w.finish(&fo);
return fo.data();
}
template <athena::Endian DNAE>
bool AudioGroupPool::toData(SystemStringView groupPath) const
std::vector<uint8_t> AudioGroupPool::toData() const
{
SystemString poolPath(groupPath);
poolPath += _S(".pool");
athena::io::FileWriter fo(poolPath);
if (fo.hasError())
return false;
athena::io::VectorWriter fo;
PoolHeader<DNAE> head = {};
head.write(fo);
@@ -1202,10 +1213,10 @@ bool AudioGroupPool::toData(SystemStringView groupPath) const
fo.seek(0, athena::Begin);
head.write(fo);
return true;
return fo.data();
}
template bool AudioGroupPool::toData<athena::Big>(SystemStringView groupPath) const;
template bool AudioGroupPool::toData<athena::Little>(SystemStringView groupPath) const;
template std::vector<uint8_t> AudioGroupPool::toData<athena::Big>() const;
template std::vector<uint8_t> AudioGroupPool::toData<athena::Little>() const;
template <>
void amuse::Curve::Enumerate<LittleDNA::Read>(athena::io::IStreamReader& r)

View File

@@ -1,3 +1,4 @@
#include <athena/VectorWriter.hpp>
#include "amuse/AudioGroupProject.hpp"
#include "amuse/AudioGroupPool.hpp"
#include "amuse/AudioGroupSampleDirectory.hpp"
@@ -331,6 +332,8 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupData& data)
{
if (data.getProjSize() < 4)
return {};
athena::io::MemoryReader r(data.getProj(), data.getProjSize());
switch (data.getDataFormat())
{
@@ -754,7 +757,7 @@ void SFXGroupIndex::toYAML(athena::io::YAMLDocWriter& w) const
}
}
bool AudioGroupProject::toYAML(SystemStringView groupPath) const
std::vector<uint8_t> AudioGroupProject::toYAML() const
{
athena::io::YAMLDocWriter w("amuse::Project");
@@ -790,10 +793,9 @@ bool AudioGroupProject::toYAML(SystemStringView groupPath) const
}
}
SystemString projPath(groupPath);
projPath += _S("/!project.yaml");
athena::io::FileWriter fo(projPath);
return w.finish(&fo);
athena::io::VectorWriter fo;
w.finish(&fo);
return fo.data();
}
#if 0
@@ -906,16 +908,12 @@ struct ObjectIdPool
};
#endif
bool AudioGroupProject::toGCNData(SystemStringView groupPath, const AudioGroupPool& pool,
const AudioGroupSampleDirectory& sdir) const
std::vector<uint8_t> AudioGroupProject::toGCNData(const AudioGroupPool& pool,
const AudioGroupSampleDirectory& sdir) const
{
constexpr athena::Endian DNAE = athena::Big;
SystemString projPath(groupPath);
projPath += _S(".proj");
athena::io::FileWriter fo(projPath);
if (fo.hasError())
return false;
athena::io::VectorWriter fo;
std::vector<GroupId> groupIds;
groupIds.reserve(m_songGroups.size() + m_sfxGroups.size());
@@ -1032,7 +1030,7 @@ bool AudioGroupProject::toGCNData(SystemStringView groupPath, const AudioGroupPo
const uint32_t finalTerm = 0xffffffff;
athena::io::Write<athena::io::PropType::None>::Do<decltype(finalTerm), DNAE>({}, finalTerm, fo);
return true;
return fo.data();
}
}

View File

@@ -8,6 +8,7 @@
#include "athena/MemoryReader.hpp"
#include "athena/FileWriter.hpp"
#include "athena/FileReader.hpp"
#include "athena/VectorWriter.hpp"
#include <cstring>
#ifndef _WIN32
#include <fcntl.h>
@@ -126,6 +127,8 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader&
AudioGroupSampleDirectory AudioGroupSampleDirectory::CreateAudioGroupSampleDirectory(const AudioGroupData& data)
{
if (data.getSdirSize() < 4)
return {};
athena::io::MemoryReader r(data.getSdir(), data.getSdirSize());
switch (data.getDataFormat())
{
@@ -885,21 +888,14 @@ void AudioGroupSampleDirectory::reloadSampleData(SystemStringView groupPath)
}
}
bool AudioGroupSampleDirectory::toGCNData(SystemStringView groupPath, const AudioGroupDatabase& group) const
std::pair<std::vector<uint8_t>, std::vector<uint8_t>>
AudioGroupSampleDirectory::toGCNData(const AudioGroupDatabase& group) const
{
constexpr athena::Endian DNAE = athena::Big;
group.setIdDatabases();
SystemString sdirPath(groupPath);
SystemString sampPath(groupPath);
sdirPath += _S(".sdir");
sampPath += _S(".samp");
athena::io::FileWriter fo(sdirPath);
if (fo.hasError())
return false;
athena::io::FileWriter sfo(sampPath);
if (sfo.hasError())
return false;
athena::io::VectorWriter fo;
athena::io::VectorWriter sfo;
std::vector<std::pair<EntryDNA<DNAE>, ADPCMParms>> entries;
entries.reserve(m_entries.size());
@@ -975,6 +971,6 @@ bool AudioGroupSampleDirectory::toGCNData(SystemStringView groupPath, const Audi
fo.writeUBytes((uint8_t*)&p.second, sizeof(ADPCMParms::DSPParms));
}
return true;
return {fo.data(), sfo.data()};
}
}

View File

@@ -192,7 +192,7 @@ bool SoundMacro::CmdEnd::Do(SoundMacroState& st, Voice& vox) const
const SoundMacro::CmdIntrospection SoundMacro::CmdStop::Introspective =
{
CmdType::Structure,
"Stop"sv,
"Stop"sv,
"Stops the macro at any point."sv,
};
bool SoundMacro::CmdStop::Do(SoundMacroState& st, Voice& vox) const
@@ -318,7 +318,7 @@ const SoundMacro::CmdIntrospection SoundMacro::CmdWaitTicks::Introspective =
bool SoundMacro::CmdWaitTicks::Do(SoundMacroState& st, Voice& vox) const
{
/* Set wait state */
if (ticksOrMs >= 0)
if (ticksOrMs != 65535)
{
float q = msSwitch ? 1000.f : st.m_ticksPerSec;
float secTime = ticksOrMs / q;
@@ -476,7 +476,7 @@ const SoundMacro::CmdIntrospection SoundMacro::CmdWaitMs::Introspective =
bool SoundMacro::CmdWaitMs::Do(SoundMacroState& st, Voice& vox) const
{
/* Set wait state */
if (ms >= 0)
if (ms != 65535)
{
float secTime = ms / 1000.f;
/* Randomize at the proper resolution */
@@ -2765,6 +2765,42 @@ bool SoundMacro::CmdSRCmodeSelect::Do(SoundMacroState& st, Voice& vox) const
return false;
}
const SoundMacro::CmdIntrospection SoundMacro::CmdWiiUnknown::Introspective =
{
CmdType::Setup,
"Wii Unknown"sv,
"????"sv,
{
{
FIELD_HEAD(SoundMacro::CmdWiiUnknown, flag),
"?"sv,
0, 1, 0
}
}
};
bool SoundMacro::CmdWiiUnknown::Do(SoundMacroState& st, Voice& vox) const
{
return false;
}
const SoundMacro::CmdIntrospection SoundMacro::CmdWiiUnknown2::Introspective =
{
CmdType::Setup,
"Wii Unknown 2"sv,
"????"sv,
{
{
FIELD_HEAD(SoundMacro::CmdWiiUnknown2, flag),
"?"sv,
0, 1, 0
}
}
};
bool SoundMacro::CmdWiiUnknown2::Do(SoundMacroState& st, Voice& vox) const
{
return false;
}
const SoundMacro::CmdIntrospection SoundMacro::CmdAddVars::Introspective =
{
CmdType::Special,

View File

@@ -431,33 +431,35 @@ void Voice::preSupplyAudio(double dt)
/* Process active pan-sweep */
bool refresh = false;
if (m_panningTime >= 0.f)
if (!m_panningQueue.empty())
{
m_panningTime += dt;
float start = (m_panPos - 64) / 64.f;
float end = (m_panPos + m_panWidth - 64) / 64.f;
float t = clamp(0.f, m_panningTime / m_panningDur, 1.f);
Panning& p = m_panningQueue.front();
p.m_time += dt;
float start = (p.m_pos - 64) / 64.f;
float end = (p.m_pos + p.m_width - 64) / 64.f;
float t = clamp(0.f, p.m_time / p.m_dur, 1.f);
_setPan((start * (1.0f - t)) + (end * t));
refresh = true;
/* Done with panning */
if (m_panningTime > m_panningDur)
m_panningTime = -1.f;
if (p.m_time > p.m_dur)
m_panningQueue.pop();
}
/* Process active span-sweep */
if (m_spanningTime >= 0.f)
if (!m_spanningQueue.empty())
{
m_spanningTime += dt;
float start = (m_spanPos - 64) / 64.f;
float end = (m_spanPos + m_spanWidth - 64) / 64.f;
float t = clamp(0.f, m_spanningTime / m_spanningDur, 1.f);
Panning& s = m_spanningQueue.front();
s.m_time += dt;
float start = (s.m_pos - 64) / 64.f;
float end = (s.m_pos + s.m_width - 64) / 64.f;
float t = clamp(0.f, s.m_time / s.m_dur, 1.f);
_setSurroundPan((start * (1.0f - t)) + (end * t));
refresh = true;
/* Done with spanning */
if (m_spanningTime > m_spanningDur)
m_spanningTime = -1.f;
if (s.m_time > s.m_dur)
m_spanningQueue.pop();
}
/* Calculate total pitch */
@@ -681,7 +683,10 @@ size_t Voice::supplyAudio(size_t samples, int16_t* data)
}
}
else
{
_macroSampleEnd();
memset(data, 0, sizeof(int16_t) * samples);
}
if (m_voxState == VoiceState::Dead)
m_curSample.reset();
@@ -1018,6 +1023,8 @@ void Voice::startSample(SampleId sampId, int32_t offset)
m_lastSamplePos = m_curSample->m_loopLengthSamples
? (m_curSample->m_loopStartSample + m_curSample->m_loopLengthSamples)
: numSamples;
if (m_lastSamplePos)
--m_lastSamplePos;
bool looped;
_checkSamplePos(looped);
@@ -1238,18 +1245,12 @@ void Voice::startFadeIn(double dur, float vol, const Curve* envCurve)
void Voice::startPanning(double dur, uint8_t panPos, int8_t panWidth)
{
m_panningTime = 0.f;
m_panningDur = dur;
m_panPos = panPos;
m_panWidth = panWidth;
m_panningQueue.push({0.f, dur, panPos, panWidth});
}
void Voice::startSpanning(double dur, uint8_t spanPos, int8_t spanWidth)
{
m_spanningTime = 0.f;
m_spanningDur = dur;
m_spanPos = spanPos;
m_spanWidth = spanWidth;
m_spanningQueue.push({0.f, dur, spanPos, spanWidth});
}
void Voice::setPitchKey(int32_t cents)