mirror of https://github.com/AxioDL/amuse.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/amuse
This commit is contained in:
commit
c27bb5c435
|
@ -75,22 +75,47 @@ add_library(amuse
|
|||
include/amuse/VolumeTable.hpp
|
||||
)
|
||||
|
||||
target_atdna(amuse atdna_AudioGroupPool.cpp include/amuse/AudioGroupPool.hpp)
|
||||
target_atdna(amuse atdna_AudioGroupProject.cpp include/amuse/AudioGroupProject.hpp)
|
||||
target_atdna(amuse atdna_AudioGroupSampleDirectory.cpp include/amuse/AudioGroupSampleDirectory.hpp)
|
||||
|
||||
target_include_directories(amuse PUBLIC include)
|
||||
target_link_libraries(amuse
|
||||
athena-core
|
||||
lzokay
|
||||
${ZLIB_LIBRARIES}
|
||||
)
|
||||
|
||||
if(NX)
|
||||
target_sources(amuse PRIVATE include/switch_math.hpp)
|
||||
endif()
|
||||
|
||||
target_atdna(amuse atdna_AudioGroupPool.cpp include/amuse/AudioGroupPool.hpp)
|
||||
target_atdna(amuse atdna_AudioGroupProject.cpp include/amuse/AudioGroupProject.hpp)
|
||||
target_atdna(amuse atdna_AudioGroupSampleDirectory.cpp include/amuse/AudioGroupSampleDirectory.hpp)
|
||||
target_include_directories(amuse PUBLIC include)
|
||||
target_link_libraries(amuse athena-core ${ZLIB_LIBRARIES} lzokay)
|
||||
if(TARGET boo)
|
||||
target_sources(amuse PRIVATE lib/BooBackend.cpp include/amuse/BooBackend.hpp)
|
||||
target_link_libraries(amuse boo)
|
||||
endif()
|
||||
if (NOT MSVC)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(amuse PRIVATE
|
||||
# Enforce various standards compliant behavior.
|
||||
/permissive-
|
||||
|
||||
# Enable standard volatile semantics.
|
||||
/volatile:iso
|
||||
|
||||
# Reports the proper value for the __cplusplus preprocessor macro.
|
||||
/Zc:__cplusplus
|
||||
|
||||
# Allow constexpr variables to have explicit external linkage.
|
||||
/Zc:externConstexpr
|
||||
|
||||
# Assume that new throws exceptions, allowing better code generation.
|
||||
/Zc:throwingNew
|
||||
)
|
||||
else()
|
||||
target_compile_options(amuse PRIVATE -Wno-unknown-pragmas)
|
||||
endif()
|
||||
|
||||
if(COMMAND add_sanitizers)
|
||||
add_sanitizers(amuse)
|
||||
endif()
|
||||
|
|
|
@ -81,6 +81,25 @@ target_compile_definitions(amuse-gui PRIVATE
|
|||
-DQT_USE_QSTRINGBUILDER
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(amuse-gui PRIVATE
|
||||
# Enforce various standards compliant behavior.
|
||||
/permissive-
|
||||
|
||||
# Enable standard volatile semantics.
|
||||
/volatile:iso
|
||||
|
||||
# Reports the proper value for the __cplusplus preprocessor macro.
|
||||
/Zc:__cplusplus
|
||||
|
||||
# Allow constexpr variables to have explicit external linkage.
|
||||
/Zc:externConstexpr
|
||||
|
||||
# Assume that new throws exceptions, allowing better code generation.
|
||||
/Zc:throwingNew
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
target_sources(amuse-gui PRIVATE
|
||||
platforms/win/amuse-gui.rc
|
||||
|
|
|
@ -67,18 +67,22 @@ static void VisitObjectFields(ProjectModel::SoundMacroNode* n,
|
|||
break;
|
||||
switch (field.m_tp) {
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroId:
|
||||
if (!func(amuse::AccessField<amuse::SoundMacroIdDNA<athena::Little>>(p.get(), field).id,
|
||||
amuse::SoundMacroId::CurNameDB))
|
||||
if (!func(amuse::AccessField<amuse::SoundMacroIdDNA<athena::Endian::Little>>(p.get(), field).id,
|
||||
amuse::SoundMacroId::CurNameDB)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::TableId:
|
||||
if (!func(amuse::AccessField<amuse::TableIdDNA<athena::Little>>(p.get(), field).id, amuse::TableId::CurNameDB))
|
||||
if (!func(amuse::AccessField<amuse::TableIdDNA<athena::Endian::Little>>(p.get(), field).id,
|
||||
amuse::TableId::CurNameDB)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SampleId:
|
||||
if (!func(amuse::AccessField<amuse::SampleIdDNA<athena::Little>>(p.get(), field).id,
|
||||
amuse::SampleId::CurNameDB))
|
||||
if (!func(amuse::AccessField<amuse::SampleIdDNA<athena::Endian::Little>>(p.get(), field).id,
|
||||
amuse::SampleId::CurNameDB)) {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -720,7 +724,7 @@ bool ProjectModel::exportGroup(const QString& path, const QString& groupName, UI
|
|||
fo.writeUBytes(proj.data(), proj.size());
|
||||
}
|
||||
{
|
||||
auto pool = group.getPool().toData<athena::Big>();
|
||||
auto pool = group.getPool().toData<athena::Endian::Big>();
|
||||
athena::io::FileWriter fo(QStringToSysString(basePath + QStringLiteral(".pool")));
|
||||
if (fo.hasError()) {
|
||||
messenger.critical(tr("Export Error"), tr("Unable to export %1.pool").arg(groupName));
|
||||
|
|
|
@ -219,8 +219,8 @@ CommandWidget::CommandWidget(QWidget* parent, amuse::SoundMacro::ICmd* cmd, amus
|
|||
nf = new FieldProjectNode(collection, this);
|
||||
nf->setProperty("fieldIndex", f);
|
||||
nf->setProperty("fieldName", fieldName);
|
||||
int index =
|
||||
collection->indexOfId(amuse::AccessField<amuse::SoundMacroIdDNA<athena::Little>>(m_cmd, field).id);
|
||||
const int index = collection->indexOfId(
|
||||
amuse::AccessField<amuse::SoundMacroIdDNA<athena::Endian::Little>>(m_cmd, field).id);
|
||||
nf->setCurrentIndex(index < 0 ? 0 : index + 1);
|
||||
connect(nf, &FieldProjectNode::currentIndexChanged, this, &CommandWidget::nodeChanged);
|
||||
layout->addWidget(nf, 1, f);
|
||||
|
@ -231,21 +231,23 @@ CommandWidget::CommandWidget(QWidget* parent, amuse::SoundMacro::ICmd* cmd, amus
|
|||
sb->setFixedHeight(30);
|
||||
sb->setProperty("fieldIndex", f);
|
||||
sb->setProperty("fieldName", fieldName);
|
||||
sb->m_spinBox.setValue(amuse::AccessField<amuse::SoundMacroStepDNA<athena::Little>>(m_cmd, field).step);
|
||||
sb->m_spinBox.setValue(
|
||||
amuse::AccessField<amuse::SoundMacroStepDNA<athena::Endian::Little>>(m_cmd, field).step);
|
||||
connect(sb, &FieldSoundMacroStep::valueChanged, this, &CommandWidget::numChanged);
|
||||
layout->addWidget(sb, 1, f);
|
||||
m_stepField = sb;
|
||||
break;
|
||||
}
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Choice: {
|
||||
FieldComboBox* cb = new FieldComboBox(this);
|
||||
auto* const cb = new FieldComboBox(this);
|
||||
cb->setFixedHeight(30);
|
||||
cb->setProperty("fieldIndex", f);
|
||||
cb->setProperty("fieldName", fieldName);
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
if (field.m_choices[j].empty())
|
||||
for (const auto choice : field.m_choices) {
|
||||
if (choice.empty()) {
|
||||
break;
|
||||
cb->addItem(tr(field.m_choices[j].data()));
|
||||
}
|
||||
cb->addItem(tr(choice.data()));
|
||||
}
|
||||
cb->setCurrentIndex(int(amuse::AccessField<int8_t>(m_cmd, field)));
|
||||
connect(cb, qOverload<int>(&FieldComboBox::currentIndexChanged), this, &CommandWidget::numChanged);
|
||||
|
@ -315,7 +317,7 @@ public:
|
|||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroStep:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::TableId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SampleId:
|
||||
amuse::AccessField<amuse::SoundMacroIdDNA<athena::Little>>(m_cmd, m_field).id = uint16_t(m_undoVal);
|
||||
amuse::AccessField<amuse::SoundMacroIdDNA<athena::Endian::Little>>(m_cmd, m_field).id = uint16_t(m_undoVal);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -357,8 +359,8 @@ public:
|
|||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroStep:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::TableId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SampleId:
|
||||
m_undoVal = amuse::AccessField<amuse::SoundMacroIdDNA<athena::Little>>(m_cmd, m_field).id.id;
|
||||
amuse::AccessField<amuse::SoundMacroIdDNA<athena::Little>>(m_cmd, m_field).id = uint16_t(m_redoVal);
|
||||
m_undoVal = amuse::AccessField<amuse::SoundMacroIdDNA<athena::Endian::Little>>(m_cmd, m_field).id.id;
|
||||
amuse::AccessField<amuse::SoundMacroIdDNA<athena::Endian::Little>>(m_cmd, m_field).id = uint16_t(m_redoVal);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
<context>
|
||||
<name>CommandWidget</name>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="285"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="287"/>
|
||||
<source>Change %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1184,17 +1184,17 @@
|
|||
<context>
|
||||
<name>PageObjectProxyModel</name>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="364"/>
|
||||
<location filename="../ProjectModel.cpp" line="368"/>
|
||||
<source>SoundMacros:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="366"/>
|
||||
<location filename="../ProjectModel.cpp" line="370"/>
|
||||
<source>Keymaps:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="368"/>
|
||||
<location filename="../ProjectModel.cpp" line="372"/>
|
||||
<source>Layers:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1231,341 +1231,341 @@
|
|||
<context>
|
||||
<name>ProjectModel</name>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="707"/>
|
||||
<location filename="../ProjectModel.cpp" line="717"/>
|
||||
<location filename="../ProjectModel.cpp" line="726"/>
|
||||
<location filename="../ProjectModel.cpp" line="736"/>
|
||||
<location filename="../ProjectModel.cpp" line="744"/>
|
||||
<location filename="../ProjectModel.cpp" line="782"/>
|
||||
<location filename="../ProjectModel.cpp" line="711"/>
|
||||
<location filename="../ProjectModel.cpp" line="721"/>
|
||||
<location filename="../ProjectModel.cpp" line="730"/>
|
||||
<location filename="../ProjectModel.cpp" line="740"/>
|
||||
<location filename="../ProjectModel.cpp" line="748"/>
|
||||
<location filename="../ProjectModel.cpp" line="786"/>
|
||||
<source>Export Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="707"/>
|
||||
<location filename="../ProjectModel.cpp" line="757"/>
|
||||
<location filename="../ProjectModel.cpp" line="782"/>
|
||||
<location filename="../ProjectModel.cpp" line="711"/>
|
||||
<location filename="../ProjectModel.cpp" line="761"/>
|
||||
<location filename="../ProjectModel.cpp" line="786"/>
|
||||
<source>Unable to find group %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="717"/>
|
||||
<location filename="../ProjectModel.cpp" line="721"/>
|
||||
<source>Unable to export %1.proj</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="726"/>
|
||||
<location filename="../ProjectModel.cpp" line="730"/>
|
||||
<source>Unable to export %1.pool</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="736"/>
|
||||
<location filename="../ProjectModel.cpp" line="740"/>
|
||||
<source>Unable to export %1.sdir</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="744"/>
|
||||
<location filename="../ProjectModel.cpp" line="748"/>
|
||||
<source>Unable to export %1.samp</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="757"/>
|
||||
<location filename="../ProjectModel.cpp" line="761"/>
|
||||
<source>Import Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="767"/>
|
||||
<location filename="../ProjectModel.cpp" line="771"/>
|
||||
<source>Export Header Error</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="767"/>
|
||||
<location filename="../ProjectModel.cpp" line="771"/>
|
||||
<source>Unable to open %1 for reading</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="788"/>
|
||||
<location filename="../ProjectModel.cpp" line="792"/>
|
||||
<source>File Exists</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="788"/>
|
||||
<location filename="../ProjectModel.cpp" line="792"/>
|
||||
<source>%1 already exists. Overwrite?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="837"/>
|
||||
<location filename="../ProjectModel.cpp" line="841"/>
|
||||
<source>Sound Macros</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="839"/>
|
||||
<location filename="../ProjectModel.cpp" line="843"/>
|
||||
<source>ADSRs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="840"/>
|
||||
<location filename="../ProjectModel.cpp" line="844"/>
|
||||
<source>Curves</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="841"/>
|
||||
<location filename="../ProjectModel.cpp" line="845"/>
|
||||
<source>Keymaps</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="842"/>
|
||||
<location filename="../ProjectModel.cpp" line="846"/>
|
||||
<source>Layers</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="843"/>
|
||||
<location filename="../ProjectModel.cpp" line="847"/>
|
||||
<source>Samples</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1095"/>
|
||||
<location filename="../ProjectModel.cpp" line="1099"/>
|
||||
<source>Naming Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1095"/>
|
||||
<location filename="../ProjectModel.cpp" line="1099"/>
|
||||
<source>%1 already exists in this context</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1099"/>
|
||||
<location filename="../ProjectModel.cpp" line="1103"/>
|
||||
<source>Rename %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1218"/>
|
||||
<location filename="../ProjectModel.cpp" line="1222"/>
|
||||
<source>Subproject Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1219"/>
|
||||
<location filename="../ProjectModel.cpp" line="1223"/>
|
||||
<source>The subproject %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1227"/>
|
||||
<location filename="../ProjectModel.cpp" line="1782"/>
|
||||
<location filename="../ProjectModel.cpp" line="1915"/>
|
||||
<location filename="../ProjectModel.cpp" line="1231"/>
|
||||
<location filename="../ProjectModel.cpp" line="1786"/>
|
||||
<location filename="../ProjectModel.cpp" line="1919"/>
|
||||
<source>Add Subproject %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1309"/>
|
||||
<location filename="../ProjectModel.cpp" line="1313"/>
|
||||
<source>Sound Group Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1309"/>
|
||||
<location filename="../ProjectModel.cpp" line="1331"/>
|
||||
<location filename="../ProjectModel.cpp" line="1313"/>
|
||||
<location filename="../ProjectModel.cpp" line="1335"/>
|
||||
<source>The group %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1314"/>
|
||||
<location filename="../ProjectModel.cpp" line="1631"/>
|
||||
<location filename="../ProjectModel.cpp" line="1922"/>
|
||||
<location filename="../ProjectModel.cpp" line="1318"/>
|
||||
<location filename="../ProjectModel.cpp" line="1635"/>
|
||||
<location filename="../ProjectModel.cpp" line="1926"/>
|
||||
<source>Add Sound Group %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1331"/>
|
||||
<location filename="../ProjectModel.cpp" line="1335"/>
|
||||
<source>Song Group Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1336"/>
|
||||
<location filename="../ProjectModel.cpp" line="1623"/>
|
||||
<location filename="../ProjectModel.cpp" line="1929"/>
|
||||
<location filename="../ProjectModel.cpp" line="1340"/>
|
||||
<location filename="../ProjectModel.cpp" line="1627"/>
|
||||
<location filename="../ProjectModel.cpp" line="1933"/>
|
||||
<source>Add Song Group %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1432"/>
|
||||
<location filename="../ProjectModel.cpp" line="1436"/>
|
||||
<source>Sound Macro Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1432"/>
|
||||
<location filename="../ProjectModel.cpp" line="1436"/>
|
||||
<source>The macro %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1443"/>
|
||||
<location filename="../ProjectModel.cpp" line="1938"/>
|
||||
<location filename="../ProjectModel.cpp" line="1447"/>
|
||||
<location filename="../ProjectModel.cpp" line="1942"/>
|
||||
<source>Add Sound Macro %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1460"/>
|
||||
<location filename="../ProjectModel.cpp" line="1464"/>
|
||||
<source>ADSR Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1460"/>
|
||||
<location filename="../ProjectModel.cpp" line="1464"/>
|
||||
<source>The ADSR %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1467"/>
|
||||
<location filename="../ProjectModel.cpp" line="1656"/>
|
||||
<location filename="../ProjectModel.cpp" line="1945"/>
|
||||
<location filename="../ProjectModel.cpp" line="1471"/>
|
||||
<location filename="../ProjectModel.cpp" line="1660"/>
|
||||
<location filename="../ProjectModel.cpp" line="1949"/>
|
||||
<source>Add ADSR %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1484"/>
|
||||
<location filename="../ProjectModel.cpp" line="1488"/>
|
||||
<source>Curve Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1484"/>
|
||||
<location filename="../ProjectModel.cpp" line="1488"/>
|
||||
<source>The Curve %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1491"/>
|
||||
<location filename="../ProjectModel.cpp" line="1664"/>
|
||||
<location filename="../ProjectModel.cpp" line="1952"/>
|
||||
<location filename="../ProjectModel.cpp" line="1495"/>
|
||||
<location filename="../ProjectModel.cpp" line="1668"/>
|
||||
<location filename="../ProjectModel.cpp" line="1956"/>
|
||||
<source>Add Curve %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1508"/>
|
||||
<location filename="../ProjectModel.cpp" line="1512"/>
|
||||
<source>Keymap Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1508"/>
|
||||
<location filename="../ProjectModel.cpp" line="1512"/>
|
||||
<source>The Keymap %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1514"/>
|
||||
<location filename="../ProjectModel.cpp" line="1679"/>
|
||||
<location filename="../ProjectModel.cpp" line="1959"/>
|
||||
<location filename="../ProjectModel.cpp" line="1518"/>
|
||||
<location filename="../ProjectModel.cpp" line="1683"/>
|
||||
<location filename="../ProjectModel.cpp" line="1963"/>
|
||||
<source>Add Keymap %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1531"/>
|
||||
<location filename="../ProjectModel.cpp" line="1535"/>
|
||||
<source>Layers Conflict</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1531"/>
|
||||
<location filename="../ProjectModel.cpp" line="1535"/>
|
||||
<source>Layers %1 is already defined</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1537"/>
|
||||
<location filename="../ProjectModel.cpp" line="1695"/>
|
||||
<location filename="../ProjectModel.cpp" line="1966"/>
|
||||
<location filename="../ProjectModel.cpp" line="1541"/>
|
||||
<location filename="../ProjectModel.cpp" line="1699"/>
|
||||
<location filename="../ProjectModel.cpp" line="1970"/>
|
||||
<source>Add Layers %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1543"/>
|
||||
<location filename="../ProjectModel.cpp" line="1552"/>
|
||||
<location filename="../ProjectModel.cpp" line="1547"/>
|
||||
<location filename="../ProjectModel.cpp" line="1556"/>
|
||||
<source>-copy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1641"/>
|
||||
<location filename="../ProjectModel.cpp" line="1645"/>
|
||||
<source>Add SoundMacro %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1837"/>
|
||||
<location filename="../ProjectModel.cpp" line="1841"/>
|
||||
<source>Cut SongGroup %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1840"/>
|
||||
<location filename="../ProjectModel.cpp" line="1844"/>
|
||||
<source>Cut SFXGroup %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1843"/>
|
||||
<location filename="../ProjectModel.cpp" line="1847"/>
|
||||
<source>Cut SoundMacro %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1846"/>
|
||||
<location filename="../ProjectModel.cpp" line="1850"/>
|
||||
<source>Cut ADSR %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1849"/>
|
||||
<location filename="../ProjectModel.cpp" line="1853"/>
|
||||
<source>Cut Curve %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1852"/>
|
||||
<location filename="../ProjectModel.cpp" line="1856"/>
|
||||
<source>Cut Keymap %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1855"/>
|
||||
<location filename="../ProjectModel.cpp" line="1859"/>
|
||||
<source>Cut Layers %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1987"/>
|
||||
<location filename="../ProjectModel.cpp" line="1991"/>
|
||||
<source>Delete Subproject</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="1988"/>
|
||||
<location filename="../ProjectModel.cpp" line="1992"/>
|
||||
<source><p>The subproject %1 will be permanently deleted from the project. Sample files will be permanently removed from the file system.</p><p><strong>This action cannot be undone!</strong></p><p>Continue?</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2002"/>
|
||||
<location filename="../ProjectModel.cpp" line="2006"/>
|
||||
<source>Delete SongGroup %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2005"/>
|
||||
<location filename="../ProjectModel.cpp" line="2009"/>
|
||||
<source>Delete SFXGroup %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2008"/>
|
||||
<location filename="../ProjectModel.cpp" line="2012"/>
|
||||
<source>Delete SoundMacro %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2011"/>
|
||||
<location filename="../ProjectModel.cpp" line="2015"/>
|
||||
<source>Delete ADSR %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2014"/>
|
||||
<location filename="../ProjectModel.cpp" line="2018"/>
|
||||
<source>Delete Curve %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2017"/>
|
||||
<location filename="../ProjectModel.cpp" line="2021"/>
|
||||
<source>Delete Keymap %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2020"/>
|
||||
<location filename="../ProjectModel.cpp" line="2024"/>
|
||||
<source>Delete Layers %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2024"/>
|
||||
<location filename="../ProjectModel.cpp" line="2028"/>
|
||||
<source>Delete Sample</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../ProjectModel.cpp" line="2025"/>
|
||||
<location filename="../ProjectModel.cpp" line="2029"/>
|
||||
<source><p>The sample %1 will be permanently deleted from the file system. <p><strong>This action cannot be undone!</strong></p><p>Continue?</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1893,72 +1893,72 @@
|
|||
<context>
|
||||
<name>SoundMacroCatalogue</name>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="824"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="826"/>
|
||||
<source>Control</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="824"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="826"/>
|
||||
<source>Pitch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="825"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="827"/>
|
||||
<source>Sample</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="825"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="827"/>
|
||||
<source>Setup</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="826"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="828"/>
|
||||
<source>Special</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="826"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="828"/>
|
||||
<source>Structure</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="827"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="829"/>
|
||||
<source>Volume</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="830"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="832"/>
|
||||
<source>Commands to control the voice</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="831"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="833"/>
|
||||
<source>Commands to control the voice's pitch</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="832"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="834"/>
|
||||
<source>Commands to control the voice's sample playback</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="833"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="835"/>
|
||||
<source>Commands to setup the voice's mixing process</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="834"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="836"/>
|
||||
<source>Miscellaneous commands</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="835"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="837"/>
|
||||
<source>Commands to control macro branching</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="836"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="838"/>
|
||||
<source>Commands to control the voice's volume</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
@ -1974,17 +1974,17 @@
|
|||
<context>
|
||||
<name>SoundMacroListing</name>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="567"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="569"/>
|
||||
<source>Reorder %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="679"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="681"/>
|
||||
<source>Insert %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../SoundMacroEditor.cpp" line="724"/>
|
||||
<location filename="../SoundMacroEditor.cpp" line="726"/>
|
||||
<source>Delete %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
|
|
|
@ -26,7 +26,7 @@ protected:
|
|||
|
||||
public:
|
||||
SystemString getSampleBasePath(SampleId sfxId) const;
|
||||
operator bool() const { return m_valid; }
|
||||
explicit operator bool() const { return m_valid; }
|
||||
AudioGroup() = default;
|
||||
explicit AudioGroup(const AudioGroupData& data) { assign(data); }
|
||||
explicit AudioGroup(SystemStringView groupPath) { assign(groupPath); }
|
||||
|
|
|
@ -89,7 +89,9 @@ public:
|
|||
size_t getSdirSize() const { return m_sdirSz; }
|
||||
size_t getSampSize() const { return m_sampSz; }
|
||||
|
||||
operator bool() const { return m_proj != nullptr && m_pool != nullptr && m_sdir != nullptr && m_samp != nullptr; }
|
||||
explicit operator bool() const {
|
||||
return m_proj != nullptr && m_pool != nullptr && m_sdir != nullptr && m_samp != nullptr;
|
||||
}
|
||||
|
||||
DataFormat getDataFormat() const { return m_fmt; }
|
||||
bool getAbsoluteProjOffsets() const { return m_absOffs; }
|
||||
|
|
|
@ -36,7 +36,7 @@ struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) ObjectHe
|
|||
AT_DECL_DNA
|
||||
Value<atUint32, DNAEn> size;
|
||||
ObjectIdDNA<DNAEn> objectId;
|
||||
Seek<2, athena::Current> pad;
|
||||
Seek<2, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
|
||||
struct SoundMacro {
|
||||
|
@ -150,12 +150,12 @@ struct SoundMacro {
|
|||
size_t m_offset;
|
||||
std::string_view m_name;
|
||||
int64_t m_min, m_max, m_default;
|
||||
std::string_view m_choices[4];
|
||||
std::array<std::string_view, 4> m_choices;
|
||||
};
|
||||
CmdType m_tp;
|
||||
std::string_view m_name;
|
||||
std::string_view m_description;
|
||||
Field m_fields[7];
|
||||
std::array<Field, 7> m_fields;
|
||||
};
|
||||
|
||||
/** Base command interface. All versions of MusyX encode little-endian parameters */
|
||||
|
@ -180,8 +180,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> key;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SplitKey; }
|
||||
};
|
||||
|
@ -189,8 +189,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> velocity;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SplitVel; }
|
||||
};
|
||||
|
@ -212,7 +212,7 @@ struct SoundMacro {
|
|||
Value<bool> keyOff;
|
||||
Value<bool> random;
|
||||
Value<bool> sampleEnd;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
Value<atUint16> times;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::Loop; }
|
||||
|
@ -221,8 +221,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Seek<1, athena::SeekOrigin::Current> dummy;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::Goto; }
|
||||
};
|
||||
|
@ -242,8 +242,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> addNote;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
Value<atUint8> priority;
|
||||
Value<atUint8> maxVoices;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
|
@ -261,8 +261,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> modValue;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SplitMod; }
|
||||
};
|
||||
|
@ -278,7 +278,7 @@ struct SoundMacro {
|
|||
struct CmdSetAdsr : ICmd {
|
||||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
TableIdDNA<athena::Little> table;
|
||||
TableIdDNA<athena::Endian::Little> table;
|
||||
Value<bool> dlsMode;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SetAdsr; }
|
||||
|
@ -288,7 +288,7 @@ struct SoundMacro {
|
|||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> scale;
|
||||
Value<atInt8> add;
|
||||
TableIdDNA<athena::Little> table;
|
||||
TableIdDNA<athena::Endian::Little> table;
|
||||
Value<bool> originalVol;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::ScaleVolume; }
|
||||
|
@ -307,7 +307,7 @@ struct SoundMacro {
|
|||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> scale;
|
||||
Value<atInt8> add;
|
||||
TableIdDNA<athena::Little> table;
|
||||
TableIdDNA<athena::Endian::Little> table;
|
||||
Value<bool> msSwitch;
|
||||
Value<atUint16> ticksOrMs;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
|
@ -317,7 +317,7 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
enum class Mode : atInt8 { NoScale = 0, Negative = 1, Positive = 2 };
|
||||
SampleIdDNA<athena::Little> sample;
|
||||
SampleIdDNA<athena::Endian::Little> sample;
|
||||
Value<Mode> mode;
|
||||
Value<atUint32> offset;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
|
@ -339,8 +339,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<atUint8> rnd;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SplitRnd; }
|
||||
};
|
||||
|
@ -349,7 +349,7 @@ struct SoundMacro {
|
|||
static const CmdIntrospection Introspective;
|
||||
Value<atInt8> scale;
|
||||
Value<atInt8> add;
|
||||
TableIdDNA<athena::Little> table;
|
||||
TableIdDNA<athena::Endian::Little> table;
|
||||
Value<bool> msSwitch;
|
||||
Value<atUint16> ticksOrMs;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
|
@ -477,7 +477,7 @@ struct SoundMacro {
|
|||
struct CmdSetPitchAdsr : ICmd {
|
||||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
TableIdDNA<athena::Little> table;
|
||||
TableIdDNA<athena::Endian::Little> table;
|
||||
Seek<1, athena::SeekOrigin::Current> seek;
|
||||
Value<atInt8> keys;
|
||||
Value<atInt8> cents;
|
||||
|
@ -519,8 +519,8 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Seek<1, athena::SeekOrigin::Current> seek;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::GoSub; }
|
||||
};
|
||||
|
@ -529,8 +529,8 @@ struct SoundMacro {
|
|||
static const CmdIntrospection Introspective;
|
||||
enum class EventType : atInt8 { KeyOff, SampleEnd, MessageRecv };
|
||||
Value<EventType> event;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::TrapEvent; }
|
||||
};
|
||||
|
@ -545,7 +545,7 @@ struct SoundMacro {
|
|||
AT_DECL_DNA_YAMLV
|
||||
static const CmdIntrospection Introspective;
|
||||
Value<bool> isVar;
|
||||
SoundMacroIdDNA<athena::Little> macro;
|
||||
SoundMacroIdDNA<athena::Endian::Little> macro;
|
||||
Value<atUint8> voiceVar;
|
||||
Value<atUint8> valueVar;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
|
@ -908,7 +908,7 @@ struct SoundMacro {
|
|||
static const CmdIntrospection Introspective;
|
||||
Value<bool> varCtrlA;
|
||||
Value<atInt8> a;
|
||||
Seek<1, athena::Current> pad;
|
||||
Seek<1, athena::SeekOrigin::Current> pad;
|
||||
Value<atInt16> imm;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::SetVar; }
|
||||
|
@ -921,7 +921,7 @@ struct SoundMacro {
|
|||
Value<bool> varCtrlB;
|
||||
Value<atInt8> b;
|
||||
Value<bool> notEq;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::IfEqual; }
|
||||
};
|
||||
|
@ -933,7 +933,7 @@ struct SoundMacro {
|
|||
Value<bool> varCtrlB;
|
||||
Value<atInt8> b;
|
||||
Value<bool> notLt;
|
||||
SoundMacroStepDNA<athena::Little> macroStep;
|
||||
SoundMacroStepDNA<athena::Endian::Little> macroStep;
|
||||
bool Do(SoundMacroState& st, Voice& vox) const override;
|
||||
CmdOp Isa() const override { return CmdOp::IfLess; }
|
||||
};
|
||||
|
@ -1100,11 +1100,11 @@ struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) KeymapDN
|
|||
Value<atInt8> transpose;
|
||||
Value<atInt8> pan; /* -128 for surround-channel only */
|
||||
Value<atInt8> prioOffset;
|
||||
Seek<3, athena::Current> pad;
|
||||
Seek<3, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
struct Keymap : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
SoundMacroIdDNA<athena::Big> macro;
|
||||
SoundMacroIdDNA<athena::Endian::Big> macro;
|
||||
Value<atInt8> transpose = 0;
|
||||
Value<atInt8> pan = 64; /* -128 for surround-channel only */
|
||||
Value<atInt8> prioOffset = 0;
|
||||
|
@ -1142,11 +1142,11 @@ struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) LayerMap
|
|||
Value<atInt8> prioOffset;
|
||||
Value<atInt8> span;
|
||||
Value<atInt8> pan;
|
||||
Seek<3, athena::Current> pad;
|
||||
Seek<3, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
struct LayerMapping : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
SoundMacroIdDNA<athena::Big> macro;
|
||||
SoundMacroIdDNA<athena::Endian::Big> macro;
|
||||
Value<atInt8> keyLo = 0;
|
||||
Value<atInt8> keyHi = 127;
|
||||
Value<atInt8> transpose = 0;
|
||||
|
|
|
@ -46,7 +46,7 @@ struct SongGroupIndex : AudioGroupIndex {
|
|||
Value<atUint8> priority;
|
||||
Value<atUint8> maxVoices;
|
||||
Value<atUint8> programNo;
|
||||
Seek<1, athena::Current> pad;
|
||||
Seek<1, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
template <athena::Endian DNAEn>
|
||||
struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) MusyX1PageEntryDNA : BigDNA {
|
||||
|
@ -56,11 +56,11 @@ struct SongGroupIndex : AudioGroupIndex {
|
|||
Value<atUint8> maxVoices;
|
||||
Value<atUint8> unk;
|
||||
Value<atUint8> programNo;
|
||||
Seek<2, athena::Current> pad;
|
||||
Seek<2, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
struct PageEntry : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
PageObjectIdDNA<athena::Big> objId;
|
||||
PageObjectIdDNA<athena::Endian::Big> objId;
|
||||
Value<atUint8> priority = 0;
|
||||
Value<atUint8> maxVoices = 255;
|
||||
|
||||
|
@ -94,7 +94,7 @@ struct SongGroupIndex : AudioGroupIndex {
|
|||
Value<atUint8> panning;
|
||||
Value<atUint8> reverb;
|
||||
Value<atUint8> chorus;
|
||||
Seek<3, athena::Current> pad;
|
||||
Seek<3, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
struct MIDISetup : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
|
@ -130,11 +130,11 @@ struct SFXGroupIndex : AudioGroupIndex {
|
|||
Value<atUint8> defVel;
|
||||
Value<atUint8> panning;
|
||||
Value<atUint8> defKey;
|
||||
Seek<1, athena::Current> pad;
|
||||
Seek<1, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
struct SFXEntry : BigDNA {
|
||||
AT_DECL_DNA_YAML
|
||||
PageObjectIdDNA<athena::Big> objId;
|
||||
PageObjectIdDNA<athena::Endian::Big> objId;
|
||||
Value<atUint8> priority = 0;
|
||||
Value<atUint8> maxVoices = 255;
|
||||
Value<atUint8> defVel = 127;
|
||||
|
|
|
@ -31,7 +31,7 @@ struct DSPADPCMHeader : BigDNA {
|
|||
Value<atInt16> x46_loop_hist1 = 0;
|
||||
Value<atInt16> x48_loop_hist2 = 0;
|
||||
Value<atUint8> m_pitch = 0; // Stash this in the padding
|
||||
Seek<21, athena::Current> pad;
|
||||
Seek<21, athena::SeekOrigin::Current> pad;
|
||||
};
|
||||
|
||||
struct VADPCMHeader : BigDNA {
|
||||
|
@ -156,11 +156,11 @@ public:
|
|||
struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) EntryDNA : BigDNA {
|
||||
AT_DECL_DNA
|
||||
SampleIdDNA<DNAEn> m_sfxId;
|
||||
Seek<2, athena::Current> pad;
|
||||
Seek<2, athena::SeekOrigin::Current> pad;
|
||||
Value<atUint32, DNAEn> m_sampleOff;
|
||||
Value<atUint32, DNAEn> m_unk;
|
||||
Value<atUint8, DNAEn> m_pitch;
|
||||
Seek<1, athena::Current> pad2;
|
||||
Seek<1, athena::SeekOrigin::Current> pad2;
|
||||
Value<atUint16, DNAEn> m_sampleRate;
|
||||
Value<atUint32, DNAEn> m_numSamples; // Top 8 bits is SampleFormat
|
||||
Value<atUint32, DNAEn> m_loopStartSample;
|
||||
|
@ -177,7 +177,7 @@ public:
|
|||
struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) MusyX1SdirEntry : BigDNA {
|
||||
AT_DECL_DNA
|
||||
SampleIdDNA<DNAEn> m_sfxId;
|
||||
Seek<2, athena::Current> pad;
|
||||
Seek<2, athena::SeekOrigin::Current> pad;
|
||||
Value<atUint32, DNAEn> m_sampleOff;
|
||||
Value<atUint32, DNAEn> m_pitchSampleRate;
|
||||
Value<atUint32, DNAEn> m_numSamples;
|
||||
|
@ -188,7 +188,7 @@ public:
|
|||
struct AT_SPECIALIZE_PARMS(athena::Endian::Big, athena::Endian::Little) MusyX1AbsSdirEntry : BigDNA {
|
||||
AT_DECL_DNA
|
||||
SampleIdDNA<DNAEn> m_sfxId;
|
||||
Seek<2, athena::Current> pad;
|
||||
Seek<2, athena::SeekOrigin::Current> pad;
|
||||
Value<uint32_t, DNAEn> m_sampleOff;
|
||||
Value<uint32_t, DNAEn> m_unk;
|
||||
Value<uint32_t, DNAEn> m_pitchSampleRate;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
|
@ -39,7 +40,7 @@ public:
|
|||
void resetSampleRate(double sampleRate) override;
|
||||
|
||||
void resetChannelLevels() override;
|
||||
void setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) override;
|
||||
void setChannelLevels(IBackendSubmix* submix, const std::array<float, 8>& coefs, bool slew) override;
|
||||
void setPitchRatio(double ratio, bool slew) override;
|
||||
void start() override;
|
||||
void stop() override;
|
||||
|
|
|
@ -38,10 +38,10 @@ constexpr float NativeSampleRate = 32000.0f;
|
|||
namespace amuse {
|
||||
struct NameDB;
|
||||
|
||||
using BigDNA = athena::io::DNA<athena::Big>;
|
||||
using LittleDNA = athena::io::DNA<athena::Little>;
|
||||
using BigDNAV = athena::io::DNAVYaml<athena::Big>;
|
||||
using LittleDNAV = athena::io::DNAVYaml<athena::Little>;
|
||||
using BigDNA = athena::io::DNA<athena::Endian::Big>;
|
||||
using LittleDNA = athena::io::DNA<athena::Endian::Little>;
|
||||
using BigDNAV = athena::io::DNAVYaml<athena::Endian::Big>;
|
||||
using LittleDNAV = athena::io::DNAVYaml<athena::Endian::Little>;
|
||||
|
||||
/** Common ID structure statically tagging
|
||||
* SoundMacros, Tables, Keymaps, Layers, Samples, SFX, Songs */
|
||||
|
@ -216,7 +216,7 @@ public:
|
|||
bool operator!=(const ObjTokenBase& other) const noexcept { return !operator==(other); }
|
||||
bool operator<(const ObjTokenBase& other) const noexcept { return m_obj < other.m_obj; }
|
||||
bool operator>(const ObjTokenBase& other) const noexcept { return m_obj > other.m_obj; }
|
||||
operator bool() const noexcept { return m_obj != nullptr; }
|
||||
explicit operator bool() const noexcept { return m_obj != nullptr; }
|
||||
void reset() noexcept {
|
||||
if (m_obj) {
|
||||
m_obj->decrement();
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
DirectoryEnumerator(SystemStringView path, Mode mode = Mode::DirsThenFilesSorted, bool sizeSort = false,
|
||||
bool reverse = false, bool noHidden = false);
|
||||
|
||||
operator bool() const { return m_entries.size() != 0; }
|
||||
explicit operator bool() const { return m_entries.size() != 0; }
|
||||
size_t size() const { return m_entries.size(); }
|
||||
std::vector<Entry>::const_iterator begin() const { return m_entries.cbegin(); }
|
||||
std::vector<Entry>::const_iterator end() const { return m_entries.cend(); }
|
||||
|
|
|
@ -38,21 +38,21 @@ public:
|
|||
using ImpType = EffectChorusImp<T>;
|
||||
|
||||
void setBaseDelay(uint32_t baseDelay) {
|
||||
baseDelay = std::clamp(5u, baseDelay, 15u);
|
||||
baseDelay = std::clamp(baseDelay, 5u, 15u);
|
||||
x90_baseDelay = baseDelay;
|
||||
m_dirty = true;
|
||||
}
|
||||
uint32_t getBaseDelay() const { return x90_baseDelay; }
|
||||
|
||||
void setVariation(uint32_t variation) {
|
||||
variation = std::clamp(0u, variation, 5u);
|
||||
variation = std::clamp(variation, 0u, 5u);
|
||||
x94_variation = variation;
|
||||
m_dirty = true;
|
||||
}
|
||||
uint32_t getVariation() const { return x94_variation; }
|
||||
|
||||
void setPeriod(uint32_t period) {
|
||||
period = std::clamp(500u, period, 10000u);
|
||||
period = std::clamp(period, 500u, 10000u);
|
||||
x98_period = period;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
|
|
@ -51,41 +51,41 @@ public:
|
|||
using ImpType = EffectDelayImp<T>;
|
||||
|
||||
void setDelay(uint32_t delay) {
|
||||
delay = std::clamp(10u, delay, 5000u);
|
||||
delay = std::clamp(delay, 10u, 5000u);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
x3c_delay[i] = delay;
|
||||
m_dirty = true;
|
||||
}
|
||||
void setChanDelay(int chanIdx, uint32_t delay) {
|
||||
delay = std::clamp(10u, delay, 5000u);
|
||||
delay = std::clamp(delay, 10u, 5000u);
|
||||
x3c_delay[chanIdx] = delay;
|
||||
m_dirty = true;
|
||||
}
|
||||
uint32_t getChanDelay(int chanIdx) const { return x3c_delay[chanIdx]; }
|
||||
|
||||
void setFeedback(uint32_t feedback) {
|
||||
feedback = std::clamp(0u, feedback, 100u);
|
||||
feedback = std::clamp(feedback, 0u, 100u);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
x48_feedback[i] = feedback;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void setChanFeedback(int chanIdx, uint32_t feedback) {
|
||||
feedback = std::clamp(0u, feedback, 100u);
|
||||
feedback = std::clamp(feedback, 0u, 100u);
|
||||
x48_feedback[chanIdx] = feedback;
|
||||
m_dirty = true;
|
||||
}
|
||||
uint32_t getChanFeedback(int chanIdx) const { return x48_feedback[chanIdx]; }
|
||||
|
||||
void setOutput(uint32_t output) {
|
||||
output = std::clamp(0u, output, 100u);
|
||||
output = std::clamp(output, 0u, 100u);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
x54_output[i] = output;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void setChanOutput(int chanIdx, uint32_t output) {
|
||||
output = std::clamp(0u, output, 100u);
|
||||
output = std::clamp(output, 0u, 100u);
|
||||
x54_output[chanIdx] = output;
|
||||
m_dirty = true;
|
||||
}
|
||||
|
@ -93,9 +93,9 @@ public:
|
|||
|
||||
void setParams(const EffectDelayInfo& info) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
x3c_delay[i] = std::clamp(10u, info.delay[i], 5000u);
|
||||
x48_feedback[i] = std::clamp(0u, info.feedback[i], 100u);
|
||||
x54_output[i] = std::clamp(0u, info.output[i], 100u);
|
||||
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
||||
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
||||
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
||||
}
|
||||
m_dirty = true;
|
||||
}
|
||||
|
|
|
@ -75,31 +75,31 @@ public:
|
|||
using ImpType = EffectReverbStdImp<T>;
|
||||
|
||||
void setColoration(float coloration) {
|
||||
x140_x1c8_coloration = std::clamp(0.f, coloration, 1.f);
|
||||
x140_x1c8_coloration = std::clamp(coloration, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getColoration() const { return x140_x1c8_coloration; }
|
||||
|
||||
void setMix(float mix) {
|
||||
x144_x1cc_mix = std::clamp(0.f, mix, 1.f);
|
||||
x144_x1cc_mix = std::clamp(mix, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getMix() const { return x144_x1cc_mix; }
|
||||
|
||||
void setTime(float time) {
|
||||
x148_x1d0_time = std::clamp(0.01f, time, 10.f);
|
||||
x148_x1d0_time = std::clamp(time, 0.01f, 10.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getTime() const { return x148_x1d0_time; }
|
||||
|
||||
void setDamping(float damping) {
|
||||
x14c_x1d4_damping = std::clamp(0.f, damping, 1.f);
|
||||
x14c_x1d4_damping = std::clamp(damping, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getDamping() const { return x14c_x1d4_damping; }
|
||||
|
||||
void setPreDelay(float preDelay) {
|
||||
x150_x1d8_preDelay = std::clamp(0.f, preDelay, 0.1f);
|
||||
x150_x1d8_preDelay = std::clamp(preDelay, 0.f, 0.1f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getPreDelay() const { return x150_x1d8_preDelay; }
|
||||
|
@ -126,7 +126,7 @@ public:
|
|||
using ImpType = EffectReverbHiImp<T>;
|
||||
|
||||
void setCrosstalk(float crosstalk) {
|
||||
x1dc_crosstalk = std::clamp(0.f, crosstalk, 1.f);
|
||||
x1dc_crosstalk = std::clamp(crosstalk, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
float getCrosstalk() const { return x1dc_crosstalk; }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
|
||||
|
@ -10,9 +11,9 @@
|
|||
namespace amuse {
|
||||
class Listener;
|
||||
|
||||
using Vector3f = float[3];
|
||||
using Vector3f = std::array<float, 3>;
|
||||
|
||||
inline float Dot(const Vector3f& a, const Vector3f& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }
|
||||
constexpr float Dot(const Vector3f& a, const Vector3f& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; }
|
||||
|
||||
inline float Length(const Vector3f& a) {
|
||||
if (std::fabs(a[0]) <= FLT_EPSILON && std::fabs(a[1]) <= FLT_EPSILON && std::fabs(a[2]) <= FLT_EPSILON)
|
||||
|
@ -20,14 +21,14 @@ inline float Length(const Vector3f& a) {
|
|||
return std::sqrt(Dot(a, a));
|
||||
}
|
||||
|
||||
inline float Normalize(Vector3f& out) {
|
||||
float dist = Length(out);
|
||||
if (dist == 0.f)
|
||||
return 0.f;
|
||||
out[0] /= dist;
|
||||
out[1] /= dist;
|
||||
out[2] /= dist;
|
||||
return dist;
|
||||
inline Vector3f Normalize(const Vector3f& in) {
|
||||
const float dist = Length(in);
|
||||
|
||||
if (dist == 0.f) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {in[0] / dist, in[1] / dist, in[2] / dist};
|
||||
}
|
||||
|
||||
/** Voice wrapper with positional-3D level control */
|
||||
|
@ -56,7 +57,7 @@ public:
|
|||
|
||||
void setVectors(const float* pos, const float* dir);
|
||||
void setMaxVol(float maxVol) {
|
||||
m_maxVol = std::clamp(0.f, maxVol, 1.f);
|
||||
m_maxVol = std::clamp(maxVol, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace amuse {
|
||||
class IBackendSubmix;
|
||||
|
||||
|
@ -34,7 +36,7 @@ public:
|
|||
virtual void resetChannelLevels() = 0;
|
||||
|
||||
/** Set channel-gains for audio source (AudioChannel enum for array index) */
|
||||
virtual void setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) = 0;
|
||||
virtual void setChannelLevels(IBackendSubmix* submix, const std::array<float, 8>& coefs, bool slew) = 0;
|
||||
|
||||
/** Called by client to dynamically adjust the pitch of voices with dynamic pitch enabled */
|
||||
virtual void setPitchRatio(double ratio, bool slew) = 0;
|
||||
|
|
|
@ -19,10 +19,10 @@ class Listener {
|
|||
|
||||
public:
|
||||
Listener(float volume, float frontDiff, float backDiff, float soundSpeed)
|
||||
: m_volume(std::clamp(0.f, volume, 1.f)), m_frontDiff(frontDiff), m_backDiff(backDiff), m_soundSpeed(soundSpeed) {}
|
||||
: m_volume(std::clamp(volume, 0.f, 1.f)), m_frontDiff(frontDiff), m_backDiff(backDiff), m_soundSpeed(soundSpeed) {}
|
||||
void setVectors(const float* pos, const float* dir, const float* heading, const float* up);
|
||||
void setVolume(float vol) {
|
||||
m_volume = std::clamp(0.f, vol, 1.f);
|
||||
m_volume = std::clamp(vol, 0.f, 1.f);
|
||||
m_dirty = true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -45,26 +45,26 @@ class Sequencer : public Entity {
|
|||
/** State of a single MIDI channel */
|
||||
struct ChannelState {
|
||||
Sequencer* m_parent = nullptr;
|
||||
uint8_t m_chanId;
|
||||
uint8_t m_chanId = 0;
|
||||
const SongGroupIndex::MIDISetup* m_setup = nullptr; /* Channel defaults to program 0 if null */
|
||||
const SongGroupIndex::PageEntry* m_page = nullptr;
|
||||
~ChannelState();
|
||||
ChannelState() = default;
|
||||
ChannelState(Sequencer& parent, uint8_t chanId);
|
||||
operator bool() const { return m_parent != nullptr; }
|
||||
explicit operator bool() const { return m_parent != nullptr; }
|
||||
|
||||
/** Voices corresponding to currently-pressed keys in channel */
|
||||
std::unordered_map<uint8_t, ObjToken<Voice>> m_chanVoxs;
|
||||
std::unordered_set<ObjToken<Voice>> m_keyoffVoxs;
|
||||
ObjToken<Voice> m_lastVoice;
|
||||
int8_t m_ctrlVals[128] = {}; /**< MIDI controller values */
|
||||
float m_curPitchWheel = 0.f; /**< MIDI pitch-wheel */
|
||||
int8_t m_pitchWheelRange = -1; /**< Pitch wheel range settable by RPN 0 */
|
||||
int8_t m_curProgram = 0; /**< MIDI program number */
|
||||
float m_curVol = 1.f; /**< Current volume of channel */
|
||||
float m_curPan = 0.f; /**< Current panning of channel */
|
||||
uint16_t m_rpn = 0; /**< Current RPN (only pitch-range 0x0000 supported) */
|
||||
double m_ticksPerSec = 1000.0; /**< Current ticks per second (tempo) for channel */
|
||||
std::array<int8_t, 128> m_ctrlVals{}; /**< MIDI controller values */
|
||||
float m_curPitchWheel = 0.f; /**< MIDI pitch-wheel */
|
||||
int8_t m_pitchWheelRange = -1; /**< Pitch wheel range settable by RPN 0 */
|
||||
int8_t m_curProgram = 0; /**< MIDI program number */
|
||||
float m_curVol = 1.f; /**< Current volume of channel */
|
||||
float m_curPan = 0.f; /**< Current panning of channel */
|
||||
uint16_t m_rpn = 0; /**< Current RPN (only pitch-range 0x0000 supported) */
|
||||
double m_ticksPerSec = 1000.0; /**< Current ticks per second (tempo) for channel */
|
||||
|
||||
void _bringOutYourDead();
|
||||
size_t getVoiceCount() const;
|
||||
|
|
|
@ -94,7 +94,7 @@ class SongState {
|
|||
|
||||
Track() = default;
|
||||
Track(SongState& parent, uint8_t midiChan, uint32_t loopStart, const TrackRegion* regions, uint32_t tempo);
|
||||
operator bool() const { return m_parent != nullptr; }
|
||||
explicit operator bool() const { return m_parent != nullptr; }
|
||||
void setRegion(const TrackRegion* region);
|
||||
void advanceRegion();
|
||||
bool advance(Sequencer& seq, double dt);
|
||||
|
|
|
@ -78,7 +78,7 @@ struct SoundMacroState {
|
|||
float evaluate(double time, const Voice& vox, const SoundMacroState& st) const;
|
||||
|
||||
/** Determine if able to use */
|
||||
operator bool() const { return m_comps.size() != 0; }
|
||||
explicit operator bool() const { return m_comps.size() != 0; }
|
||||
};
|
||||
|
||||
Evaluator m_volumeSel;
|
||||
|
|
|
@ -18,7 +18,7 @@ class Studio {
|
|||
|
||||
std::list<StudioSend> m_studiosOut;
|
||||
#ifndef NDEBUG
|
||||
bool _cyclicCheck(Studio* leaf);
|
||||
bool _cyclicCheck(const Studio* leaf) const;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
|
@ -146,7 +147,7 @@ class Voice : public Entity {
|
|||
float m_tremoloScale = 0.f; /**< minimum volume factor produced via LFO */
|
||||
float m_tremoloModScale = 0.f; /**< minimum volume factor produced via LFO, scaled via mod wheel */
|
||||
|
||||
float m_lfoPeriods[2] = {}; /**< time-periods for LFO1 and LFO2 */
|
||||
std::array<float, 2> m_lfoPeriods{}; /**< time-periods for LFO1 and LFO2 */
|
||||
std::unique_ptr<int8_t[]> m_ctrlValsSelf; /**< Self-owned MIDI Controller values */
|
||||
int8_t* m_extCtrlVals = nullptr; /**< MIDI Controller values (external storage) */
|
||||
|
||||
|
@ -186,10 +187,10 @@ class Voice : public Entity {
|
|||
ObjToken<Voice> _startChildMacro(ObjectId macroId, int macroStep, double ticksPerSec, uint8_t midiKey,
|
||||
uint8_t midiVel, uint8_t midiMod, bool pushPc = false);
|
||||
|
||||
void _panLaw(float coefsOut[8], float frontPan, float backPan, float totalSpan) const;
|
||||
std::array<float, 8> _panLaw(float frontPan, float backPan, float totalSpan) const;
|
||||
void _setPan(float pan);
|
||||
void _setSurroundPan(float span);
|
||||
void _setChannelCoefs(const float coefs[8]);
|
||||
void _setChannelCoefs(const std::array<float, 8>& coefs);
|
||||
void _setPitchWheel(float pitchWheel);
|
||||
void _notifyCtrlChange(uint8_t ctrl, int8_t val);
|
||||
|
||||
|
@ -261,7 +262,7 @@ public:
|
|||
void setSurroundPan(float span);
|
||||
|
||||
/** Set current voice channel coefficients immediately */
|
||||
void setChannelCoefs(const float coefs[8]);
|
||||
void setChannelCoefs(const std::array<float, 8>& coefs);
|
||||
|
||||
/** Start volume envelope to specified level */
|
||||
void startEnvelope(double dur, float vol, const Curve* envCurve);
|
||||
|
|
|
@ -37,41 +37,42 @@ struct MakeDefaultCmdOp {
|
|||
static std::unique_ptr<SoundMacro::ICmd> Do(R& r) {
|
||||
std::unique_ptr<SoundMacro::ICmd> ret = std::make_unique<Tp>();
|
||||
if (const SoundMacro::CmdIntrospection* introspection = SoundMacro::GetCmdIntrospection(r)) {
|
||||
for (int f = 0; f < 7; ++f) {
|
||||
const amuse::SoundMacro::CmdIntrospection::Field& field = introspection->m_fields[f];
|
||||
if (!field.m_name.empty()) {
|
||||
switch (field.m_tp) {
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Bool:
|
||||
AccessField<bool>(ret.get(), field) = bool(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int8:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Choice:
|
||||
AccessField<int8_t>(ret.get(), field) = int8_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt8:
|
||||
AccessField<uint8_t>(ret.get(), field) = uint8_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int16:
|
||||
AccessField<int16_t>(ret.get(), field) = int16_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt16:
|
||||
AccessField<uint16_t>(ret.get(), field) = uint16_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int32:
|
||||
AccessField<int32_t>(ret.get(), field) = int32_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt32:
|
||||
AccessField<uint32_t>(ret.get(), field) = uint32_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroStep:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::TableId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SampleId:
|
||||
AccessField<SoundMacroIdDNA<athena::Little>>(ret.get(), field).id = uint16_t(field.m_default);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (const auto& field : introspection->m_fields) {
|
||||
if (field.m_name.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (field.m_tp) {
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Bool:
|
||||
AccessField<bool>(ret.get(), field) = bool(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int8:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Choice:
|
||||
AccessField<int8_t>(ret.get(), field) = int8_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt8:
|
||||
AccessField<uint8_t>(ret.get(), field) = uint8_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int16:
|
||||
AccessField<int16_t>(ret.get(), field) = int16_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt16:
|
||||
AccessField<uint16_t>(ret.get(), field) = uint16_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::Int32:
|
||||
AccessField<int32_t>(ret.get(), field) = int32_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::UInt32:
|
||||
AccessField<uint32_t>(ret.get(), field) = uint32_t(field.m_default);
|
||||
break;
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SoundMacroStep:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::TableId:
|
||||
case amuse::SoundMacro::CmdIntrospection::Field::Type::SampleId:
|
||||
AccessField<SoundMacroIdDNA<athena::Endian::Little>>(ret.get(), field).id = uint16_t(field.m_default);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +89,7 @@ struct IntrospectCmdOp {
|
|||
|
||||
static bool AtEnd(athena::io::IStreamReader& r) {
|
||||
uint32_t v = r.readUint32Big();
|
||||
r.seek(-4, athena::Current);
|
||||
r.seek(-4, athena::SeekOrigin::Current);
|
||||
return v == 0xffffffff;
|
||||
}
|
||||
|
||||
|
@ -100,7 +101,7 @@ AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) {
|
|||
head.read(r);
|
||||
|
||||
if (head.soundMacrosOffset) {
|
||||
r.seek(head.soundMacrosOffset, athena::Begin);
|
||||
r.seek(head.soundMacrosOffset, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd(r)) {
|
||||
ObjectHeader<DNAE> objHead;
|
||||
atInt64 startPos = r.position();
|
||||
|
@ -111,12 +112,12 @@ AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) {
|
|||
auto& macro = ret.m_soundMacros[objHead.objectId.id];
|
||||
macro = MakeObj<SoundMacro>();
|
||||
macro->template readCmds<DNAE>(r, objHead.size - 8);
|
||||
r.seek(startPos + objHead.size, athena::Begin);
|
||||
r.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
if (head.tablesOffset) {
|
||||
r.seek(head.tablesOffset, athena::Begin);
|
||||
r.seek(head.tablesOffset, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd(r)) {
|
||||
ObjectHeader<DNAE> objHead;
|
||||
atInt64 startPos = r.position();
|
||||
|
@ -139,12 +140,12 @@ AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) {
|
|||
r.readUBytesToBuf(&static_cast<Curve&>(**ptr).data[0], objHead.size - 8);
|
||||
break;
|
||||
}
|
||||
r.seek(startPos + objHead.size, athena::Begin);
|
||||
r.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
if (head.keymapsOffset) {
|
||||
r.seek(head.keymapsOffset, athena::Begin);
|
||||
r.seek(head.keymapsOffset, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd(r)) {
|
||||
ObjectHeader<DNAE> objHead;
|
||||
atInt64 startPos = r.position();
|
||||
|
@ -159,12 +160,12 @@ AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) {
|
|||
kmData.read(r);
|
||||
(*km)[i] = kmData;
|
||||
}
|
||||
r.seek(startPos + objHead.size, athena::Begin);
|
||||
r.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
if (head.layersOffset) {
|
||||
r.seek(head.layersOffset, athena::Begin);
|
||||
r.seek(head.layersOffset, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd(r)) {
|
||||
ObjectHeader<DNAE> objHead;
|
||||
atInt64 startPos = r.position();
|
||||
|
@ -182,14 +183,14 @@ AudioGroupPool AudioGroupPool::_AudioGroupPool(athena::io::IStreamReader& r) {
|
|||
lmData.read(r);
|
||||
lm->push_back(lmData);
|
||||
}
|
||||
r.seek(startPos + objHead.size, athena::Begin);
|
||||
r.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
template AudioGroupPool AudioGroupPool::_AudioGroupPool<athena::Big>(athena::io::IStreamReader& r);
|
||||
template AudioGroupPool AudioGroupPool::_AudioGroupPool<athena::Little>(athena::io::IStreamReader& r);
|
||||
template AudioGroupPool AudioGroupPool::_AudioGroupPool<athena::Endian::Big>(athena::io::IStreamReader& r);
|
||||
template AudioGroupPool AudioGroupPool::_AudioGroupPool<athena::Endian::Little>(athena::io::IStreamReader& r);
|
||||
|
||||
AudioGroupPool AudioGroupPool::CreateAudioGroupPool(const AudioGroupData& data) {
|
||||
if (data.getPoolSize() < 16)
|
||||
|
@ -197,9 +198,9 @@ AudioGroupPool AudioGroupPool::CreateAudioGroupPool(const AudioGroupData& data)
|
|||
athena::io::MemoryReader r(data.getPool(), data.getPoolSize());
|
||||
switch (data.getDataFormat()) {
|
||||
case DataFormat::PC:
|
||||
return _AudioGroupPool<athena::Little>(r);
|
||||
return _AudioGroupPool<athena::Endian::Little>(r);
|
||||
default:
|
||||
return _AudioGroupPool<athena::Big>(r);
|
||||
return _AudioGroupPool<athena::Endian::Big>(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,8 +340,8 @@ void SoundMacro::readCmds(athena::io::IStreamReader& r, uint32_t size) {
|
|||
m_cmds.push_back(CmdDo<MakeCmdOp, std::unique_ptr<ICmd>>(mr));
|
||||
}
|
||||
}
|
||||
template void SoundMacro::readCmds<athena::Big>(athena::io::IStreamReader& r, uint32_t size);
|
||||
template void SoundMacro::readCmds<athena::Little>(athena::io::IStreamReader& r, uint32_t size);
|
||||
template void SoundMacro::readCmds<athena::Endian::Big>(athena::io::IStreamReader& r, uint32_t size);
|
||||
template void SoundMacro::readCmds<athena::Endian::Little>(athena::io::IStreamReader& r, uint32_t size);
|
||||
|
||||
template <athena::Endian DNAE>
|
||||
void SoundMacro::writeCmds(athena::io::IStreamWriter& w) const {
|
||||
|
@ -352,8 +353,8 @@ void SoundMacro::writeCmds(athena::io::IStreamWriter& w) const {
|
|||
athena::io::Write<athena::io::PropType::None>::Do<decltype(data), DNAE>({}, data, w);
|
||||
}
|
||||
}
|
||||
template void SoundMacro::writeCmds<athena::Big>(athena::io::IStreamWriter& w) const;
|
||||
template void SoundMacro::writeCmds<athena::Little>(athena::io::IStreamWriter& w) const;
|
||||
template void SoundMacro::writeCmds<athena::Endian::Big>(athena::io::IStreamWriter& w) const;
|
||||
template void SoundMacro::writeCmds<athena::Endian::Little>(athena::io::IStreamWriter& w) const;
|
||||
|
||||
void SoundMacro::buildFromPrototype(const SoundMacro& other) {
|
||||
m_cmds.reserve(other.m_cmds.size());
|
||||
|
@ -1019,9 +1020,9 @@ std::vector<uint8_t> AudioGroupPool::toData() const {
|
|||
p.second->template writeCmds<DNAE>(fo);
|
||||
objHead.size = fo.position() - startPos;
|
||||
objHead.objectId = p.first;
|
||||
fo.seek(startPos, athena::Begin);
|
||||
fo.seek(startPos, athena::SeekOrigin::Begin);
|
||||
objHead.write(fo);
|
||||
fo.seek(startPos + objHead.size, athena::Begin);
|
||||
fo.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
athena::io::Write<athena::io::PropType::None>::Do<decltype(term), DNAE>({}, term, fo);
|
||||
}
|
||||
|
@ -1049,9 +1050,9 @@ std::vector<uint8_t> AudioGroupPool::toData() const {
|
|||
}
|
||||
objHead.size = fo.position() - startPos;
|
||||
objHead.objectId = p.first;
|
||||
fo.seek(startPos, athena::Begin);
|
||||
fo.seek(startPos, athena::SeekOrigin::Begin);
|
||||
objHead.write(fo);
|
||||
fo.seek(startPos + objHead.size, athena::Begin);
|
||||
fo.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
athena::io::Write<athena::io::PropType::None>::Do<decltype(term), DNAE>({}, term, fo);
|
||||
}
|
||||
|
@ -1068,9 +1069,9 @@ std::vector<uint8_t> AudioGroupPool::toData() const {
|
|||
}
|
||||
objHead.size = fo.position() - startPos;
|
||||
objHead.objectId = p.first;
|
||||
fo.seek(startPos, athena::Begin);
|
||||
fo.seek(startPos, athena::SeekOrigin::Begin);
|
||||
objHead.write(fo);
|
||||
fo.seek(startPos + objHead.size, athena::Begin);
|
||||
fo.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
athena::io::Write<athena::io::PropType::None>::Do<decltype(term), DNAE>({}, term, fo);
|
||||
}
|
||||
|
@ -1089,20 +1090,20 @@ std::vector<uint8_t> AudioGroupPool::toData() const {
|
|||
}
|
||||
objHead.size = fo.position() - startPos;
|
||||
objHead.objectId = p.first;
|
||||
fo.seek(startPos, athena::Begin);
|
||||
fo.seek(startPos, athena::SeekOrigin::Begin);
|
||||
objHead.write(fo);
|
||||
fo.seek(startPos + objHead.size, athena::Begin);
|
||||
fo.seek(startPos + objHead.size, athena::SeekOrigin::Begin);
|
||||
}
|
||||
athena::io::Write<athena::io::PropType::None>::Do<decltype(term), DNAE>({}, term, fo);
|
||||
}
|
||||
|
||||
fo.seek(0, athena::Begin);
|
||||
fo.seek(0, athena::SeekOrigin::Begin);
|
||||
head.write(fo);
|
||||
|
||||
return fo.data();
|
||||
}
|
||||
template std::vector<uint8_t> AudioGroupPool::toData<athena::Big>() const;
|
||||
template std::vector<uint8_t> AudioGroupPool::toData<athena::Little>() const;
|
||||
template std::vector<uint8_t> AudioGroupPool::toData<athena::Endian::Big>() const;
|
||||
template std::vector<uint8_t> AudioGroupPool::toData<athena::Endian::Little>() const;
|
||||
|
||||
template <>
|
||||
void amuse::Curve::Enumerate<LittleDNA::Read>(athena::io::IStreamReader& r) {
|
||||
|
|
|
@ -13,19 +13,19 @@ namespace amuse {
|
|||
|
||||
static bool AtEnd64(athena::io::IStreamReader& r) {
|
||||
uint64_t v = r.readUint64Big();
|
||||
r.seek(-8, athena::Current);
|
||||
r.seek(-8, athena::SeekOrigin::Current);
|
||||
return v == 0xffffffffffffffff;
|
||||
}
|
||||
|
||||
static bool AtEnd32(athena::io::IStreamReader& r) {
|
||||
uint32_t v = r.readUint32Big();
|
||||
r.seek(-4, athena::Current);
|
||||
r.seek(-4, athena::SeekOrigin::Current);
|
||||
return v == 0xffffffff;
|
||||
}
|
||||
|
||||
static bool AtEnd16(athena::io::IStreamReader& r) {
|
||||
uint16_t v = r.readUint16Big();
|
||||
r.seek(-2, athena::Current);
|
||||
r.seek(-2, athena::SeekOrigin::Current);
|
||||
return v == 0xffff;
|
||||
}
|
||||
|
||||
|
@ -82,37 +82,42 @@ static void WriteRangedObjectIds(athena::io::IStreamWriter& w, const T& list) {
|
|||
|
||||
AudioGroupProject::AudioGroupProject(athena::io::IStreamReader& r, GCNDataTag) {
|
||||
while (!AtEnd32(r)) {
|
||||
GroupHeader<athena::Big> header;
|
||||
GroupHeader<athena::Endian::Big> header;
|
||||
header.read(r);
|
||||
|
||||
if (GroupId::CurNameDB)
|
||||
GroupId::CurNameDB->registerPair(NameDB::generateName(header.groupId, NameDB::Type::Group), header.groupId);
|
||||
|
||||
#if 0
|
||||
/* Sound Macros */
|
||||
r.seek(header.soundMacroIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
/* Sound Macros */
|
||||
r.seek(header.soundMacroIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
}
|
||||
|
||||
/* Samples */
|
||||
r.seek(header.samplIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
/* Samples */
|
||||
r.seek(header.samplIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
r.seek(header.tableIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
/* Tables */
|
||||
r.seek(header.tableIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
}
|
||||
|
||||
/* Keymaps */
|
||||
r.seek(header.keymapIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
/* Keymaps */
|
||||
r.seek(header.keymapIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
}
|
||||
|
||||
/* Layers */
|
||||
r.seek(header.layerIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
/* Layers */
|
||||
r.seek(header.layerIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (header.type == GroupType::Song) {
|
||||
|
@ -120,43 +125,45 @@ AudioGroupProject::AudioGroupProject(athena::io::IStreamReader& r, GCNDataTag) {
|
|||
idx = MakeObj<SongGroupIndex>();
|
||||
|
||||
/* Normal pages */
|
||||
r.seek(header.pageTableOff, athena::Begin);
|
||||
r.seek(header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd64(r)) {
|
||||
SongGroupIndex::PageEntryDNA<athena::Big> entry;
|
||||
SongGroupIndex::PageEntryDNA<athena::Endian::Big> entry;
|
||||
entry.read(r);
|
||||
idx->m_normPages[entry.programNo] = entry;
|
||||
}
|
||||
|
||||
/* Drum pages */
|
||||
r.seek(header.drumTableOff, athena::Begin);
|
||||
r.seek(header.drumTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd64(r)) {
|
||||
SongGroupIndex::PageEntryDNA<athena::Big> entry;
|
||||
SongGroupIndex::PageEntryDNA<athena::Endian::Big> entry;
|
||||
entry.read(r);
|
||||
idx->m_drumPages[entry.programNo] = entry;
|
||||
}
|
||||
|
||||
/* MIDI setups */
|
||||
r.seek(header.midiSetupsOff, athena::Begin);
|
||||
r.seek(header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (r.position() < header.groupEndOff) {
|
||||
uint16_t songId = r.readUint16Big();
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
std::array<SongGroupIndex::MIDISetup, 16>& setup = idx->m_midiSetups[songId];
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
setup[i].read(r);
|
||||
if (SongId::CurNameDB)
|
||||
}
|
||||
if (SongId::CurNameDB) {
|
||||
SongId::CurNameDB->registerPair(NameDB::generateName(songId, NameDB::Type::Song), songId);
|
||||
}
|
||||
}
|
||||
} else if (header.type == GroupType::SFX) {
|
||||
auto& idx = m_sfxGroups[header.groupId];
|
||||
idx = MakeObj<SFXGroupIndex>();
|
||||
|
||||
/* SFX entries */
|
||||
r.seek(header.pageTableOff, athena::Begin);
|
||||
r.seek(header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
uint16_t count = r.readUint16Big();
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
idx->m_sfxEntries.reserve(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SFXGroupIndex::SFXEntryDNA<athena::Big> entry;
|
||||
SFXGroupIndex::SFXEntryDNA<athena::Endian::Big> entry;
|
||||
entry.read(r);
|
||||
idx->m_sfxEntries[entry.sfxId.id] = entry;
|
||||
if (SFXId::CurNameDB)
|
||||
|
@ -164,7 +171,7 @@ AudioGroupProject::AudioGroupProject(athena::io::IStreamReader& r, GCNDataTag) {
|
|||
}
|
||||
}
|
||||
|
||||
r.seek(header.groupEndOff, athena::Begin);
|
||||
r.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,30 +188,35 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
GroupId::CurNameDB->registerPair(NameDB::generateName(header.groupId, NameDB::Type::Group), header.groupId);
|
||||
|
||||
#if 0
|
||||
/* Sound Macros */
|
||||
r.seek(subDataOff + header.soundMacroIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<DNAE>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
/* Sound Macros */
|
||||
r.seek(subDataOff + header.soundMacroIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
}
|
||||
|
||||
/* Samples */
|
||||
r.seek(subDataOff + header.samplIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<DNAE>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
/* Samples */
|
||||
r.seek(subDataOff + header.samplIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
r.seek(subDataOff + header.tableIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<DNAE>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
/* Tables */
|
||||
r.seek(subDataOff + header.tableIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
}
|
||||
|
||||
/* Keymaps */
|
||||
r.seek(subDataOff + header.keymapIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<DNAE>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
/* Keymaps */
|
||||
r.seek(subDataOff + header.keymapIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
}
|
||||
|
||||
/* Layers */
|
||||
r.seek(subDataOff + header.layerIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<DNAE>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
/* Layers */
|
||||
r.seek(subDataOff + header.layerIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (header.type == GroupType::Song) {
|
||||
|
@ -213,7 +225,7 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
|
||||
if (absOffs) {
|
||||
/* Normal pages */
|
||||
r.seek(header.pageTableOff, athena::Begin);
|
||||
r.seek(header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
SongGroupIndex::PageEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
|
@ -221,7 +233,7 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
}
|
||||
|
||||
/* Drum pages */
|
||||
r.seek(header.drumTableOff, athena::Begin);
|
||||
r.seek(header.drumTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
SongGroupIndex::PageEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
|
@ -229,19 +241,20 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
}
|
||||
|
||||
/* MIDI setups */
|
||||
r.seek(header.midiSetupsOff, athena::Begin);
|
||||
r.seek(header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (r.position() < header.groupEndOff) {
|
||||
uint16_t songId;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(songId), DNAE>({}, songId, r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
std::array<SongGroupIndex::MIDISetup, 16>& setup = idx->m_midiSetups[songId];
|
||||
for (int i = 0; i < 16; ++i)
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
setup[i].read(r);
|
||||
}
|
||||
SongId::CurNameDB->registerPair(NameDB::generateName(songId, NameDB::Type::Song), songId);
|
||||
}
|
||||
} else {
|
||||
/* Normal pages */
|
||||
r.seek(subDataOff + header.pageTableOff, athena::Begin);
|
||||
r.seek(subDataOff + header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
SongGroupIndex::MusyX1PageEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
|
@ -249,7 +262,7 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
}
|
||||
|
||||
/* Drum pages */
|
||||
r.seek(subDataOff + header.drumTableOff, athena::Begin);
|
||||
r.seek(subDataOff + header.drumTableOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
SongGroupIndex::MusyX1PageEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
|
@ -257,11 +270,11 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
}
|
||||
|
||||
/* MIDI setups */
|
||||
r.seek(subDataOff + header.midiSetupsOff, athena::Begin);
|
||||
r.seek(subDataOff + header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (atInt64(r.position() + 4) < groupBegin + header.groupEndOff) {
|
||||
uint16_t songId;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(songId), DNAE>({}, songId, r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
std::array<SongGroupIndex::MIDISetup, 16>& setup = idx->m_midiSetups[songId];
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
SongGroupIndex::MusyX1MIDISetup ent;
|
||||
|
@ -276,24 +289,24 @@ AudioGroupProject AudioGroupProject::_AudioGroupProject(athena::io::IStreamReade
|
|||
idx = MakeObj<SFXGroupIndex>();
|
||||
|
||||
/* SFX entries */
|
||||
r.seek(subDataOff + header.pageTableOff, athena::Begin);
|
||||
r.seek(subDataOff + header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
uint16_t count;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(count), DNAE>({}, count, r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
idx->m_sfxEntries.reserve(count);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SFXGroupIndex::SFXEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
idx->m_sfxEntries[entry.sfxId.id] = entry;
|
||||
SFXId::CurNameDB->registerPair(NameDB::generateName(entry.sfxId.id, NameDB::Type::SFX), entry.sfxId.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (absOffs)
|
||||
r.seek(header.groupEndOff, athena::Begin);
|
||||
r.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
else
|
||||
r.seek(groupBegin + header.groupEndOff, athena::Begin);
|
||||
r.seek(groupBegin + header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -308,9 +321,9 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupDat
|
|||
default:
|
||||
return AudioGroupProject(r, GCNDataTag{});
|
||||
case DataFormat::N64:
|
||||
return _AudioGroupProject<athena::Big>(r, data.getAbsoluteProjOffsets());
|
||||
return _AudioGroupProject<athena::Endian::Big>(r, data.getAbsoluteProjOffsets());
|
||||
case DataFormat::PC:
|
||||
return _AudioGroupProject<athena::Little>(r, data.getAbsoluteProjOffsets());
|
||||
return _AudioGroupProject<athena::Endian::Little>(r, data.getAbsoluteProjOffsets());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,57 +459,61 @@ AudioGroupProject AudioGroupProject::CreateAudioGroupProject(const AudioGroupPro
|
|||
|
||||
void AudioGroupProject::BootstrapObjectIDs(athena::io::IStreamReader& r, GCNDataTag) {
|
||||
while (!AtEnd32(r)) {
|
||||
GroupHeader<athena::Big> header;
|
||||
GroupHeader<athena::Endian::Big> header;
|
||||
header.read(r);
|
||||
|
||||
GroupId::CurNameDB->registerPair(NameDB::generateName(header.groupId, NameDB::Type::Group), header.groupId);
|
||||
|
||||
/* Sound Macros */
|
||||
r.seek(header.soundMacroIdsOff, athena::Begin);
|
||||
r.seek(header.soundMacroIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
ReadRangedObjectIds<athena::Endian::Big>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
|
||||
/* Samples */
|
||||
r.seek(header.samplIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
r.seek(header.samplIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
r.seek(header.tableIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
r.seek(header.tableIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
}
|
||||
|
||||
/* Keymaps */
|
||||
r.seek(header.keymapIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
r.seek(header.keymapIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
}
|
||||
|
||||
/* Layers */
|
||||
r.seek(header.layerIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
ReadRangedObjectIds<athena::Big>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
r.seek(header.layerIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<athena::Endian::Big>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
}
|
||||
|
||||
if (header.type == GroupType::Song) {
|
||||
/* MIDI setups */
|
||||
r.seek(header.midiSetupsOff, athena::Begin);
|
||||
r.seek(header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (r.position() < header.groupEndOff) {
|
||||
uint16_t id = r.readUint16Big();
|
||||
SongId::CurNameDB->registerPair(NameDB::generateName(id, NameDB::Type::Song), id);
|
||||
r.seek(2 + 5 * 16, athena::Current);
|
||||
r.seek(2 + 5 * 16, athena::SeekOrigin::Current);
|
||||
}
|
||||
} else if (header.type == GroupType::SFX) {
|
||||
/* SFX entries */
|
||||
r.seek(header.pageTableOff, athena::Begin);
|
||||
r.seek(header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
uint16_t count = r.readUint16Big();
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SFXGroupIndex::SFXEntryDNA<athena::Big> entry;
|
||||
SFXGroupIndex::SFXEntryDNA<athena::Endian::Big> entry;
|
||||
entry.read(r);
|
||||
SFXId::CurNameDB->registerPair(NameDB::generateName(entry.sfxId.id, NameDB::Type::SFX), entry.sfxId.id);
|
||||
}
|
||||
}
|
||||
|
||||
r.seek(header.groupEndOff, athena::Begin);
|
||||
r.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -511,67 +528,73 @@ void AudioGroupProject::BootstrapObjectIDs(athena::io::IStreamReader& r, bool ab
|
|||
GroupId::CurNameDB->registerPair(NameDB::generateName(header.groupId, NameDB::Type::Group), header.groupId);
|
||||
|
||||
/* Sound Macros */
|
||||
r.seek(subDataOff + header.soundMacroIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
r.seek(subDataOff + header.soundMacroIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(SoundMacroId::CurNameDB, r, NameDB::Type::SoundMacro);
|
||||
}
|
||||
|
||||
/* Samples */
|
||||
r.seek(subDataOff + header.samplIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
r.seek(subDataOff + header.samplIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(SampleId::CurNameDB, r, NameDB::Type::Sample);
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
r.seek(subDataOff + header.tableIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
r.seek(subDataOff + header.tableIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(TableId::CurNameDB, r, NameDB::Type::Table);
|
||||
}
|
||||
|
||||
/* Keymaps */
|
||||
r.seek(subDataOff + header.keymapIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
r.seek(subDataOff + header.keymapIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(KeymapId::CurNameDB, r, NameDB::Type::Keymap);
|
||||
}
|
||||
|
||||
/* Layers */
|
||||
r.seek(subDataOff + header.layerIdsOff, athena::Begin);
|
||||
while (!AtEnd16(r))
|
||||
r.seek(subDataOff + header.layerIdsOff, athena::SeekOrigin::Begin);
|
||||
while (!AtEnd16(r)) {
|
||||
ReadRangedObjectIds<DNAE>(LayersId::CurNameDB, r, NameDB::Type::Layer);
|
||||
}
|
||||
|
||||
if (header.type == GroupType::Song) {
|
||||
/* MIDI setups */
|
||||
if (absOffs) {
|
||||
r.seek(header.midiSetupsOff, athena::Begin);
|
||||
r.seek(header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (r.position() < header.groupEndOff) {
|
||||
uint16_t id;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(id), DNAE>({}, id, r);
|
||||
SongId::CurNameDB->registerPair(NameDB::generateName(id, NameDB::Type::Song), id);
|
||||
r.seek(2 + 5 * 16, athena::Current);
|
||||
r.seek(2 + 5 * 16, athena::SeekOrigin::Current);
|
||||
}
|
||||
} else {
|
||||
r.seek(subDataOff + header.midiSetupsOff, athena::Begin);
|
||||
r.seek(subDataOff + header.midiSetupsOff, athena::SeekOrigin::Begin);
|
||||
while (atInt64(r.position()) < groupBegin + header.groupEndOff) {
|
||||
uint16_t id;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(id), DNAE>({}, id, r);
|
||||
SongId::CurNameDB->registerPair(NameDB::generateName(id, NameDB::Type::Song), id);
|
||||
r.seek(2 + 8 * 16, athena::Current);
|
||||
r.seek(2 + 8 * 16, athena::SeekOrigin::Current);
|
||||
}
|
||||
}
|
||||
} else if (header.type == GroupType::SFX) {
|
||||
/* SFX entries */
|
||||
r.seek(subDataOff + header.pageTableOff, athena::Begin);
|
||||
r.seek(subDataOff + header.pageTableOff, athena::SeekOrigin::Begin);
|
||||
uint16_t count;
|
||||
athena::io::Read<athena::io::PropType::None>::Do<decltype(count), DNAE>({}, count, r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
SFXGroupIndex::SFXEntryDNA<DNAE> entry;
|
||||
entry.read(r);
|
||||
r.seek(2, athena::Current);
|
||||
r.seek(2, athena::SeekOrigin::Current);
|
||||
SFXId::CurNameDB->registerPair(NameDB::generateName(entry.sfxId.id, NameDB::Type::SFX), entry.sfxId.id);
|
||||
}
|
||||
}
|
||||
|
||||
if (absOffs)
|
||||
r.seek(header.groupEndOff, athena::Begin);
|
||||
else
|
||||
r.seek(groupBegin + header.groupEndOff, athena::Begin);
|
||||
if (absOffs) {
|
||||
r.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
} else {
|
||||
r.seek(groupBegin + header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,10 +606,10 @@ void AudioGroupProject::BootstrapObjectIDs(const AudioGroupData& data) {
|
|||
BootstrapObjectIDs(r, GCNDataTag{});
|
||||
break;
|
||||
case DataFormat::N64:
|
||||
BootstrapObjectIDs<athena::Big>(r, data.getAbsoluteProjOffsets());
|
||||
BootstrapObjectIDs<athena::Endian::Big>(r, data.getAbsoluteProjOffsets());
|
||||
break;
|
||||
case DataFormat::PC:
|
||||
BootstrapObjectIDs<athena::Little>(r, data.getAbsoluteProjOffsets());
|
||||
BootstrapObjectIDs<athena::Endian::Little>(r, data.getAbsoluteProjOffsets());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -797,7 +820,7 @@ struct ObjectIdPool
|
|||
|
||||
std::vector<uint8_t> AudioGroupProject::toGCNData(const AudioGroupPool& pool,
|
||||
const AudioGroupSampleDirectory& sdir) const {
|
||||
constexpr athena::Endian DNAE = athena::Big;
|
||||
constexpr athena::Endian DNAE = athena::Endian::Big;
|
||||
|
||||
athena::io::VectorWriter fo;
|
||||
|
||||
|
@ -861,9 +884,9 @@ std::vector<uint8_t> AudioGroupProject::toGCNData(const AudioGroupPool& pool,
|
|||
}
|
||||
|
||||
header.groupEndOff = fo.position();
|
||||
fo.seek(groupStart, athena::Begin);
|
||||
fo.seek(groupStart, athena::SeekOrigin::Begin);
|
||||
header.write(fo);
|
||||
fo.seek(header.groupEndOff, athena::Begin);
|
||||
fo.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
} else {
|
||||
auto search2 = m_sfxGroups.find(id);
|
||||
if (search2 != m_sfxGroups.end()) {
|
||||
|
@ -897,9 +920,9 @@ std::vector<uint8_t> AudioGroupProject::toGCNData(const AudioGroupPool& pool,
|
|||
}
|
||||
|
||||
header.groupEndOff = fo.position();
|
||||
fo.seek(groupStart, athena::Begin);
|
||||
fo.seek(groupStart, athena::SeekOrigin::Begin);
|
||||
header.write(fo);
|
||||
fo.seek(header.groupEndOff, athena::Begin);
|
||||
fo.seek(header.groupEndOff, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace amuse {
|
|||
|
||||
static bool AtEnd32(athena::io::IStreamReader& r) {
|
||||
uint32_t v = r.readUint32Big();
|
||||
r.seek(-4, athena::Current);
|
||||
r.seek(-4, athena::SeekOrigin::Current);
|
||||
return v == 0xffffffff;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ void AudioGroupSampleDirectory::ADPCMParms::swapBigVADPCM() {
|
|||
|
||||
AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader& r, GCNDataTag) {
|
||||
while (!AtEnd32(r)) {
|
||||
EntryDNA<athena::Big> ent;
|
||||
EntryDNA<athena::Endian::Big> ent;
|
||||
ent.read(r);
|
||||
m_entries[ent.m_sfxId] = MakeObj<Entry>(ent);
|
||||
if (SampleId::CurNameDB)
|
||||
|
@ -55,7 +55,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader&
|
|||
|
||||
for (auto& p : m_entries) {
|
||||
if (p.second->m_data->m_adpcmParmOffset) {
|
||||
r.seek(p.second->m_data->m_adpcmParmOffset, athena::Begin);
|
||||
r.seek(p.second->m_data->m_adpcmParmOffset, athena::SeekOrigin::Begin);
|
||||
r.readUBytesToBuf(&p.second->m_data->m_ADPCMParms, sizeof(ADPCMParms::DSPParms));
|
||||
p.second->m_data->m_ADPCMParms.swapBigDSP();
|
||||
}
|
||||
|
@ -66,14 +66,14 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader&
|
|||
bool absOffs, N64DataTag) {
|
||||
if (absOffs) {
|
||||
while (!AtEnd32(r)) {
|
||||
MusyX1AbsSdirEntry<athena::Big> ent;
|
||||
MusyX1AbsSdirEntry<athena::Endian::Big> ent;
|
||||
ent.read(r);
|
||||
m_entries[ent.m_sfxId] = MakeObj<Entry>(ent);
|
||||
SampleId::CurNameDB->registerPair(NameDB::generateName(ent.m_sfxId, NameDB::Type::Sample), ent.m_sfxId);
|
||||
}
|
||||
} else {
|
||||
while (!AtEnd32(r)) {
|
||||
MusyX1SdirEntry<athena::Big> ent;
|
||||
MusyX1SdirEntry<athena::Endian::Big> ent;
|
||||
ent.read(r);
|
||||
m_entries[ent.m_sfxId] = MakeObj<Entry>(ent);
|
||||
SampleId::CurNameDB->registerPair(NameDB::generateName(ent.m_sfxId, NameDB::Type::Sample), ent.m_sfxId);
|
||||
|
@ -89,7 +89,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader&
|
|||
AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader& r, bool absOffs, PCDataTag) {
|
||||
if (absOffs) {
|
||||
while (!AtEnd32(r)) {
|
||||
MusyX1AbsSdirEntry<athena::Little> ent;
|
||||
MusyX1AbsSdirEntry<athena::Endian::Little> ent;
|
||||
ent.read(r);
|
||||
auto& store = m_entries[ent.m_sfxId];
|
||||
store = MakeObj<Entry>(ent);
|
||||
|
@ -98,7 +98,7 @@ AudioGroupSampleDirectory::AudioGroupSampleDirectory(athena::io::IStreamReader&
|
|||
}
|
||||
} else {
|
||||
while (!AtEnd32(r)) {
|
||||
MusyX1SdirEntry<athena::Little> ent;
|
||||
MusyX1SdirEntry<athena::Endian::Little> ent;
|
||||
ent.read(r);
|
||||
auto& store = m_entries[ent.m_sfxId];
|
||||
store = MakeObj<Entry>(ent);
|
||||
|
@ -237,7 +237,7 @@ void AudioGroupSampleDirectory::EntryData::loadLooseWAV(SystemStringView wavPath
|
|||
m_looseData.reset(new uint8_t[chunkSize]);
|
||||
r.readUBytesToBuf(m_looseData.get(), chunkSize);
|
||||
}
|
||||
r.seek(startPos + chunkSize, athena::Begin);
|
||||
r.seek(startPos + chunkSize, athena::SeekOrigin::Begin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(SystemStringView dsp
|
|||
|
||||
athena::io::FileWriter w(dspPath, false);
|
||||
if (!w.hasError()) {
|
||||
w.seek(0, athena::Begin);
|
||||
w.seek(0, athena::SeekOrigin::Begin);
|
||||
head.write(w);
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataDSP(SystemStringView dsp
|
|||
void AudioGroupSampleDirectory::EntryData::patchMetadataVADPCM(SystemStringView vadpcmPath) {
|
||||
athena::io::FileWriter w(vadpcmPath, false);
|
||||
if (!w.hasError()) {
|
||||
w.seek(0, athena::Begin);
|
||||
w.seek(0, athena::SeekOrigin::Begin);
|
||||
VADPCMHeader header;
|
||||
header.m_pitchSampleRate = m_pitch << 24;
|
||||
header.m_pitchSampleRate |= m_sampleRate & 0xffff;
|
||||
|
@ -434,12 +434,12 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
|
|||
loopOffset = startPos + 36;
|
||||
++readSec;
|
||||
}
|
||||
r.seek(startPos + chunkSize, athena::Begin);
|
||||
r.seek(startPos + chunkSize, athena::SeekOrigin::Begin);
|
||||
}
|
||||
|
||||
if (smplOffset == -1 || loopOffset == -1) {
|
||||
/* Complete rewrite of RIFF layout - new smpl chunk */
|
||||
r.seek(12, athena::Begin);
|
||||
r.seek(12, athena::SeekOrigin::Begin);
|
||||
athena::io::FileWriter w(wavPath);
|
||||
if (!w.hasError()) {
|
||||
w.writeUint32Little(SBIG('RIFF'));
|
||||
|
@ -470,7 +470,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
|
|||
loop.end = getLoopEndSample();
|
||||
loop.write(w);
|
||||
if (chunkMagic == SBIG('smpl')) {
|
||||
r.seek(chunkSize, athena::Current);
|
||||
r.seek(chunkSize, athena::SeekOrigin::Current);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
|
|||
}
|
||||
|
||||
atUint64 wavLen = w.position();
|
||||
w.seek(4, athena::Begin);
|
||||
w.seek(4, athena::SeekOrigin::Begin);
|
||||
w.writeUint32Little(wavLen - 8);
|
||||
}
|
||||
r.close();
|
||||
|
@ -489,7 +489,7 @@ void AudioGroupSampleDirectory::EntryData::patchMetadataWAV(SystemStringView wav
|
|||
r.close();
|
||||
athena::io::FileWriter w(wavPath, false);
|
||||
if (!w.hasError()) {
|
||||
w.seek(smplOffset, athena::Begin);
|
||||
w.seek(smplOffset, athena::SeekOrigin::Begin);
|
||||
WAVSampleChunk smpl;
|
||||
smpl.smplPeriod = 1000000000 / fmt.sampleRate;
|
||||
smpl.midiNote = m_pitch;
|
||||
|
@ -810,7 +810,7 @@ void AudioGroupSampleDirectory::_extractCompressed(SampleId id, const EntryData&
|
|||
samps += sampleCount;
|
||||
}
|
||||
|
||||
w.seek(0, athena::Begin);
|
||||
w.seek(0, athena::SeekOrigin::Begin);
|
||||
header.write(w);
|
||||
} else {
|
||||
return;
|
||||
|
@ -877,7 +877,7 @@ void AudioGroupSampleDirectory::reloadSampleData(SystemStringView groupPath) {
|
|||
|
||||
std::pair<std::vector<uint8_t>, std::vector<uint8_t>>
|
||||
AudioGroupSampleDirectory::toGCNData(const AudioGroupDatabase& group) const {
|
||||
constexpr athena::Endian DNAE = athena::Big;
|
||||
constexpr athena::Endian DNAE = athena::Endian::Big;
|
||||
|
||||
athena::io::VectorWriter fo;
|
||||
athena::io::VectorWriter sfo;
|
||||
|
|
|
@ -36,9 +36,9 @@ void BooBackendVoice::resetSampleRate(double sampleRate) { m_booVoice->resetSamp
|
|||
|
||||
void BooBackendVoice::resetChannelLevels() { m_booVoice->resetChannelLevels(); }
|
||||
|
||||
void BooBackendVoice::setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew) {
|
||||
BooBackendSubmix& smx = *reinterpret_cast<BooBackendSubmix*>(submix);
|
||||
m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs, slew);
|
||||
void BooBackendVoice::setChannelLevels(IBackendSubmix* submix, const std::array<float, 8>& coefs, bool slew) {
|
||||
auto& smx = *static_cast<BooBackendSubmix*>(submix);
|
||||
m_booVoice->setMonoChannelLevels(smx.m_booSubmix.get(), coefs.data(), slew);
|
||||
}
|
||||
|
||||
void BooBackendVoice::setPitchRatio(double ratio, bool slew) { m_booVoice->setPitchRatio(ratio, slew); }
|
||||
|
|
|
@ -49,52 +49,52 @@ bool Copy(const SystemChar* from, const SystemChar* to) {
|
|||
thread_local NameDB* type::CurNameDB = nullptr; \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader & reader) { \
|
||||
void type##DNA<athena::Endian::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { \
|
||||
id = reader.readUint16Little(); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter & writer) { \
|
||||
void type##DNA<athena::Endian::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) { \
|
||||
writer.writeUint16Little(id.id); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t & sz) { \
|
||||
void type##DNA<athena::Endian::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) { \
|
||||
sz += 2; \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader & reader) { \
|
||||
void type##DNA<athena::Endian::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) { \
|
||||
_read(reader); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter & writer) { \
|
||||
void type##DNA<athena::Endian::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) { \
|
||||
_write(writer); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader & reader) { \
|
||||
void type##DNA<athena::Endian::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) { \
|
||||
id = reader.readUint16Big(); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter & writer) { \
|
||||
void type##DNA<athena::Endian::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) { \
|
||||
writer.writeUint16Big(id.id); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t & sz) { \
|
||||
void type##DNA<athena::Endian::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) { \
|
||||
sz += 2; \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader & reader) { \
|
||||
void type##DNA<athena::Endian::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) { \
|
||||
_read(reader); \
|
||||
} \
|
||||
template <> \
|
||||
template <> \
|
||||
void type##DNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter & writer) { \
|
||||
void type##DNA<athena::Endian::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) { \
|
||||
_write(writer); \
|
||||
} \
|
||||
template <athena::Endian DNAE> \
|
||||
|
@ -122,8 +122,8 @@ bool Copy(const SystemChar* from, const SystemChar* to) {
|
|||
std::string_view type##DNA<DNAE>::DNAType() { \
|
||||
return "amuse::" #type "DNA"sv; \
|
||||
} \
|
||||
template struct type##DNA<athena::Big>; \
|
||||
template struct type##DNA<athena::Little>;
|
||||
template struct type##DNA<athena::Endian::Big>; \
|
||||
template struct type##DNA<athena::Endian::Little>;
|
||||
|
||||
DEFINE_ID_TYPE(ObjectId, "object")
|
||||
DEFINE_ID_TYPE(SoundMacroId, "SoundMacro")
|
||||
|
@ -137,52 +137,52 @@ DEFINE_ID_TYPE(GroupId, "group")
|
|||
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
void PageObjectIdDNA<athena::Endian::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
id = reader.readUint16Little();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
void PageObjectIdDNA<athena::Endian::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
writer.writeUint16Little(id.id);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
void PageObjectIdDNA<athena::Endian::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
sz += 2;
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
void PageObjectIdDNA<athena::Endian::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
_read(reader);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
void PageObjectIdDNA<athena::Endian::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
_write(writer);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
void PageObjectIdDNA<athena::Endian::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
id = reader.readUint16Big();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
void PageObjectIdDNA<athena::Endian::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
writer.writeUint16Big(id.id);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
void PageObjectIdDNA<athena::Endian::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
sz += 2;
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
void PageObjectIdDNA<athena::Endian::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
_read(reader);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void PageObjectIdDNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
void PageObjectIdDNA<athena::Endian::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
_write(writer);
|
||||
}
|
||||
template <athena::Endian DNAE>
|
||||
|
@ -232,65 +232,65 @@ template <athena::Endian DNAE>
|
|||
std::string_view PageObjectIdDNA<DNAE>::DNAType() {
|
||||
return "amuse::PageObjectIdDNA"sv;
|
||||
}
|
||||
template struct PageObjectIdDNA<athena::Big>;
|
||||
template struct PageObjectIdDNA<athena::Little>;
|
||||
template struct PageObjectIdDNA<athena::Endian::Big>;
|
||||
template struct PageObjectIdDNA<athena::Endian::Little>;
|
||||
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
void SoundMacroStepDNA<athena::Endian::Little>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
step = reader.readUint16Little();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
void SoundMacroStepDNA<athena::Endian::Little>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
writer.writeUint16Little(step);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
void SoundMacroStepDNA<athena::Endian::Little>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
sz += 2;
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
void SoundMacroStepDNA<athena::Endian::Little>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
step = reader.readUint16();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
void SoundMacroStepDNA<athena::Endian::Little>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
writer.writeUint16(step);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
void SoundMacroStepDNA<athena::Endian::Big>::Enumerate<BigDNA::Read>(athena::io::IStreamReader& reader) {
|
||||
step = reader.readUint16Big();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
void SoundMacroStepDNA<athena::Endian::Big>::Enumerate<BigDNA::Write>(athena::io::IStreamWriter& writer) {
|
||||
writer.writeUint16Big(step);
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
void SoundMacroStepDNA<athena::Endian::Big>::Enumerate<BigDNA::BinarySize>(size_t& sz) {
|
||||
sz += 2;
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
void SoundMacroStepDNA<athena::Endian::Big>::Enumerate<BigDNA::ReadYaml>(athena::io::YAMLDocReader& reader) {
|
||||
step = reader.readUint16();
|
||||
}
|
||||
template <>
|
||||
template <>
|
||||
void SoundMacroStepDNA<athena::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
void SoundMacroStepDNA<athena::Endian::Big>::Enumerate<BigDNA::WriteYaml>(athena::io::YAMLDocWriter& writer) {
|
||||
writer.writeUint16(step);
|
||||
}
|
||||
template <athena::Endian DNAE>
|
||||
std::string_view SoundMacroStepDNA<DNAE>::DNAType() {
|
||||
return "amuse::SoundMacroStepDNA"sv;
|
||||
}
|
||||
template struct SoundMacroStepDNA<athena::Big>;
|
||||
template struct SoundMacroStepDNA<athena::Little>;
|
||||
template struct SoundMacroStepDNA<athena::Endian::Big>;
|
||||
template struct SoundMacroStepDNA<athena::Endian::Little>;
|
||||
|
||||
ObjectId NameDB::generateId(Type tp) const {
|
||||
uint16_t maxMatch = 0;
|
||||
|
|
|
@ -143,9 +143,9 @@ static const float rsmpTab12khz[] =
|
|||
/* clang-format on */
|
||||
|
||||
EffectChorus::EffectChorus(uint32_t baseDelay, uint32_t variation, uint32_t period)
|
||||
: x90_baseDelay(std::clamp(5u, baseDelay, 15u))
|
||||
, x94_variation(std::clamp(0u, variation, 5u))
|
||||
, x98_period(std::clamp(500u, period, 10000u)) {}
|
||||
: x90_baseDelay(std::clamp(baseDelay, 5u, 15u))
|
||||
, x94_variation(std::clamp(variation, 0u, 5u))
|
||||
, x98_period(std::clamp(period, 500u, 10000u)) {}
|
||||
|
||||
template <typename T>
|
||||
EffectChorusImp<T>::EffectChorusImp(uint32_t baseDelay, uint32_t variation, uint32_t period, double sampleRate)
|
||||
|
|
|
@ -10,9 +10,9 @@ namespace amuse {
|
|||
|
||||
template <typename T>
|
||||
EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uint32_t initOutput, double sampleRate) {
|
||||
initDelay = std::clamp(10u, initDelay, 5000u);
|
||||
initFeedback = std::clamp(0u, initFeedback, 100u);
|
||||
initOutput = std::clamp(0u, initOutput, 100u);
|
||||
initDelay = std::clamp(initDelay, 10u, 5000u);
|
||||
initFeedback = std::clamp(initFeedback, 0u, 100u);
|
||||
initOutput = std::clamp(initOutput, 0u, 100u);
|
||||
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
x3c_delay[i] = initDelay;
|
||||
|
@ -26,9 +26,9 @@ EffectDelayImp<T>::EffectDelayImp(uint32_t initDelay, uint32_t initFeedback, uin
|
|||
template <typename T>
|
||||
EffectDelayImp<T>::EffectDelayImp(const EffectDelayInfo& info, double sampleRate) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
x3c_delay[i] = std::clamp(10u, info.delay[i], 5000u);
|
||||
x48_feedback[i] = std::clamp(0u, info.feedback[i], 100u);
|
||||
x54_output[i] = std::clamp(0u, info.output[i], 100u);
|
||||
x3c_delay[i] = std::clamp(info.delay[i], 10u, 5000u);
|
||||
x48_feedback[i] = std::clamp(info.feedback[i], 0u, 100u);
|
||||
x54_output[i] = std::clamp(info.output[i], 0u, 100u);
|
||||
}
|
||||
|
||||
_setup(sampleRate);
|
||||
|
|
|
@ -57,14 +57,14 @@ void ReverbDelayLine::setdelay(int32_t delay) {
|
|||
}
|
||||
|
||||
EffectReverbStd::EffectReverbStd(float coloration, float mix, float time, float damping, float preDelay)
|
||||
: x140_x1c8_coloration(std::clamp(0.f, coloration, 1.f))
|
||||
, x144_x1cc_mix(std::clamp(0.f, mix, 1.f))
|
||||
, x148_x1d0_time(std::clamp(0.01f, time, 10.f))
|
||||
, x14c_x1d4_damping(std::clamp(0.f, damping, 1.f))
|
||||
, x150_x1d8_preDelay(std::clamp(0.f, preDelay, 0.1f)) {}
|
||||
: x140_x1c8_coloration(std::clamp(coloration, 0.f, 1.f))
|
||||
, x144_x1cc_mix(std::clamp(mix, 0.f, 1.f))
|
||||
, x148_x1d0_time(std::clamp(time, 0.01f, 10.f))
|
||||
, x14c_x1d4_damping(std::clamp(damping, 0.f, 1.f))
|
||||
, x150_x1d8_preDelay(std::clamp(preDelay, 0.f, 0.1f)) {}
|
||||
|
||||
EffectReverbHi::EffectReverbHi(float coloration, float mix, float time, float damping, float preDelay, float crosstalk)
|
||||
: EffectReverbStd(coloration, mix, time, damping, preDelay), x1dc_crosstalk(std::clamp(0.f, crosstalk, 1.0f)) {}
|
||||
: EffectReverbStd(coloration, mix, time, damping, preDelay), x1dc_crosstalk(std::clamp(crosstalk, 0.f, 1.0f)) {}
|
||||
|
||||
template <typename T>
|
||||
EffectReverbStdImp<T>::EffectReverbStdImp(float coloration, float mix, float time, float damping, float preDelay,
|
||||
|
|
|
@ -5,22 +5,19 @@
|
|||
#include "amuse/Voice.hpp"
|
||||
|
||||
namespace amuse {
|
||||
|
||||
static void Delta(Vector3f& out, const Vector3f& a, const Vector3f& b) {
|
||||
out[0] = a[0] - b[0];
|
||||
out[1] = a[1] - b[1];
|
||||
out[2] = a[2] - b[2];
|
||||
static constexpr Vector3f Delta(const Vector3f& a, const Vector3f& b) {
|
||||
return {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
|
||||
}
|
||||
|
||||
Emitter::~Emitter() {}
|
||||
Emitter::~Emitter() = default;
|
||||
|
||||
Emitter::Emitter(Engine& engine, const AudioGroup& group, ObjToken<Voice> vox, float maxDist, float minVol,
|
||||
float falloff, bool doppler)
|
||||
: Entity(engine, group, vox->getGroupId(), vox->getObjectId())
|
||||
, m_vox(vox)
|
||||
, m_maxDist(maxDist)
|
||||
, m_minVol(std::clamp(0.f, minVol, 1.f))
|
||||
, m_falloff(std::clamp(-1.f, falloff, 1.f))
|
||||
, m_minVol(std::clamp(minVol, 0.f, 1.f))
|
||||
, m_falloff(std::clamp(falloff, -1.f, 1.f))
|
||||
, m_doppler(doppler) {}
|
||||
|
||||
void Emitter::_destroy() {
|
||||
|
@ -54,19 +51,18 @@ void Emitter::_update() {
|
|||
return;
|
||||
}
|
||||
|
||||
float coefs[8] = {};
|
||||
std::array<float, 8> coefs{};
|
||||
double avgDopplerRatio = 0.0;
|
||||
|
||||
for (auto& listener : m_engine.m_activeListeners) {
|
||||
Vector3f listenerToEmitter;
|
||||
Delta(listenerToEmitter, m_pos, listener->m_pos);
|
||||
float dist = Length(listenerToEmitter);
|
||||
float panDist = Dot(listenerToEmitter, listener->m_right);
|
||||
float frontPan = std::clamp(-1.f, panDist / listener->m_frontDiff, 1.f);
|
||||
float backPan = std::clamp(-1.f, panDist / listener->m_backDiff, 1.f);
|
||||
float spanDist = -Dot(listenerToEmitter, listener->m_heading);
|
||||
float span =
|
||||
std::clamp(-1.f, spanDist > 0.f ? spanDist / listener->m_backDiff : spanDist / listener->m_frontDiff, 1.f);
|
||||
const Vector3f listenerToEmitter = Delta(m_pos, listener->m_pos);
|
||||
const float dist = Length(listenerToEmitter);
|
||||
const float panDist = Dot(listenerToEmitter, listener->m_right);
|
||||
const float frontPan = std::clamp(panDist / listener->m_frontDiff, -1.f, 1.f);
|
||||
const float backPan = std::clamp(panDist / listener->m_backDiff, -1.f, 1.f);
|
||||
const float spanDist = -Dot(listenerToEmitter, listener->m_heading);
|
||||
const float span =
|
||||
std::clamp(spanDist > 0.f ? spanDist / listener->m_backDiff : spanDist / listener->m_frontDiff, -1.f, 1.f);
|
||||
|
||||
/* Calculate attenuation */
|
||||
float att = _attenuationCurve(dist);
|
||||
|
@ -74,27 +70,25 @@ void Emitter::_update() {
|
|||
att = m_attCache.getVolume(att, false);
|
||||
if (att > FLT_EPSILON) {
|
||||
/* Apply pan law */
|
||||
float thisCoefs[8] = {};
|
||||
m_vox->_panLaw(thisCoefs, frontPan, backPan, span);
|
||||
const std::array<float, 8> thisCoefs = m_vox->_panLaw(frontPan, backPan, span);
|
||||
|
||||
/* Take maximum coefficient across listeners */
|
||||
for (int i = 0; i < 8; ++i)
|
||||
for (size_t i = 0; i < coefs.size(); ++i) {
|
||||
coefs[i] = std::max(coefs[i], thisCoefs[i] * att * listener->m_volume);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate doppler */
|
||||
if (m_doppler) {
|
||||
/* Positive values indicate emitter and listener closing in */
|
||||
Vector3f dirDelta;
|
||||
Delta(dirDelta, m_dir, listener->m_dir);
|
||||
Vector3f posDelta;
|
||||
Delta(posDelta, listener->m_pos, m_pos);
|
||||
Normalize(posDelta);
|
||||
float deltaSpeed = Dot(dirDelta, posDelta);
|
||||
if (listener->m_soundSpeed != 0.f)
|
||||
const Vector3f dirDelta = Delta(m_dir, listener->m_dir);
|
||||
const Vector3f posDelta = Normalize(Delta(listener->m_pos, m_pos));
|
||||
const float deltaSpeed = Dot(dirDelta, posDelta);
|
||||
if (listener->m_soundSpeed != 0.f) {
|
||||
avgDopplerRatio += 1.0 + deltaSpeed / listener->m_soundSpeed;
|
||||
else
|
||||
} else {
|
||||
avgDopplerRatio += 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +104,7 @@ void Emitter::_update() {
|
|||
}
|
||||
|
||||
void Emitter::setVectors(const float* pos, const float* dir) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
for (size_t i = 0; i < m_pos.size(); ++i) {
|
||||
m_pos[i] = pos[i];
|
||||
m_dir[i] = dir[i];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "amuse/Engine.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "amuse/AudioGroup.hpp"
|
||||
#include "amuse/AudioGroupData.hpp"
|
||||
#include "amuse/Common.hpp"
|
||||
|
@ -11,7 +13,7 @@
|
|||
|
||||
namespace amuse {
|
||||
|
||||
static const float FullLevels[8] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
|
||||
constexpr std::array<float, 8> FullLevels{1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
|
||||
|
||||
Engine::~Engine() {
|
||||
m_backend.setCallbackInterface(nullptr);
|
||||
|
@ -251,7 +253,7 @@ ObjToken<Voice> Engine::fxStart(SFXId sfxId, float vol, float pan, ObjToken<Stud
|
|||
|
||||
(*ret)->setVolume(vol);
|
||||
float evalPan = pan != 0.f ? pan : ((entry->panning - 64.f) / 63.f);
|
||||
evalPan = std::clamp(-1.f, evalPan, 1.f);
|
||||
evalPan = std::clamp(evalPan, -1.f, 1.f);
|
||||
(*ret)->setPan(evalPan);
|
||||
return *ret;
|
||||
}
|
||||
|
@ -273,7 +275,7 @@ ObjToken<Voice> Engine::fxStart(const AudioGroup* group, GroupId groupId, SFXId
|
|||
|
||||
(*ret)->setVolume(vol);
|
||||
float evalPan = pan != 0.f ? pan : ((entry.panning - 64.f) / 63.f);
|
||||
evalPan = std::clamp(-1.f, evalPan, 1.f);
|
||||
evalPan = std::clamp(evalPan, -1.f, 1.f);
|
||||
(*ret)->setPan(evalPan);
|
||||
return *ret;
|
||||
}
|
||||
|
|
|
@ -42,8 +42,9 @@ void Envelope::reset(const ADSRDLS* adsr, int8_t note, int8_t vel) {
|
|||
|
||||
void Envelope::keyOff(const Voice& vox) {
|
||||
double releaseTime = m_releaseTime;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
releaseTime = MIDItoTIME[std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiRelease)), 103)] / 1000.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
releaseTime = MIDItoTIME[std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiRelease)), 0, 103)] / 1000.0;
|
||||
}
|
||||
|
||||
m_phase = (releaseTime != 0.0) ? State::Release : State::Complete;
|
||||
m_curTime = 0.0;
|
||||
|
@ -64,8 +65,9 @@ float Envelope::advance(double dt, const Voice& vox) {
|
|||
switch (m_phase) {
|
||||
case State::Attack: {
|
||||
double attackTime = m_attackTime;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
attackTime = MIDItoTIME[std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiAttack)), 103)] / 1000.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
attackTime = MIDItoTIME[std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiAttack)), 0, 103)] / 1000.0;
|
||||
}
|
||||
|
||||
if (attackTime == 0.0) {
|
||||
m_phase = State::Decay;
|
||||
|
@ -85,12 +87,14 @@ float Envelope::advance(double dt, const Voice& vox) {
|
|||
}
|
||||
case State::Decay: {
|
||||
double decayTime = m_decayTime;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
decayTime = MIDItoTIME[std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiDecay)), 103)] / 1000.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
decayTime = MIDItoTIME[std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiDecay)), 0, 103)] / 1000.0;
|
||||
}
|
||||
|
||||
double sustainFactor = m_sustainFactor;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
sustainFactor = std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiSustain)), 127) / 127.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
sustainFactor = std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiSustain)), 0, 127) / 127.0;
|
||||
}
|
||||
|
||||
if (decayTime == 0.0) {
|
||||
m_phase = State::Sustain;
|
||||
|
@ -110,15 +114,17 @@ float Envelope::advance(double dt, const Voice& vox) {
|
|||
}
|
||||
case State::Sustain: {
|
||||
double sustainFactor = m_sustainFactor;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
sustainFactor = std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiSustain)), 127) / 127.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
sustainFactor = std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiSustain)), 0, 127) / 127.0;
|
||||
}
|
||||
|
||||
return sustainFactor;
|
||||
}
|
||||
case State::Release: {
|
||||
double releaseTime = m_releaseTime;
|
||||
if (vox.m_state.m_useAdsrControllers)
|
||||
releaseTime = MIDItoTIME[std::clamp(0, int(vox.getCtrlValue(vox.m_state.m_midiRelease)), 103)] / 1000.0;
|
||||
if (vox.m_state.m_useAdsrControllers) {
|
||||
releaseTime = MIDItoTIME[std::clamp(int(vox.getCtrlValue(vox.m_state.m_midiRelease)), 0, 103)] / 1000.0;
|
||||
}
|
||||
|
||||
if (releaseTime == 0.0) {
|
||||
m_phase = State::Complete;
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
namespace amuse {
|
||||
|
||||
static void Cross(Vector3f& out, const Vector3f& a, const Vector3f& b) {
|
||||
out[0] = a[1] * b[2] - a[2] * b[1];
|
||||
out[1] = a[2] * b[0] - a[0] * b[2];
|
||||
out[2] = a[0] * b[1] - a[1] * b[0];
|
||||
static constexpr Vector3f Cross(const Vector3f& a, const Vector3f& b) {
|
||||
return {
|
||||
a[1] * b[2] - a[2] * b[1],
|
||||
a[2] * b[0] - a[0] * b[2],
|
||||
a[0] * b[1] - a[1] * b[0],
|
||||
};
|
||||
}
|
||||
|
||||
void Listener::setVectors(const float* pos, const float* dir, const float* heading, const float* up) {
|
||||
|
@ -16,11 +18,9 @@ void Listener::setVectors(const float* pos, const float* dir, const float* headi
|
|||
m_up[i] = up[i];
|
||||
}
|
||||
|
||||
Normalize(m_heading);
|
||||
Normalize(m_up);
|
||||
Cross(m_right, m_heading, m_up);
|
||||
Normalize(m_right);
|
||||
|
||||
m_heading = Normalize(m_heading);
|
||||
m_up = Normalize(m_up);
|
||||
m_right = Normalize(Cross(m_heading, m_up));
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ Sequencer::~Sequencer() {
|
|||
|
||||
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SongGroupIndex* songGroup,
|
||||
SongId setupId, ObjToken<Studio> studio)
|
||||
: Entity(engine, group, groupId), m_songGroup(songGroup), m_studio(studio) {
|
||||
: Entity(engine, group, groupId), m_songGroup(songGroup), m_studio(std::move(studio)) {
|
||||
auto it = m_songGroup->m_midiSetups.find(setupId);
|
||||
if (it != m_songGroup->m_midiSetups.cend())
|
||||
m_midiSetup = it->second.data();
|
||||
|
@ -61,7 +61,7 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, c
|
|||
|
||||
Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, const SFXGroupIndex* sfxGroup,
|
||||
ObjToken<Studio> studio)
|
||||
: Entity(engine, group, groupId), m_sfxGroup(sfxGroup), m_studio(studio) {
|
||||
: Entity(engine, group, groupId), m_sfxGroup(sfxGroup), m_studio(std::move(studio)) {
|
||||
std::map<ObjectId, const SFXGroupIndex::SFXEntry*> sortSFX;
|
||||
for (const auto& sfx : sfxGroup->m_sfxEntries)
|
||||
sortSFX[sfx.first] = &sfx.second;
|
||||
|
@ -71,7 +71,7 @@ Sequencer::Sequencer(Engine& engine, const AudioGroup& group, GroupId groupId, c
|
|||
m_sfxMappings.push_back(sfx.second);
|
||||
}
|
||||
|
||||
Sequencer::ChannelState::~ChannelState() {}
|
||||
Sequencer::ChannelState::~ChannelState() = default;
|
||||
|
||||
Sequencer::ChannelState::ChannelState(Sequencer& parent, uint8_t chanId) : m_parent(&parent), m_chanId(chanId) {
|
||||
if (m_parent->m_songGroup) {
|
||||
|
@ -208,7 +208,7 @@ ObjToken<Voice> Sequencer::ChannelState::keyOn(uint8_t note, uint8_t velocity) {
|
|||
if (*ret) {
|
||||
(*ret)->m_sequencer = m_parent;
|
||||
m_chanVoxs[note] = *ret;
|
||||
(*ret)->installCtrlValues(m_ctrlVals);
|
||||
(*ret)->installCtrlValues(m_ctrlVals.data());
|
||||
|
||||
ObjectId oid;
|
||||
bool res;
|
||||
|
@ -246,11 +246,13 @@ ObjToken<Voice> Sequencer::ChannelState::keyOn(uint8_t note, uint8_t velocity) {
|
|||
}
|
||||
|
||||
ObjToken<Voice> Sequencer::keyOn(uint8_t chan, uint8_t note, uint8_t velocity) {
|
||||
if (chan > 15)
|
||||
if (chan >= m_chanStates.size()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!m_chanStates[chan])
|
||||
if (!m_chanStates[chan]) {
|
||||
m_chanStates[chan] = ChannelState(*this, chan);
|
||||
}
|
||||
|
||||
return m_chanStates[chan].keyOn(note, velocity);
|
||||
}
|
||||
|
@ -268,8 +270,9 @@ void Sequencer::ChannelState::keyOff(uint8_t note, uint8_t velocity) {
|
|||
}
|
||||
|
||||
void Sequencer::keyOff(uint8_t chan, uint8_t note, uint8_t velocity) {
|
||||
if (chan > 15 || !m_chanStates[chan])
|
||||
if (chan >= m_chanStates.size() || !m_chanStates[chan]) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_chanStates[chan].keyOff(note, velocity);
|
||||
}
|
||||
|
@ -351,8 +354,9 @@ void Sequencer::ChannelState::prevProgram() {
|
|||
}
|
||||
|
||||
void Sequencer::setCtrlValue(uint8_t chan, uint8_t ctrl, int8_t val) {
|
||||
if (chan > 15)
|
||||
if (chan >= m_chanStates.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctrl == 0x66) {
|
||||
fmt::print(fmt("Loop Start\n"));
|
||||
|
@ -360,8 +364,9 @@ void Sequencer::setCtrlValue(uint8_t chan, uint8_t ctrl, int8_t val) {
|
|||
fmt::print(fmt("Loop End\n"));
|
||||
}
|
||||
|
||||
if (!m_chanStates[chan])
|
||||
if (!m_chanStates[chan]) {
|
||||
m_chanStates[chan] = ChannelState(*this, chan);
|
||||
}
|
||||
|
||||
m_chanStates[chan].setCtrlValue(ctrl, val);
|
||||
}
|
||||
|
@ -375,11 +380,13 @@ void Sequencer::ChannelState::setPitchWheel(float pitchWheel) {
|
|||
}
|
||||
|
||||
void Sequencer::setPitchWheel(uint8_t chan, float pitchWheel) {
|
||||
if (chan > 15)
|
||||
if (chan >= m_chanStates.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_chanStates[chan])
|
||||
if (!m_chanStates[chan]) {
|
||||
m_chanStates[chan] = ChannelState(*this, chan);
|
||||
}
|
||||
|
||||
m_chanStates[chan].setPitchWheel(pitchWheel);
|
||||
}
|
||||
|
@ -422,18 +429,22 @@ void Sequencer::allOff(bool now) {
|
|||
}
|
||||
|
||||
void Sequencer::allOff(uint8_t chan, bool now) {
|
||||
if (chan > 15 || !m_chanStates[chan])
|
||||
if (chan >= m_chanStates.size() || !m_chanStates[chan]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (now) {
|
||||
for (const auto& vox : m_chanStates[chan].m_chanVoxs)
|
||||
for (const auto& vox : m_chanStates[chan].m_chanVoxs) {
|
||||
vox.second->kill();
|
||||
for (const auto& vox : m_chanStates[chan].m_keyoffVoxs)
|
||||
}
|
||||
for (const auto& vox : m_chanStates[chan].m_keyoffVoxs) {
|
||||
vox->kill();
|
||||
}
|
||||
m_chanStates[chan].m_chanVoxs.clear();
|
||||
m_chanStates[chan].m_keyoffVoxs.clear();
|
||||
} else
|
||||
} else {
|
||||
m_chanStates[chan].allOff();
|
||||
}
|
||||
}
|
||||
|
||||
void Sequencer::ChannelState::killKeygroup(uint8_t kg, bool now) {
|
||||
|
@ -575,12 +586,14 @@ void Sequencer::setVolume(float vol, float fadeTime) {
|
|||
}
|
||||
|
||||
int8_t Sequencer::getChanProgram(int8_t chanId) const {
|
||||
if (chanId > 15)
|
||||
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_chanStates[chanId]) {
|
||||
if (!m_midiSetup)
|
||||
if (!m_midiSetup) {
|
||||
return 0;
|
||||
}
|
||||
return m_midiSetup[chanId].programNo;
|
||||
}
|
||||
|
||||
|
@ -588,31 +601,37 @@ int8_t Sequencer::getChanProgram(int8_t chanId) const {
|
|||
}
|
||||
|
||||
bool Sequencer::setChanProgram(int8_t chanId, int8_t prog) {
|
||||
if (chanId > 15)
|
||||
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_chanStates[chanId])
|
||||
if (!m_chanStates[chanId]) {
|
||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||
}
|
||||
|
||||
return m_chanStates[chanId].programChange(prog);
|
||||
}
|
||||
|
||||
void Sequencer::nextChanProgram(int8_t chanId) {
|
||||
if (chanId > 15)
|
||||
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_chanStates[chanId])
|
||||
if (!m_chanStates[chanId]) {
|
||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||
}
|
||||
|
||||
return m_chanStates[chanId].nextProgram();
|
||||
}
|
||||
|
||||
void Sequencer::prevChanProgram(int8_t chanId) {
|
||||
if (chanId > 15)
|
||||
if (static_cast<size_t>(chanId) >= m_chanStates.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_chanStates[chanId])
|
||||
if (!m_chanStates[chanId]) {
|
||||
m_chanStates[chanId] = ChannelState(*this, chanId);
|
||||
}
|
||||
|
||||
return m_chanStates[chanId].prevProgram();
|
||||
}
|
||||
|
|
|
@ -683,7 +683,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, int& v
|
|||
/* Update pitch */
|
||||
trk.m_pitchVal += trk.m_nextPitchDelta;
|
||||
events.emplace(regStart + trk.m_nextPitchTick,
|
||||
Event{PitchEvent{}, trk.m_midiChan, std::clamp(0, trk.m_pitchVal + 0x2000, 0x4000)});
|
||||
Event{PitchEvent{}, trk.m_midiChan, std::clamp(trk.m_pitchVal + 0x2000, 0, 0x4000)});
|
||||
if (trk.m_pitchWheelData[0] != 0x80 || trk.m_pitchWheelData[1] != 0x00) {
|
||||
auto delta = DecodeDelta(trk.m_pitchWheelData);
|
||||
trk.m_nextPitchTick += delta.first;
|
||||
|
@ -700,7 +700,7 @@ std::vector<uint8_t> SongConverter::SongToMIDI(const unsigned char* data, int& v
|
|||
/* Update modulation */
|
||||
trk.m_modVal += trk.m_nextModDelta;
|
||||
events.emplace(regStart + trk.m_nextModTick,
|
||||
Event{CtrlEvent{}, trk.m_midiChan, 1, uint8_t(std::clamp(0, trk.m_modVal / 128, 127)), 0});
|
||||
Event{CtrlEvent{}, trk.m_midiChan, 1, uint8_t(std::clamp(trk.m_modVal / 128, 0, 127)), 0});
|
||||
if (trk.m_modWheelData[0] != 0x80 || trk.m_modWheelData[1] != 0x00) {
|
||||
auto delta = DecodeDelta(trk.m_modWheelData);
|
||||
trk.m_nextModTick += delta.first;
|
||||
|
|
|
@ -443,7 +443,7 @@ bool SongState::Track::advance(Sequencer& seq, double dt) {
|
|||
if (pitchTick + remPitchTicks > nextTick) {
|
||||
/* Update pitch */
|
||||
m_pitchVal += m_nextPitchDelta;
|
||||
seq.setPitchWheel(m_midiChan, std::clamp(-1.f, m_pitchVal / 8191.f, 1.f));
|
||||
seq.setPitchWheel(m_midiChan, std::clamp(m_pitchVal / 8191.f, -1.f, 1.f));
|
||||
if (m_pitchWheelData[0] != 0x80 || m_pitchWheelData[1] != 0x00) {
|
||||
auto delta = DecodeDelta(m_pitchWheelData);
|
||||
m_nextPitchTick += delta.first;
|
||||
|
@ -467,7 +467,7 @@ bool SongState::Track::advance(Sequencer& seq, double dt) {
|
|||
if (modTick + remModTicks > nextTick) {
|
||||
/* Update modulation */
|
||||
m_modVal += m_nextModDelta;
|
||||
seq.setCtrlValue(m_midiChan, 1, int8_t(std::clamp(0, m_modVal / 127, 127)));
|
||||
seq.setCtrlValue(m_midiChan, 1, int8_t(std::clamp(m_modVal / 127, 0, 127)));
|
||||
if (m_modWheelData[0] != 0x80 || m_modWheelData[1] != 0x00) {
|
||||
auto delta = DecodeDelta(m_modWheelData);
|
||||
m_nextModTick += delta.first;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,16 @@
|
|||
#include "amuse/Studio.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "amuse/Engine.hpp"
|
||||
|
||||
namespace amuse {
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool Studio::_cyclicCheck(Studio* leaf) {
|
||||
for (auto it = m_studiosOut.begin(); it != m_studiosOut.end();) {
|
||||
if (leaf == it->m_targetStudio.get() || it->m_targetStudio->_cyclicCheck(leaf))
|
||||
return true;
|
||||
++it;
|
||||
}
|
||||
return false;
|
||||
bool Studio::_cyclicCheck(const Studio* leaf) const {
|
||||
return std::any_of(m_studiosOut.cbegin(), m_studiosOut.cend(), [leaf](const auto& studio) {
|
||||
return leaf == studio.m_targetStudio.get() || studio.m_targetStudio->_cyclicCheck(leaf);
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -20,7 +20,7 @@ Studio::Studio(Engine& engine, bool mainOut) : m_engine(engine), m_master(engine
|
|||
}
|
||||
|
||||
void Studio::addStudioSend(ObjToken<Studio> studio, float dry, float auxA, float auxB) {
|
||||
m_studiosOut.emplace_back(studio, dry, auxA, auxB);
|
||||
m_studiosOut.emplace_back(std::move(studio), dry, auxA, auxB);
|
||||
|
||||
/* Cyclic check */
|
||||
assert(!_cyclicCheck(this));
|
||||
|
|
121
lib/Voice.cpp
121
lib/Voice.cpp
|
@ -114,8 +114,8 @@ void Voice::_doKeyOff() {
|
|||
|
||||
void Voice::_setTotalPitch(int32_t cents, bool slew) {
|
||||
// fprintf(stderr, "PITCH %d %d \n", cents, slew);
|
||||
int32_t interval = std::clamp(0, cents, 12700) - m_curSample->getPitch() * 100;
|
||||
double ratio = std::exp2(interval / 1200.0) * m_dopplerRatio;
|
||||
const int32_t interval = std::clamp(cents, 0, 12700) - m_curSample->getPitch() * 100;
|
||||
const double ratio = std::exp2(interval / 1200.0) * m_dopplerRatio;
|
||||
m_sampleRate = m_curSample->m_sampleRate * ratio;
|
||||
m_backendVoice->setPitchRatio(ratio, slew);
|
||||
}
|
||||
|
@ -155,10 +155,11 @@ ObjToken<Voice> Voice::_findVoice(int vid, ObjToken<Voice> thisPtr) {
|
|||
}
|
||||
|
||||
std::unique_ptr<int8_t[]>& Voice::_ensureCtrlVals() {
|
||||
if (m_ctrlValsSelf)
|
||||
if (m_ctrlValsSelf) {
|
||||
return m_ctrlValsSelf;
|
||||
m_ctrlValsSelf.reset(new int8_t[128]);
|
||||
memset(m_ctrlValsSelf.get(), 0, 128);
|
||||
}
|
||||
|
||||
m_ctrlValsSelf = std::make_unique<int8_t[]>(128);
|
||||
return m_ctrlValsSelf;
|
||||
}
|
||||
|
||||
|
@ -200,8 +201,8 @@ void Voice::_procSamplePre(int16_t& samp) {
|
|||
dt = m_sampleRate * 160;
|
||||
if (rem != 0) {
|
||||
/* Lerp within 160-sample block */
|
||||
float t = rem / 160.f;
|
||||
float l = std::clamp(0.f, m_lastLevel * (1.f - t) + m_nextLevel * t, 1.f);
|
||||
const float t = rem / 160.f;
|
||||
const float l = std::clamp(m_lastLevel * (1.f - t) + m_nextLevel * t, 0.f, 1.f);
|
||||
|
||||
/* Apply total volume to sample using decibel scale */
|
||||
samp = ApplyVolume(m_lerpedCache.getVolume(l * m_engine.m_masterVolume, m_dlsVol), samp);
|
||||
|
@ -218,12 +219,13 @@ void Voice::_procSamplePre(int16_t& samp) {
|
|||
/* Process active envelope */
|
||||
if (m_envelopeTime >= 0.0) {
|
||||
m_envelopeTime += dt;
|
||||
float start = m_envelopeStart;
|
||||
float end = m_envelopeEnd;
|
||||
float t = std::clamp(0.f, float(m_envelopeTime / m_envelopeDur), 1.f);
|
||||
if (m_envelopeCurve && m_envelopeCurve->data.size() >= 128)
|
||||
const float start = m_envelopeStart;
|
||||
const float end = m_envelopeEnd;
|
||||
float t = std::clamp(float(m_envelopeTime / m_envelopeDur), 0.f, 1.f);
|
||||
if (m_envelopeCurve && m_envelopeCurve->data.size() >= 128) {
|
||||
t = m_envelopeCurve->data[t * 127.f] / 127.f;
|
||||
m_envelopeVol = std::clamp(0.f, (start * (1.0f - t)) + (end * t), 1.f);
|
||||
}
|
||||
m_envelopeVol = std::clamp((start * (1.0f - t)) + (end * t), 0.f, 1.f);
|
||||
|
||||
// printf("%d %f\n", m_vid, m_envelopeVol);
|
||||
|
||||
|
@ -280,7 +282,7 @@ void Voice::_procSamplePre(int16_t& samp) {
|
|||
}
|
||||
}
|
||||
|
||||
m_nextLevel = std::clamp(0.f, m_nextLevel, 1.f);
|
||||
m_nextLevel = std::clamp(m_nextLevel, 0.f, 1.f);
|
||||
|
||||
/* Apply total volume to sample using decibel scale */
|
||||
samp = ApplyVolume(m_nextLevelCache.getVolume(m_nextLevel * m_engine.m_masterVolume, m_dlsVol), samp);
|
||||
|
@ -288,8 +290,8 @@ void Voice::_procSamplePre(int16_t& samp) {
|
|||
|
||||
template <typename T>
|
||||
T Voice::_procSampleMaster(double time, T samp) {
|
||||
float evalVol = m_state.m_volumeSel ? (m_state.m_volumeSel.evaluate(time, *this, m_state) / 127.f) : 1.f;
|
||||
return ApplyVolume(m_masterCache.getVolume(std::clamp(0.f, evalVol, 1.f), m_dlsVol), samp);
|
||||
const float evalVol = m_state.m_volumeSel ? (m_state.m_volumeSel.evaluate(time, *this, m_state) / 127.f) : 1.f;
|
||||
return ApplyVolume(m_masterCache.getVolume(std::clamp(evalVol, 0.f, 1.f), m_dlsVol), samp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -297,7 +299,7 @@ T Voice::_procSampleAuxA(double time, T samp) {
|
|||
float evalVol = m_state.m_volumeSel ? (m_state.m_volumeSel.evaluate(time, *this, m_state) / 127.f) : 1.f;
|
||||
evalVol *= m_state.m_reverbSel ? (m_state.m_reverbSel.evaluate(time, *this, m_state) / 127.f) : m_curReverbVol;
|
||||
evalVol += m_state.m_preAuxASel ? (m_state.m_preAuxASel.evaluate(time, *this, m_state) / 127.f) : 0.f;
|
||||
return ApplyVolume(m_auxACache.getVolume(std::clamp(0.f, evalVol, 1.f), m_dlsVol), samp);
|
||||
return ApplyVolume(m_auxACache.getVolume(std::clamp(evalVol, 0.f, 1.f), m_dlsVol), samp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -305,7 +307,7 @@ T Voice::_procSampleAuxB(double time, T samp) {
|
|||
float evalVol = m_state.m_volumeSel ? (m_state.m_volumeSel.evaluate(time, *this, m_state) / 127.f) : 1.f;
|
||||
evalVol *= m_state.m_postAuxB ? (m_state.m_postAuxB.evaluate(time, *this, m_state) / 127.f) : m_curAuxBVol;
|
||||
evalVol += m_state.m_preAuxBSel ? (m_state.m_preAuxBSel.evaluate(time, *this, m_state) / 127.f) : 0.f;
|
||||
return ApplyVolume(m_auxBCache.getVolume(std::clamp(0.f, evalVol, 1.f), m_dlsVol), samp);
|
||||
return ApplyVolume(m_auxBCache.getVolume(std::clamp(evalVol, 0.f, 1.f), m_dlsVol), samp);
|
||||
}
|
||||
|
||||
uint32_t Voice::_GetBlockSampleCount(SampleFormat fmt) {
|
||||
|
@ -343,7 +345,7 @@ void Voice::preSupplyAudio(double dt) {
|
|||
bool panDirty = false;
|
||||
if (m_state.m_panSel) {
|
||||
float evalPan = (m_state.m_panSel.evaluate(m_voiceTime, *this, m_state) - 64.f) / 63.f;
|
||||
evalPan = std::clamp(-1.f, evalPan, 1.f);
|
||||
evalPan = std::clamp(evalPan, -1.f, 1.f);
|
||||
if (evalPan != m_curPan) {
|
||||
m_curPan = evalPan;
|
||||
panDirty = true;
|
||||
|
@ -351,7 +353,7 @@ void Voice::preSupplyAudio(double dt) {
|
|||
}
|
||||
if (m_state.m_spanSel) {
|
||||
float evalSpan = (m_state.m_spanSel.evaluate(m_voiceTime, *this, m_state) - 64.f) / 63.f;
|
||||
evalSpan = std::clamp(-1.f, evalSpan, 1.f);
|
||||
evalSpan = std::clamp(evalSpan, -1.f, 1.f);
|
||||
if (evalSpan != m_curSpan) {
|
||||
m_curSpan = evalSpan;
|
||||
panDirty = true;
|
||||
|
@ -361,8 +363,8 @@ void Voice::preSupplyAudio(double dt) {
|
|||
_setPan(m_curPan);
|
||||
|
||||
if (m_state.m_pitchWheelSel) {
|
||||
float evalPWheel = (m_state.m_pitchWheelSel.evaluate(m_voiceTime, *this, m_state) - 64.f) / 63.f;
|
||||
_setPitchWheel(std::clamp(-1.f, evalPWheel, 1.f));
|
||||
const float evalPWheel = (m_state.m_pitchWheelSel.evaluate(m_voiceTime, *this, m_state) - 64.f) / 63.f;
|
||||
_setPitchWheel(std::clamp(evalPWheel, -1.f, 1.f));
|
||||
}
|
||||
|
||||
/* Process active pan-sweep */
|
||||
|
@ -370,9 +372,9 @@ void Voice::preSupplyAudio(double dt) {
|
|||
if (!m_panningQueue.empty()) {
|
||||
Panning& p = m_panningQueue.front();
|
||||
p.m_time += dt;
|
||||
double start = (p.m_pos - 64) / 64.0;
|
||||
double end = (p.m_pos + p.m_width - 64) / 64.0;
|
||||
double t = std::clamp(0.0, p.m_time / p.m_dur, 1.0);
|
||||
const double start = (p.m_pos - 64) / 64.0;
|
||||
const double end = (p.m_pos + p.m_width - 64) / 64.0;
|
||||
const double t = std::clamp(p.m_time / p.m_dur, 0.0, 1.0);
|
||||
_setPan(float((start * (1.0 - t)) + (end * t)));
|
||||
refresh = true;
|
||||
|
||||
|
@ -385,9 +387,9 @@ void Voice::preSupplyAudio(double dt) {
|
|||
if (!m_spanningQueue.empty()) {
|
||||
Panning& s = m_spanningQueue.front();
|
||||
s.m_time += dt;
|
||||
double start = (s.m_pos - 64) / 64.0;
|
||||
double end = (s.m_pos + s.m_width - 64) / 64.0;
|
||||
double t = std::clamp(0.0, s.m_time / s.m_dur, 1.0);
|
||||
const double start = (s.m_pos - 64) / 64.0;
|
||||
const double end = (s.m_pos + s.m_width - 64) / 64.0;
|
||||
const double t = std::clamp(s.m_time / s.m_dur, 0.0, 1.0);
|
||||
_setSurroundPan(float((start * (1.0 - t)) + (end * t)));
|
||||
refresh = true;
|
||||
|
||||
|
@ -402,7 +404,7 @@ void Voice::preSupplyAudio(double dt) {
|
|||
m_pitchDirty = false;
|
||||
if (m_portamentoTime >= 0.f) {
|
||||
m_portamentoTime += dt;
|
||||
float t = std::clamp(0.f, m_portamentoTime / m_state.m_portamentoTime, 1.f);
|
||||
const float t = std::clamp(m_portamentoTime / m_state.m_portamentoTime, 0.f, 1.f);
|
||||
|
||||
newPitch = (m_curPitch * (1.0f - t)) + (m_portamentoTarget * t);
|
||||
refresh = true;
|
||||
|
@ -849,14 +851,15 @@ void Voice::startSample(SampleId sampId, int32_t offset) {
|
|||
m_backendVoice->resetSampleRate(m_curSample->m_sampleRate);
|
||||
m_needsSlew = false;
|
||||
|
||||
int32_t numSamples = m_curSample->getNumSamples();
|
||||
const int32_t numSamples = m_curSample->getNumSamples();
|
||||
if (offset) {
|
||||
if (m_curSample->isLooped()) {
|
||||
if (offset > int32_t(m_curSample->m_loopStartSample))
|
||||
offset = ((offset - m_curSample->m_loopStartSample) % m_curSample->m_loopLengthSamples) +
|
||||
m_curSample->m_loopStartSample;
|
||||
} else
|
||||
offset = std::clamp(0, offset, numSamples);
|
||||
} else {
|
||||
offset = std::clamp(offset, 0, numSamples);
|
||||
}
|
||||
}
|
||||
m_curSamplePos = offset;
|
||||
m_prev1 = 0;
|
||||
|
@ -895,12 +898,14 @@ void Voice::setVolume(float vol) {
|
|||
if (m_destroyed)
|
||||
return;
|
||||
|
||||
m_targetUserVol = std::clamp(0.f, vol, 1.f);
|
||||
m_targetUserVol = std::clamp(vol, 0.f, 1.f);
|
||||
for (ObjToken<Voice>& vox : m_childVoices)
|
||||
vox->setVolume(vol);
|
||||
}
|
||||
|
||||
void Voice::_panLaw(float coefs[8], float frontPan, float backPan, float totalSpan) const {
|
||||
std::array<float, 8> Voice::_panLaw(float frontPan, float backPan, float totalSpan) const {
|
||||
std::array<float, 8> coefs{};
|
||||
|
||||
/* -3dB panning law for various channel configs */
|
||||
switch (m_engine.m_channelSet) {
|
||||
case AudioChannelSet::Stereo:
|
||||
|
@ -1008,17 +1013,19 @@ void Voice::_panLaw(float coefs[8], float frontPan, float backPan, float totalSp
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
return coefs;
|
||||
}
|
||||
|
||||
void Voice::_setPan(float pan) {
|
||||
if (m_destroyed || m_emitter)
|
||||
if (m_destroyed || m_emitter) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_curPan = std::clamp(-1.f, pan, 1.f);
|
||||
float totalPan = std::clamp(-1.f, m_curPan, 1.f);
|
||||
float totalSpan = std::clamp(-1.f, m_curSpan, 1.f);
|
||||
float coefs[8] = {};
|
||||
_panLaw(coefs, totalPan, totalPan, totalSpan);
|
||||
m_curPan = std::clamp(pan, -1.f, 1.f);
|
||||
const float totalPan = std::clamp(m_curPan, -1.f, 1.f);
|
||||
const float totalSpan = std::clamp(m_curSpan, -1.f, 1.f);
|
||||
const auto coefs = _panLaw(totalPan, totalPan, totalSpan);
|
||||
_setChannelCoefs(coefs);
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1039,7 @@ void Voice::setPan(float pan) {
|
|||
}
|
||||
|
||||
void Voice::_setSurroundPan(float span) {
|
||||
m_curSpan = std::clamp(-1.f, span, 1.f);
|
||||
m_curSpan = std::clamp(span, -1.f, 1.f);
|
||||
_setPan(m_curPan);
|
||||
}
|
||||
|
||||
|
@ -1045,13 +1052,13 @@ void Voice::setSurroundPan(float span) {
|
|||
vox->setSurroundPan(span);
|
||||
}
|
||||
|
||||
void Voice::_setChannelCoefs(const float coefs[8]) {
|
||||
void Voice::_setChannelCoefs(const std::array<float, 8>& coefs) {
|
||||
m_backendVoice->setChannelLevels(m_studio->getMaster().m_backendSubmix.get(), coefs, true);
|
||||
m_backendVoice->setChannelLevels(m_studio->getAuxA().m_backendSubmix.get(), coefs, true);
|
||||
m_backendVoice->setChannelLevels(m_studio->getAuxB().m_backendSubmix.get(), coefs, true);
|
||||
}
|
||||
|
||||
void Voice::setChannelCoefs(const float coefs[8]) {
|
||||
void Voice::setChannelCoefs(const std::array<float, 8>& coefs) {
|
||||
if (m_destroyed)
|
||||
return;
|
||||
|
||||
|
@ -1063,8 +1070,8 @@ void Voice::setChannelCoefs(const float coefs[8]) {
|
|||
void Voice::startEnvelope(double dur, float vol, const Curve* envCurve) {
|
||||
m_envelopeTime = 0.f;
|
||||
m_envelopeDur = dur;
|
||||
m_envelopeStart = std::clamp(0.f, m_envelopeVol, 1.f);
|
||||
m_envelopeEnd = std::clamp(0.f, vol, 1.f);
|
||||
m_envelopeStart = std::clamp(m_envelopeVol, 0.f, 1.f);
|
||||
m_envelopeEnd = std::clamp(vol, 0.f, 1.f);
|
||||
m_envelopeCurve = envCurve;
|
||||
}
|
||||
|
||||
|
@ -1072,7 +1079,7 @@ void Voice::startFadeIn(double dur, float vol, const Curve* envCurve) {
|
|||
m_envelopeTime = 0.f;
|
||||
m_envelopeDur = dur;
|
||||
m_envelopeStart = 0.f;
|
||||
m_envelopeEnd = std::clamp(0.f, vol, 1.f);
|
||||
m_envelopeEnd = std::clamp(vol, 0.f, 1.f);
|
||||
m_envelopeCurve = envCurve;
|
||||
}
|
||||
|
||||
|
@ -1134,21 +1141,25 @@ void Voice::setPitchSweep2(uint8_t times, int16_t add) {
|
|||
}
|
||||
|
||||
void Voice::setReverbVol(float rvol) {
|
||||
if (m_destroyed)
|
||||
if (m_destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_curReverbVol = std::clamp(0.f, rvol, 1.f);
|
||||
for (ObjToken<Voice>& vox : m_childVoices)
|
||||
m_curReverbVol = std::clamp(rvol, 0.f, 1.f);
|
||||
for (ObjToken<Voice>& vox : m_childVoices) {
|
||||
vox->setReverbVol(rvol);
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::setAuxBVol(float bvol) {
|
||||
if (m_destroyed)
|
||||
if (m_destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_curAuxBVol = std::clamp(0.f, bvol, 1.f);
|
||||
for (ObjToken<Voice>& vox : m_childVoices)
|
||||
m_curAuxBVol = std::clamp(bvol, 0.f, 1.f);
|
||||
for (ObjToken<Voice>& vox : m_childVoices) {
|
||||
vox->setAuxBVol(bvol);
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::setAdsr(ObjectId adsrId, bool dls) {
|
||||
|
@ -1207,14 +1218,16 @@ void Voice::_setPitchWheel(float pitchWheel) {
|
|||
}
|
||||
|
||||
void Voice::setPitchWheel(float pitchWheel) {
|
||||
if (m_destroyed)
|
||||
if (m_destroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_curPitchWheel = std::clamp(-1.f, pitchWheel, 1.f);
|
||||
m_curPitchWheel = std::clamp(pitchWheel, -1.f, 1.f);
|
||||
_setPitchWheel(m_curPitchWheel);
|
||||
|
||||
for (ObjToken<Voice>& vox : m_childVoices)
|
||||
for (ObjToken<Voice>& vox : m_childVoices) {
|
||||
vox->setPitchWheel(pitchWheel);
|
||||
}
|
||||
}
|
||||
|
||||
void Voice::setPitchWheelRange(int8_t up, int8_t down) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#include "amuse/VolumeTable.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
|
||||
#include "amuse/Common.hpp"
|
||||
|
||||
namespace amuse {
|
||||
|
||||
static const float VolumeTable[] = {
|
||||
constexpr std::array<float, 129> VolumeTable{
|
||||
0.000000f, 0.000031f, 0.000153f, 0.000397f, 0.000702f, 0.001129f, 0.001648f, 0.002228f, 0.002930f, 0.003723f,
|
||||
0.004608f, 0.005585f, 0.006653f, 0.007843f, 0.009125f, 0.010498f, 0.011963f, 0.013550f, 0.015198f, 0.016999f,
|
||||
0.018860f, 0.020844f, 0.022919f, 0.025117f, 0.027406f, 0.029817f, 0.032319f, 0.034944f, 0.037660f, 0.040468f,
|
||||
|
@ -19,9 +19,10 @@ static const float VolumeTable[] = {
|
|||
0.452864f, 0.464217f, 0.475753f, 0.487442f, 0.499313f, 0.511399f, 0.523606f, 0.536027f, 0.548631f, 0.561419f,
|
||||
0.574389f, 0.587542f, 0.600879f, 0.614399f, 0.628132f, 0.642018f, 0.656148f, 0.670431f, 0.684927f, 0.699637f,
|
||||
0.714530f, 0.729637f, 0.744926f, 0.760430f, 0.776147f, 0.792077f, 0.808191f, 0.824549f, 0.841090f, 0.857845f,
|
||||
0.874844f, 0.892056f, 0.909452f, 0.927122f, 0.945006f, 0.963073f, 0.981414f, 1.000000f, 1.000000f};
|
||||
0.874844f, 0.892056f, 0.909452f, 0.927122f, 0.945006f, 0.963073f, 0.981414f, 1.000000f, 1.000000f,
|
||||
};
|
||||
|
||||
static const float DLSVolumeTable[] = {
|
||||
constexpr std::array<float, 129> DLSVolumeTable{
|
||||
0.000000f, 0.000062f, 0.000248f, 0.000558f, 0.000992f, 0.001550f, 0.002232f, 0.003038f, 0.003968f, 0.005022f,
|
||||
0.006200f, 0.007502f, 0.008928f, 0.010478f, 0.012152f, 0.013950f, 0.015872f, 0.017918f, 0.020088f, 0.022382f,
|
||||
0.024800f, 0.027342f, 0.030008f, 0.032798f, 0.035712f, 0.038750f, 0.041912f, 0.045198f, 0.048608f, 0.052142f,
|
||||
|
@ -34,25 +35,32 @@ static const float DLSVolumeTable[] = {
|
|||
0.502201f, 0.513423f, 0.524769f, 0.536239f, 0.547833f, 0.559551f, 0.571393f, 0.583359f, 0.595449f, 0.607663f,
|
||||
0.620001f, 0.632463f, 0.645049f, 0.657759f, 0.670593f, 0.683551f, 0.696633f, 0.709839f, 0.723169f, 0.736623f,
|
||||
0.750202f, 0.763904f, 0.777730f, 0.791680f, 0.805754f, 0.819952f, 0.834274f, 0.848720f, 0.863290f, 0.877984f,
|
||||
0.892802f, 0.907744f, 0.922810f, 0.938000f, 0.953314f, 0.968752f, 0.984314f, 1.000000f, 1.000000f};
|
||||
0.892802f, 0.907744f, 0.922810f, 0.938000f, 0.953314f, 0.968752f, 0.984314f, 1.000000f, 1.000000f,
|
||||
};
|
||||
|
||||
float LookupVolume(float vol) {
|
||||
vol = std::clamp(0.f, vol * 127.f, 127.f);
|
||||
float f = std::floor(vol);
|
||||
float c = std::ceil(vol);
|
||||
if (f == c)
|
||||
vol = std::clamp(vol * 127.f, 0.f, 127.f);
|
||||
const float f = std::floor(vol);
|
||||
const float c = std::ceil(vol);
|
||||
|
||||
if (f == c) {
|
||||
return VolumeTable[int(f)];
|
||||
float t = vol - f;
|
||||
}
|
||||
|
||||
const float t = vol - f;
|
||||
return (1.f - t) * VolumeTable[int(f)] + t * VolumeTable[int(c)];
|
||||
}
|
||||
|
||||
float LookupDLSVolume(float vol) {
|
||||
vol = std::clamp(0.f, vol * 127.f, 127.f);
|
||||
float f = std::floor(vol);
|
||||
float c = std::ceil(vol);
|
||||
if (f == c)
|
||||
vol = std::clamp(vol * 127.f, 0.f, 127.f);
|
||||
const float f = std::floor(vol);
|
||||
const float c = std::ceil(vol);
|
||||
|
||||
if (f == c) {
|
||||
return DLSVolumeTable[int(f)];
|
||||
float t = vol - f;
|
||||
}
|
||||
|
||||
const float t = vol - f;
|
||||
return (1.f - t) * DLSVolumeTable[int(f)] + t * DLSVolumeTable[int(c)];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue