Fix local signing issues

CQTexperiment
Christopher Snowhill 2020-02-13 17:35:20 -08:00
parent c2278b49be
commit 8bc6396918
141 changed files with 8173 additions and 12828 deletions

3
.gitmodules vendored
View File

@ -16,3 +16,6 @@
[submodule "Frameworks/libsidplay/sidplay-residfp-code"]
path = Frameworks/libsidplay/sidplay-residfp-code
url = https://bitbucket.org/losnoco/sidplay-residfp.git
[submodule "Frameworks/libatrac9/libatrac9"]
path = Frameworks/libatrac9/libatrac9
url = https://github.com/Thealexbarney/LibAtrac9.git

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -566,7 +566,7 @@
TargetAttributes = {
83D3C4D3201C654F005564CB = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
ProvisioningStyle = Manual;
};
};
};
@ -808,9 +808,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -828,6 +828,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.AdPlug;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
@ -836,9 +837,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -852,6 +853,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.AdPlug;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;

View File

@ -259,8 +259,11 @@
730F235509181A3A00AB638C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -273,6 +276,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.ogg;
PRODUCT_NAME = Ogg;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
ZERO_LINK = YES;
@ -282,8 +286,11 @@
730F235609181A3A00AB638C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -295,6 +302,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.8;
PRODUCT_BUNDLE_IDENTIFIER = org.xiph.ogg;
PRODUCT_NAME = Ogg;
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
ZERO_LINK = NO;

View File

@ -1141,7 +1141,7 @@
TargetAttributes = {
83E5EFBC1FFEF7CC00659F0F = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
ProvisioningStyle = Manual;
};
};
};
@ -1456,9 +1456,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -1471,6 +1471,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libOpenMPT;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
@ -1479,9 +1480,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
@ -1494,6 +1495,7 @@
);
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libOpenMPT;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;

View File

@ -578,6 +578,7 @@
LastUpgradeCheck = 1130;
TargetAttributes = {
730F23A1091827B100AB638C = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
};
738835E30B18F870005C7A69 = {
@ -756,11 +757,11 @@
730F23ED091827B100AB638C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = NO;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;
@ -791,11 +792,11 @@
730F23EE091827B100AB638C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = /Library/Frameworks;

View File

@ -234,6 +234,7 @@
TargetAttributes = {
83D7311B1A74968900CA1366 = {
CreatedOnToolsVersion = 6.1.1;
DevelopmentTeam = N6E749HJ2X;
};
};
};
@ -348,7 +349,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
@ -398,7 +399,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
@ -409,8 +410,10 @@
83D731331A74968900CA1366 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@loader_path/Frameworks";
@ -436,9 +439,10 @@
83D731341A74968900CA1366 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@loader_path/Frameworks";

View File

@ -1,374 +0,0 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
83D730FF1A738F4E00CA1366 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D730F21A738F4E00CA1366 /* common.c */; };
83D731001A738F4E00CA1366 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730F31A738F4E00CA1366 /* common.h */; };
83D731011A738F4E00CA1366 /* dct4.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D730F41A738F4E00CA1366 /* dct4.c */; };
83D731021A738F4E00CA1366 /* dct4.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730F51A738F4E00CA1366 /* dct4.h */; };
83D731031A738F4E00CA1366 /* decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D730F61A738F4E00CA1366 /* decoder.c */; };
83D731041A738F4E00CA1366 /* decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730F71A738F4E00CA1366 /* decoder.h */; };
83D731051A738F4E00CA1366 /* huffman.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D730F81A738F4E00CA1366 /* huffman.c */; };
83D731061A738F4E00CA1366 /* huffman.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730F91A738F4E00CA1366 /* huffman.h */; };
83D731071A738F4E00CA1366 /* huffman_consts.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730FA1A738F4E00CA1366 /* huffman_consts.h */; };
83D731081A738F4E00CA1366 /* rmlt.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D730FB1A738F4E00CA1366 /* rmlt.c */; };
83D731091A738F4E00CA1366 /* rmlt.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730FC1A738F4E00CA1366 /* rmlt.h */; };
83D7310A1A738F4E00CA1366 /* siren7.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730FD1A738F4E00CA1366 /* siren7.h */; };
83D7310B1A738F4E00CA1366 /* g7221.h in Headers */ = {isa = PBXBuildFile; fileRef = 83D730FE1A738F4E00CA1366 /* g7221.h */; settings = {ATTRIBUTES = (Public, ); }; };
83D7310D1A738F8500CA1366 /* g7221.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D7310C1A738F8500CA1366 /* g7221.c */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
83D730C91A738EB200CA1366 /* g7221.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = g7221.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83D730CD1A738EB200CA1366 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
83D730F21A738F4E00CA1366 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = common.c; sourceTree = "<group>"; };
83D730F31A738F4E00CA1366 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
83D730F41A738F4E00CA1366 /* dct4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dct4.c; sourceTree = "<group>"; };
83D730F51A738F4E00CA1366 /* dct4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dct4.h; sourceTree = "<group>"; };
83D730F61A738F4E00CA1366 /* decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decoder.c; sourceTree = "<group>"; };
83D730F71A738F4E00CA1366 /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decoder.h; sourceTree = "<group>"; };
83D730F81A738F4E00CA1366 /* huffman.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = huffman.c; sourceTree = "<group>"; };
83D730F91A738F4E00CA1366 /* huffman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huffman.h; sourceTree = "<group>"; };
83D730FA1A738F4E00CA1366 /* huffman_consts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huffman_consts.h; sourceTree = "<group>"; };
83D730FB1A738F4E00CA1366 /* rmlt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rmlt.c; sourceTree = "<group>"; };
83D730FC1A738F4E00CA1366 /* rmlt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rmlt.h; sourceTree = "<group>"; };
83D730FD1A738F4E00CA1366 /* siren7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = siren7.h; sourceTree = "<group>"; };
83D730FE1A738F4E00CA1366 /* g7221.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g7221.h; sourceTree = "<group>"; };
83D7310C1A738F8500CA1366 /* g7221.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g7221.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
83D730C51A738EB200CA1366 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
83D730BF1A738EB200CA1366 = {
isa = PBXGroup;
children = (
83D730CB1A738EB200CA1366 /* g7221 */,
83D730CA1A738EB200CA1366 /* Products */,
);
sourceTree = "<group>";
};
83D730CA1A738EB200CA1366 /* Products */ = {
isa = PBXGroup;
children = (
83D730C91A738EB200CA1366 /* g7221.framework */,
);
name = Products;
sourceTree = "<group>";
};
83D730CB1A738EB200CA1366 /* g7221 */ = {
isa = PBXGroup;
children = (
83D730F11A738F4E00CA1366 /* libsiren */,
83D730FE1A738F4E00CA1366 /* g7221.h */,
83D730CC1A738EB200CA1366 /* Supporting Files */,
83D7310C1A738F8500CA1366 /* g7221.c */,
);
path = g7221;
sourceTree = "<group>";
};
83D730CC1A738EB200CA1366 /* Supporting Files */ = {
isa = PBXGroup;
children = (
83D730CD1A738EB200CA1366 /* Info.plist */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
83D730F11A738F4E00CA1366 /* libsiren */ = {
isa = PBXGroup;
children = (
83D730F21A738F4E00CA1366 /* common.c */,
83D730F31A738F4E00CA1366 /* common.h */,
83D730F41A738F4E00CA1366 /* dct4.c */,
83D730F51A738F4E00CA1366 /* dct4.h */,
83D730F61A738F4E00CA1366 /* decoder.c */,
83D730F71A738F4E00CA1366 /* decoder.h */,
83D730F81A738F4E00CA1366 /* huffman.c */,
83D730F91A738F4E00CA1366 /* huffman.h */,
83D730FA1A738F4E00CA1366 /* huffman_consts.h */,
83D730FB1A738F4E00CA1366 /* rmlt.c */,
83D730FC1A738F4E00CA1366 /* rmlt.h */,
83D730FD1A738F4E00CA1366 /* siren7.h */,
);
path = libsiren;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
83D730C61A738EB200CA1366 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
83D7310B1A738F4E00CA1366 /* g7221.h in Headers */,
83D731061A738F4E00CA1366 /* huffman.h in Headers */,
83D7310A1A738F4E00CA1366 /* siren7.h in Headers */,
83D731071A738F4E00CA1366 /* huffman_consts.h in Headers */,
83D731001A738F4E00CA1366 /* common.h in Headers */,
83D731041A738F4E00CA1366 /* decoder.h in Headers */,
83D731021A738F4E00CA1366 /* dct4.h in Headers */,
83D731091A738F4E00CA1366 /* rmlt.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
83D730C81A738EB200CA1366 /* g7221 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 83D730DF1A738EB200CA1366 /* Build configuration list for PBXNativeTarget "g7221" */;
buildPhases = (
83D730C41A738EB200CA1366 /* Sources */,
83D730C51A738EB200CA1366 /* Frameworks */,
83D730C61A738EB200CA1366 /* Headers */,
83D730C71A738EB200CA1366 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = g7221;
productName = g7221;
productReference = 83D730C91A738EB200CA1366 /* g7221.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83D730C01A738EB200CA1366 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
83D730C81A738EB200CA1366 = {
CreatedOnToolsVersion = 6.1.1;
};
};
};
buildConfigurationList = 83D730C31A738EB200CA1366 /* Build configuration list for PBXProject "g7221" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 83D730BF1A738EB200CA1366;
productRefGroup = 83D730CA1A738EB200CA1366 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
83D730C81A738EB200CA1366 /* g7221 */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
83D730C71A738EB200CA1366 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
83D730C41A738EB200CA1366 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
83D731081A738F4E00CA1366 /* rmlt.c in Sources */,
83D731011A738F4E00CA1366 /* dct4.c in Sources */,
83D731031A738F4E00CA1366 /* decoder.c in Sources */,
83D7310D1A738F8500CA1366 /* g7221.c in Sources */,
83D730FF1A738F4E00CA1366 /* common.c in Sources */,
83D731051A738F4E00CA1366 /* huffman.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
83D730DD1A738EB200CA1366 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
83D730DE1A738EB200CA1366 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.10;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
83D730E01A738EB200CA1366 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@loader_path/Frameworks";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = g7221/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cogx.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Debug;
};
83D730E11A738EB200CA1366 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@loader_path/Frameworks";
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = g7221/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "org.cogx.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
83D730C31A738EB200CA1366 /* Build configuration list for PBXProject "g7221" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83D730DD1A738EB200CA1366 /* Debug */,
83D730DE1A738EB200CA1366 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
83D730DF1A738EB200CA1366 /* Build configuration list for PBXNativeTarget "g7221" */ = {
isa = XCConfigurationList;
buildConfigurations = (
83D730E01A738EB200CA1366 /* Debug */,
83D730E11A738EB200CA1366 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 83D730C01A738EB200CA1366 /* Project object */;
}

View File

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1130"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83D730C81A738EB200CA1366"
BuildableName = "g7221.framework"
BlueprintName = "g7221"
ReferencedContainer = "container:g7221.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83D730C81A738EB200CA1366"
BuildableName = "g7221.framework"
BlueprintName = "g7221"
ReferencedContainer = "container:g7221.xcodeproj">
</BuildableReference>
</MacroExpansion>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83D730C81A738EB200CA1366"
BuildableName = "g7221.framework"
BlueprintName = "g7221"
ReferencedContainer = "container:g7221.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

@ -0,0 +1 @@
Subproject commit 6a9e00f6c7abd74d037fd210b6670d3cdb313049

View File

@ -13,14 +13,12 @@
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2018 Christopher Snowhill. All rights reserved.</string>
<key>NSPrincipalClass</key>
<string></string>
<string>Copyright © 2020 Christopher Snowhill. All rights reserved.</string>
</dict>
</plist>

View File

@ -3,75 +3,76 @@
archiveVersion = 1;
classes = {
};
objectVersion = 48;
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
830EBDF020045FF80023AA10 /* tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDB920045FF80023AA10 /* tables.c */; };
830EBDF120045FF80023AA10 /* libatrac9.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDBA20045FF80023AA10 /* libatrac9.c */; };
830EBDF220045FF80023AA10 /* huffCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDBB20045FF80023AA10 /* huffCodes.c */; };
830EBDF320045FF80023AA10 /* imdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDBC20045FF80023AA10 /* imdct.c */; };
830EBDF420045FF80023AA10 /* scale_factors.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDBD20045FF80023AA10 /* scale_factors.h */; };
830EBDF520045FF80023AA10 /* utility.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDBE20045FF80023AA10 /* utility.c */; };
830EBDF620045FF80023AA10 /* quantization.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDBF20045FF80023AA10 /* quantization.h */; };
830EBDF720045FF80023AA10 /* band_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDC020045FF80023AA10 /* band_extension.c */; };
830EBDF820045FF80023AA10 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDC120045FF80023AA10 /* unpack.c */; };
830EBDF920045FF80023AA10 /* bit_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDC220045FF80023AA10 /* bit_reader.h */; };
830EBDFA20045FF80023AA10 /* decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDC320045FF80023AA10 /* decoder.h */; };
830EBDFB20045FF80023AA10 /* decinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDC420045FF80023AA10 /* decinit.c */; };
830EBDFC20045FF80023AA10 /* bit_allocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDC520045FF80023AA10 /* bit_allocation.h */; };
830EBDFE20045FF80023AA10 /* libatrac9.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDC720045FF80023AA10 /* libatrac9.h */; settings = {ATTRIBUTES = (Public, ); }; };
830EBDFF20045FF80023AA10 /* tables.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDC820045FF80023AA10 /* tables.h */; };
830EBE0020045FF80023AA10 /* scale_factors.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDC920045FF80023AA10 /* scale_factors.c */; };
830EBE0120045FF80023AA10 /* error_codes.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDCA20045FF80023AA10 /* error_codes.h */; };
830EBE0220045FF80023AA10 /* imdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDCB20045FF80023AA10 /* imdct.h */; };
830EBE0420045FF80023AA10 /* huffCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDCD20045FF80023AA10 /* huffCodes.h */; };
830EBE0520045FF80023AA10 /* decinit.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDCE20045FF80023AA10 /* decinit.h */; };
830EBE0620045FF80023AA10 /* decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDCF20045FF80023AA10 /* decoder.c */; };
830EBE0720045FF80023AA10 /* bit_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDD020045FF80023AA10 /* bit_reader.c */; };
830EBE0820045FF80023AA10 /* unpack.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDD120045FF80023AA10 /* unpack.h */; };
830EBE0A20045FF80023AA10 /* quantization.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDD320045FF80023AA10 /* quantization.c */; };
830EBE0B20045FF80023AA10 /* utility.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDD420045FF80023AA10 /* utility.h */; };
830EBE0C20045FF80023AA10 /* band_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDD520045FF80023AA10 /* band_extension.h */; };
830EBE0D20045FF80023AA10 /* bit_allocation.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBDD620045FF80023AA10 /* bit_allocation.c */; };
830EBE0E20045FF80023AA10 /* structures.h in Headers */ = {isa = PBXBuildFile; fileRef = 830EBDD720045FF80023AA10 /* structures.h */; };
835FC6E523F62B0F006960FA /* structures.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6C923F62B0E006960FA /* structures.h */; };
835FC6E623F62B0F006960FA /* bit_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CA23F62B0E006960FA /* bit_reader.c */; };
835FC6E723F62B0F006960FA /* quantization.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CB23F62B0E006960FA /* quantization.c */; };
835FC6E823F62B0F006960FA /* decinit.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CC23F62B0E006960FA /* decinit.c */; };
835FC6E923F62B0F006960FA /* libatrac9.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CD23F62B0E006960FA /* libatrac9.c */; };
835FC6EA23F62B0F006960FA /* imdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CE23F62B0E006960FA /* imdct.c */; };
835FC6EB23F62B0F006960FA /* tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6CF23F62B0E006960FA /* tables.c */; };
835FC6EC23F62B0F006960FA /* decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D023F62B0E006960FA /* decoder.h */; };
835FC6ED23F62B0F006960FA /* scale_factors.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D123F62B0E006960FA /* scale_factors.h */; };
835FC6EE23F62B0F006960FA /* libatrac9.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D223F62B0E006960FA /* libatrac9.h */; settings = {ATTRIBUTES = (Public, ); }; };
835FC6EF23F62B0F006960FA /* scale_factors.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6D323F62B0E006960FA /* scale_factors.c */; };
835FC6F023F62B0F006960FA /* decinit.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D423F62B0F006960FA /* decinit.h */; };
835FC6F123F62B0F006960FA /* imdct.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D523F62B0F006960FA /* imdct.h */; };
835FC6F223F62B0F006960FA /* bit_allocation.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6D623F62B0F006960FA /* bit_allocation.c */; };
835FC6F323F62B0F006960FA /* utility.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D723F62B0F006960FA /* utility.h */; };
835FC6F423F62B0F006960FA /* unpack.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6D823F62B0F006960FA /* unpack.h */; };
835FC6F523F62B0F006960FA /* huffCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6D923F62B0F006960FA /* huffCodes.c */; };
835FC6F623F62B0F006960FA /* quantization.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6DA23F62B0F006960FA /* quantization.h */; };
835FC6F723F62B0F006960FA /* decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6DB23F62B0F006960FA /* decoder.c */; };
835FC6F823F62B0F006960FA /* band_extension.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6DC23F62B0F006960FA /* band_extension.h */; };
835FC6F923F62B0F006960FA /* band_extension.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6DD23F62B0F006960FA /* band_extension.c */; };
835FC6FA23F62B0F006960FA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6DE23F62B0F006960FA /* unpack.c */; };
835FC6FB23F62B0F006960FA /* bit_allocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6DF23F62B0F006960FA /* bit_allocation.h */; };
835FC6FC23F62B0F006960FA /* tables.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6E023F62B0F006960FA /* tables.h */; };
835FC6FD23F62B0F006960FA /* utility.c in Sources */ = {isa = PBXBuildFile; fileRef = 835FC6E123F62B0F006960FA /* utility.c */; };
835FC6FE23F62B0F006960FA /* bit_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6E223F62B0F006960FA /* bit_reader.h */; };
835FC6FF23F62B0F006960FA /* error_codes.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6E323F62B0F006960FA /* error_codes.h */; };
835FC70023F62B0F006960FA /* huffCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 835FC6E423F62B0F006960FA /* huffCodes.h */; };
836C052423F62E9300FA07C7 /* libatrac9-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 836C052323F62E9200FA07C7 /* libatrac9-Info.plist */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
830EBD8720045F190023AA10 /* libatrac9.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libatrac9.framework; sourceTree = BUILT_PRODUCTS_DIR; };
830EBD8B20045F190023AA10 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
830EBDB920045FF80023AA10 /* tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tables.c; sourceTree = "<group>"; };
830EBDBA20045FF80023AA10 /* libatrac9.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libatrac9.c; sourceTree = "<group>"; };
830EBDBB20045FF80023AA10 /* huffCodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = huffCodes.c; sourceTree = "<group>"; };
830EBDBC20045FF80023AA10 /* imdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imdct.c; sourceTree = "<group>"; };
830EBDBD20045FF80023AA10 /* scale_factors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = scale_factors.h; sourceTree = "<group>"; };
830EBDBE20045FF80023AA10 /* utility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utility.c; sourceTree = "<group>"; };
830EBDBF20045FF80023AA10 /* quantization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = quantization.h; sourceTree = "<group>"; };
830EBDC020045FF80023AA10 /* band_extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = band_extension.c; sourceTree = "<group>"; };
830EBDC120045FF80023AA10 /* unpack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unpack.c; sourceTree = "<group>"; };
830EBDC220045FF80023AA10 /* bit_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bit_reader.h; sourceTree = "<group>"; };
830EBDC320045FF80023AA10 /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decoder.h; sourceTree = "<group>"; };
830EBDC420045FF80023AA10 /* decinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decinit.c; sourceTree = "<group>"; };
830EBDC520045FF80023AA10 /* bit_allocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bit_allocation.h; sourceTree = "<group>"; };
830EBDC720045FF80023AA10 /* libatrac9.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libatrac9.h; sourceTree = "<group>"; };
830EBDC820045FF80023AA10 /* tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tables.h; sourceTree = "<group>"; };
830EBDC920045FF80023AA10 /* scale_factors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scale_factors.c; sourceTree = "<group>"; };
830EBDCA20045FF80023AA10 /* error_codes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = error_codes.h; sourceTree = "<group>"; };
830EBDCB20045FF80023AA10 /* imdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imdct.h; sourceTree = "<group>"; };
830EBDCD20045FF80023AA10 /* huffCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = huffCodes.h; sourceTree = "<group>"; };
830EBDCE20045FF80023AA10 /* decinit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = decinit.h; sourceTree = "<group>"; };
830EBDCF20045FF80023AA10 /* decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = decoder.c; sourceTree = "<group>"; };
830EBDD020045FF80023AA10 /* bit_reader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bit_reader.c; sourceTree = "<group>"; };
830EBDD120045FF80023AA10 /* unpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unpack.h; sourceTree = "<group>"; };
830EBDD320045FF80023AA10 /* quantization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = quantization.c; sourceTree = "<group>"; };
830EBDD420045FF80023AA10 /* utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utility.h; sourceTree = "<group>"; };
830EBDD520045FF80023AA10 /* band_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = band_extension.h; sourceTree = "<group>"; };
830EBDD620045FF80023AA10 /* bit_allocation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bit_allocation.c; sourceTree = "<group>"; };
830EBDD720045FF80023AA10 /* structures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = structures.h; sourceTree = "<group>"; };
835FC6B023F61BF0006960FA /* libatrac9.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libatrac9.framework; sourceTree = BUILT_PRODUCTS_DIR; };
835FC6C923F62B0E006960FA /* structures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = structures.h; path = C/src/structures.h; sourceTree = "<group>"; };
835FC6CA23F62B0E006960FA /* bit_reader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bit_reader.c; path = C/src/bit_reader.c; sourceTree = "<group>"; };
835FC6CB23F62B0E006960FA /* quantization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = quantization.c; path = C/src/quantization.c; sourceTree = "<group>"; };
835FC6CC23F62B0E006960FA /* decinit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = decinit.c; path = C/src/decinit.c; sourceTree = "<group>"; };
835FC6CD23F62B0E006960FA /* libatrac9.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = libatrac9.c; path = C/src/libatrac9.c; sourceTree = "<group>"; };
835FC6CE23F62B0E006960FA /* imdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = imdct.c; path = C/src/imdct.c; sourceTree = "<group>"; };
835FC6CF23F62B0E006960FA /* tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tables.c; path = C/src/tables.c; sourceTree = "<group>"; };
835FC6D023F62B0E006960FA /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = decoder.h; path = C/src/decoder.h; sourceTree = "<group>"; };
835FC6D123F62B0E006960FA /* scale_factors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scale_factors.h; path = C/src/scale_factors.h; sourceTree = "<group>"; };
835FC6D223F62B0E006960FA /* libatrac9.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = libatrac9.h; path = C/src/libatrac9.h; sourceTree = "<group>"; };
835FC6D323F62B0E006960FA /* scale_factors.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = scale_factors.c; path = C/src/scale_factors.c; sourceTree = "<group>"; };
835FC6D423F62B0F006960FA /* decinit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = decinit.h; path = C/src/decinit.h; sourceTree = "<group>"; };
835FC6D523F62B0F006960FA /* imdct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imdct.h; path = C/src/imdct.h; sourceTree = "<group>"; };
835FC6D623F62B0F006960FA /* bit_allocation.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bit_allocation.c; path = C/src/bit_allocation.c; sourceTree = "<group>"; };
835FC6D723F62B0F006960FA /* utility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utility.h; path = C/src/utility.h; sourceTree = "<group>"; };
835FC6D823F62B0F006960FA /* unpack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unpack.h; path = C/src/unpack.h; sourceTree = "<group>"; };
835FC6D923F62B0F006960FA /* huffCodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = huffCodes.c; path = C/src/huffCodes.c; sourceTree = "<group>"; };
835FC6DA23F62B0F006960FA /* quantization.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quantization.h; path = C/src/quantization.h; sourceTree = "<group>"; };
835FC6DB23F62B0F006960FA /* decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = decoder.c; path = C/src/decoder.c; sourceTree = "<group>"; };
835FC6DC23F62B0F006960FA /* band_extension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = band_extension.h; path = C/src/band_extension.h; sourceTree = "<group>"; };
835FC6DD23F62B0F006960FA /* band_extension.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = band_extension.c; path = C/src/band_extension.c; sourceTree = "<group>"; };
835FC6DE23F62B0F006960FA /* unpack.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack.c; path = C/src/unpack.c; sourceTree = "<group>"; };
835FC6DF23F62B0F006960FA /* bit_allocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bit_allocation.h; path = C/src/bit_allocation.h; sourceTree = "<group>"; };
835FC6E023F62B0F006960FA /* tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tables.h; path = C/src/tables.h; sourceTree = "<group>"; };
835FC6E123F62B0F006960FA /* utility.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = utility.c; path = C/src/utility.c; sourceTree = "<group>"; };
835FC6E223F62B0F006960FA /* bit_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bit_reader.h; path = C/src/bit_reader.h; sourceTree = "<group>"; };
835FC6E323F62B0F006960FA /* error_codes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = error_codes.h; path = C/src/error_codes.h; sourceTree = "<group>"; };
835FC6E423F62B0F006960FA /* huffCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = huffCodes.h; path = C/src/huffCodes.h; sourceTree = "<group>"; };
836C052323F62E9200FA07C7 /* libatrac9-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "libatrac9-Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
830EBD8320045F190023AA10 /* Frameworks */ = {
835FC6AD23F61BF0006960FA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
@ -81,110 +82,94 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
830EBD7D20045F190023AA10 = {
835FC6A623F61BF0006960FA = {
isa = PBXGroup;
children = (
830EBD8920045F190023AA10 /* libatrac9 */,
830EBD8820045F190023AA10 /* Products */,
836C052323F62E9200FA07C7 /* libatrac9-Info.plist */,
835FC6B223F61BF0006960FA /* libatrac9 */,
835FC6B123F61BF0006960FA /* Products */,
);
sourceTree = "<group>";
};
830EBD8820045F190023AA10 /* Products */ = {
835FC6B123F61BF0006960FA /* Products */ = {
isa = PBXGroup;
children = (
830EBD8720045F190023AA10 /* libatrac9.framework */,
835FC6B023F61BF0006960FA /* libatrac9.framework */,
);
name = Products;
sourceTree = "<group>";
};
830EBD8920045F190023AA10 /* libatrac9 */ = {
835FC6B223F61BF0006960FA /* libatrac9 */ = {
isa = PBXGroup;
children = (
830EBD9C20045FF80023AA10 /* LibAtrac9 */,
830EBD8B20045F190023AA10 /* Info.plist */,
835FC6DD23F62B0F006960FA /* band_extension.c */,
835FC6DC23F62B0F006960FA /* band_extension.h */,
835FC6D623F62B0F006960FA /* bit_allocation.c */,
835FC6DF23F62B0F006960FA /* bit_allocation.h */,
835FC6CA23F62B0E006960FA /* bit_reader.c */,
835FC6E223F62B0F006960FA /* bit_reader.h */,
835FC6CC23F62B0E006960FA /* decinit.c */,
835FC6D423F62B0F006960FA /* decinit.h */,
835FC6DB23F62B0F006960FA /* decoder.c */,
835FC6D023F62B0E006960FA /* decoder.h */,
835FC6E323F62B0F006960FA /* error_codes.h */,
835FC6D923F62B0F006960FA /* huffCodes.c */,
835FC6E423F62B0F006960FA /* huffCodes.h */,
835FC6CE23F62B0E006960FA /* imdct.c */,
835FC6D523F62B0F006960FA /* imdct.h */,
835FC6CD23F62B0E006960FA /* libatrac9.c */,
835FC6D223F62B0E006960FA /* libatrac9.h */,
835FC6CB23F62B0E006960FA /* quantization.c */,
835FC6DA23F62B0F006960FA /* quantization.h */,
835FC6D323F62B0E006960FA /* scale_factors.c */,
835FC6D123F62B0E006960FA /* scale_factors.h */,
835FC6C923F62B0E006960FA /* structures.h */,
835FC6CF23F62B0E006960FA /* tables.c */,
835FC6E023F62B0F006960FA /* tables.h */,
835FC6DE23F62B0F006960FA /* unpack.c */,
835FC6D823F62B0F006960FA /* unpack.h */,
835FC6E123F62B0F006960FA /* utility.c */,
835FC6D723F62B0F006960FA /* utility.h */,
);
path = libatrac9;
sourceTree = "<group>";
};
830EBD9C20045FF80023AA10 /* LibAtrac9 */ = {
isa = PBXGroup;
children = (
830EBDB820045FF80023AA10 /* C */,
);
path = LibAtrac9;
sourceTree = "<group>";
};
830EBDB820045FF80023AA10 /* C */ = {
isa = PBXGroup;
children = (
830EBDC020045FF80023AA10 /* band_extension.c */,
830EBDD520045FF80023AA10 /* band_extension.h */,
830EBDD620045FF80023AA10 /* bit_allocation.c */,
830EBDC520045FF80023AA10 /* bit_allocation.h */,
830EBDD020045FF80023AA10 /* bit_reader.c */,
830EBDC220045FF80023AA10 /* bit_reader.h */,
830EBDC420045FF80023AA10 /* decinit.c */,
830EBDCE20045FF80023AA10 /* decinit.h */,
830EBDCF20045FF80023AA10 /* decoder.c */,
830EBDC320045FF80023AA10 /* decoder.h */,
830EBDCA20045FF80023AA10 /* error_codes.h */,
830EBDBB20045FF80023AA10 /* huffCodes.c */,
830EBDCD20045FF80023AA10 /* huffCodes.h */,
830EBDBC20045FF80023AA10 /* imdct.c */,
830EBDCB20045FF80023AA10 /* imdct.h */,
830EBDBA20045FF80023AA10 /* libatrac9.c */,
830EBDC720045FF80023AA10 /* libatrac9.h */,
830EBDD320045FF80023AA10 /* quantization.c */,
830EBDBF20045FF80023AA10 /* quantization.h */,
830EBDC920045FF80023AA10 /* scale_factors.c */,
830EBDBD20045FF80023AA10 /* scale_factors.h */,
830EBDD720045FF80023AA10 /* structures.h */,
830EBDB920045FF80023AA10 /* tables.c */,
830EBDC820045FF80023AA10 /* tables.h */,
830EBDC120045FF80023AA10 /* unpack.c */,
830EBDD120045FF80023AA10 /* unpack.h */,
830EBDBE20045FF80023AA10 /* utility.c */,
830EBDD420045FF80023AA10 /* utility.h */,
);
path = C;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
830EBD8420045F190023AA10 /* Headers */ = {
835FC6AB23F61BF0006960FA /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
830EBDFE20045FF80023AA10 /* libatrac9.h in Headers */,
830EBE0220045FF80023AA10 /* imdct.h in Headers */,
830EBE0520045FF80023AA10 /* decinit.h in Headers */,
830EBE0420045FF80023AA10 /* huffCodes.h in Headers */,
830EBE0B20045FF80023AA10 /* utility.h in Headers */,
830EBE0820045FF80023AA10 /* unpack.h in Headers */,
830EBDF420045FF80023AA10 /* scale_factors.h in Headers */,
830EBE0C20045FF80023AA10 /* band_extension.h in Headers */,
830EBE0120045FF80023AA10 /* error_codes.h in Headers */,
830EBDFA20045FF80023AA10 /* decoder.h in Headers */,
830EBDFF20045FF80023AA10 /* tables.h in Headers */,
830EBDF920045FF80023AA10 /* bit_reader.h in Headers */,
830EBE0E20045FF80023AA10 /* structures.h in Headers */,
830EBDFC20045FF80023AA10 /* bit_allocation.h in Headers */,
830EBDF620045FF80023AA10 /* quantization.h in Headers */,
835FC6EE23F62B0F006960FA /* libatrac9.h in Headers */,
835FC6F423F62B0F006960FA /* unpack.h in Headers */,
835FC6FC23F62B0F006960FA /* tables.h in Headers */,
835FC6F823F62B0F006960FA /* band_extension.h in Headers */,
835FC6F123F62B0F006960FA /* imdct.h in Headers */,
835FC6FB23F62B0F006960FA /* bit_allocation.h in Headers */,
835FC6FE23F62B0F006960FA /* bit_reader.h in Headers */,
835FC6F023F62B0F006960FA /* decinit.h in Headers */,
835FC70023F62B0F006960FA /* huffCodes.h in Headers */,
835FC6E523F62B0F006960FA /* structures.h in Headers */,
835FC6ED23F62B0F006960FA /* scale_factors.h in Headers */,
835FC6FF23F62B0F006960FA /* error_codes.h in Headers */,
835FC6F323F62B0F006960FA /* utility.h in Headers */,
835FC6F623F62B0F006960FA /* quantization.h in Headers */,
835FC6EC23F62B0F006960FA /* decoder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
830EBD8620045F190023AA10 /* libatrac9 */ = {
835FC6AF23F61BF0006960FA /* libatrac9 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 830EBD8F20045F190023AA10 /* Build configuration list for PBXNativeTarget "libatrac9" */;
buildConfigurationList = 835FC6B823F61BF0006960FA /* Build configuration list for PBXNativeTarget "libatrac9" */;
buildPhases = (
830EBD8220045F190023AA10 /* Sources */,
830EBD8320045F190023AA10 /* Frameworks */,
830EBD8420045F190023AA10 /* Headers */,
830EBD8520045F190023AA10 /* Resources */,
835FC6AB23F61BF0006960FA /* Headers */,
835FC6AC23F61BF0006960FA /* Sources */,
835FC6AD23F61BF0006960FA /* Frameworks */,
835FC6AE23F61BF0006960FA /* Resources */,
);
buildRules = (
);
@ -192,77 +177,77 @@
);
name = libatrac9;
productName = libatrac9;
productReference = 830EBD8720045F190023AA10 /* libatrac9.framework */;
productReference = 835FC6B023F61BF0006960FA /* libatrac9.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
830EBD7E20045F190023AA10 /* Project object */ = {
835FC6A723F61BF0006960FA /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0940;
LastUpgradeCheck = 1130;
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
830EBD8620045F190023AA10 = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
835FC6AF23F61BF0006960FA = {
CreatedOnToolsVersion = 11.3.1;
};
};
};
buildConfigurationList = 830EBD8120045F190023AA10 /* Build configuration list for PBXProject "libatrac9" */;
compatibilityVersion = "Xcode 8.0";
buildConfigurationList = 835FC6AA23F61BF0006960FA /* Build configuration list for PBXProject "libatrac9" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 830EBD7D20045F190023AA10;
productRefGroup = 830EBD8820045F190023AA10 /* Products */;
mainGroup = 835FC6A623F61BF0006960FA;
productRefGroup = 835FC6B123F61BF0006960FA /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
830EBD8620045F190023AA10 /* libatrac9 */,
835FC6AF23F61BF0006960FA /* libatrac9 */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
830EBD8520045F190023AA10 /* Resources */ = {
835FC6AE23F61BF0006960FA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
836C052423F62E9300FA07C7 /* libatrac9-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
830EBD8220045F190023AA10 /* Sources */ = {
835FC6AC23F61BF0006960FA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
830EBE0620045FF80023AA10 /* decoder.c in Sources */,
830EBDF720045FF80023AA10 /* band_extension.c in Sources */,
830EBE0020045FF80023AA10 /* scale_factors.c in Sources */,
830EBDF520045FF80023AA10 /* utility.c in Sources */,
830EBDFB20045FF80023AA10 /* decinit.c in Sources */,
830EBE0720045FF80023AA10 /* bit_reader.c in Sources */,
830EBE0A20045FF80023AA10 /* quantization.c in Sources */,
830EBDF820045FF80023AA10 /* unpack.c in Sources */,
830EBDF020045FF80023AA10 /* tables.c in Sources */,
830EBDF320045FF80023AA10 /* imdct.c in Sources */,
830EBDF220045FF80023AA10 /* huffCodes.c in Sources */,
830EBDF120045FF80023AA10 /* libatrac9.c in Sources */,
830EBE0D20045FF80023AA10 /* bit_allocation.c in Sources */,
835FC6FD23F62B0F006960FA /* utility.c in Sources */,
835FC6F723F62B0F006960FA /* decoder.c in Sources */,
835FC6EB23F62B0F006960FA /* tables.c in Sources */,
835FC6EA23F62B0F006960FA /* imdct.c in Sources */,
835FC6FA23F62B0F006960FA /* unpack.c in Sources */,
835FC6E723F62B0F006960FA /* quantization.c in Sources */,
835FC6EF23F62B0F006960FA /* scale_factors.c in Sources */,
835FC6E823F62B0F006960FA /* decinit.c in Sources */,
835FC6F223F62B0F006960FA /* bit_allocation.c in Sources */,
835FC6E623F62B0F006960FA /* bit_reader.c in Sources */,
835FC6F923F62B0F006960FA /* band_extension.c in Sources */,
835FC6F523F62B0F006960FA /* huffCodes.c in Sources */,
835FC6E923F62B0F006960FA /* libatrac9.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
830EBD8D20045F190023AA10 /* Debug */ = {
835FC6B623F61BF0006960FA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@ -272,6 +257,7 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
@ -293,7 +279,6 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
@ -313,9 +298,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = YES;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
@ -323,7 +308,7 @@
};
name = Debug;
};
830EBD8E20045F190023AA10 /* Release */ = {
835FC6B723F61BF0006960FA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
@ -333,6 +318,7 @@
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
@ -354,7 +340,6 @@
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
CODE_SIGN_IDENTITY = "Mac Developer";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@ -368,53 +353,59 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.13;
MACOSX_DEPLOYMENT_TARGET = 10.8;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
830EBD9020045F190023AA10 /* Debug */ = {
835FC6B923F61BF0006960FA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = libatrac9/LibAtrac9/C;
INFOPLIST_FILE = libatrac9/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libatrac9;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = libatrac9-Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = co.losno.libatrac9;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
};
830EBD9120045F190023AA10 /* Release */ = {
835FC6BA23F61BF0006960FA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
HEADER_SEARCH_PATHS = libatrac9/LibAtrac9/C;
INFOPLIST_FILE = libatrac9/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libatrac9;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = libatrac9-Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = co.losno.libatrac9;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;
@ -422,25 +413,25 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
830EBD8120045F190023AA10 /* Build configuration list for PBXProject "libatrac9" */ = {
835FC6AA23F61BF0006960FA /* Build configuration list for PBXProject "libatrac9" */ = {
isa = XCConfigurationList;
buildConfigurations = (
830EBD8D20045F190023AA10 /* Debug */,
830EBD8E20045F190023AA10 /* Release */,
835FC6B623F61BF0006960FA /* Debug */,
835FC6B723F61BF0006960FA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
830EBD8F20045F190023AA10 /* Build configuration list for PBXNativeTarget "libatrac9" */ = {
835FC6B823F61BF0006960FA /* Build configuration list for PBXNativeTarget "libatrac9" */ = {
isa = XCConfigurationList;
buildConfigurations = (
830EBD9020045F190023AA10 /* Debug */,
830EBD9120045F190023AA10 /* Release */,
835FC6B923F61BF0006960FA /* Debug */,
835FC6BA23F61BF0006960FA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 830EBD7E20045F190023AA10 /* Project object */;
rootObject = 835FC6A723F61BF0006960FA /* Project object */;
}

View File

@ -1,63 +0,0 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

View File

@ -1,261 +0,0 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

View File

@ -1,191 +0,0 @@
#include "band_extension.h"
#include "tables.h"
#include "utility.h"
#include <math.h>
void ApplyBandExtension(block* block)
{
if (!block->BandExtensionEnabled || !block->HasExtensionData) return;
for (int i = 0; i < block->ChannelCount; i++)
{
ApplyBandExtensionChannel(&block->Channels[i]);
}
}
void ApplyBandExtensionChannel(channel* channel)
{
const int groupAUnit = channel->Block->QuantizationUnitCount;
int* scaleFactors = channel->ScaleFactors;
double* spectra = channel->Spectra;
double scales[6];
int* values = channel->BexValues;
const bex_group* bex_info = &BexGroupInfo[channel->Block->QuantizationUnitCount - 13];
const int bandCount = bex_info->band_count;
const int groupBUnit = bex_info->group_b_unit;
const int groupCUnit = bex_info->group_c_unit;
const int totalUnits = max(groupCUnit, 22);
const int bexQuantUnits = totalUnits - groupAUnit;
const int groupABin = QuantUnitToCoeffIndex[groupAUnit];
const int groupBBin = QuantUnitToCoeffIndex[groupBUnit];
const int groupCBin = QuantUnitToCoeffIndex[groupCUnit];
const int totalBins = QuantUnitToCoeffIndex[totalUnits];
FillHighFrequencies(spectra, groupABin, groupBBin, groupCBin, totalBins);
double groupAScale, groupBScale, groupCScale;
double rate, scale, mult;
switch (channel->BexMode)
{
case 0:
switch (bandCount)
{
case 3:
scales[0] = BexMode0Bands3[0][values[0]];
scales[1] = BexMode0Bands3[1][values[0]];
scales[2] = BexMode0Bands3[2][values[1]];
scales[3] = BexMode0Bands3[3][values[2]];
scales[4] = BexMode0Bands3[4][values[3]];
break;
case 4:
scales[0] = BexMode0Bands4[0][values[0]];
scales[1] = BexMode0Bands4[1][values[0]];
scales[2] = BexMode0Bands4[2][values[1]];
scales[3] = BexMode0Bands4[3][values[2]];
scales[4] = BexMode0Bands4[4][values[3]];
break;
case 5:
scales[0] = BexMode0Bands5[0][values[0]];
scales[1] = BexMode0Bands5[1][values[1]];
scales[2] = BexMode0Bands5[2][values[1]];
break;
}
scales[bexQuantUnits - 1] = SpectrumScale[scaleFactors[groupAUnit]];
AddNoiseToSpectrum(channel, QuantUnitToCoeffIndex[totalUnits - 1],
QuantUnitToCoeffCount[totalUnits - 1]);
ScaleBexQuantUnits(spectra, scales, groupAUnit, totalUnits);
break;
case 1:
for (int i = groupAUnit; i < totalUnits; i++)
{
scales[i - groupAUnit] = SpectrumScale[scaleFactors[i]];
}
AddNoiseToSpectrum(channel, groupABin, totalBins - groupABin);
ScaleBexQuantUnits(spectra, scales, groupAUnit, totalUnits);
break;
case 2:
groupAScale = BexMode2Scale[values[0]];
groupBScale = BexMode2Scale[values[1]];
for (int i = groupABin; i < groupBBin; i++)
{
spectra[i] *= groupAScale;
}
for (int i = groupBBin; i < groupCBin; i++)
{
spectra[i] *= groupBScale;
}
return;
case 3:
rate = pow(2, BexMode3Rate[values[1]]);
scale = BexMode3Initial[values[0]];
for (int i = groupABin; i < totalBins; i++)
{
scale *= rate;
spectra[i] *= scale;
}
return;
case 4:
mult = BexMode4Multiplier[values[0]];
groupAScale = 0.7079468 * mult;
groupBScale = 0.5011902 * mult;
groupCScale = 0.3548279 * mult;
for (int i = groupABin; i < groupBBin; i++)
{
spectra[i] *= groupAScale;
}
for (int i = groupBBin; i < groupCBin; i++)
{
spectra[i] *= groupBScale;
}
for (int i = groupCBin; i < totalBins; i++)
{
spectra[i] *= groupCScale;
}
}
}
void ScaleBexQuantUnits(double* spectra, double* scales, int startUnit, int totalUnits)
{
for (int i = startUnit; i < totalUnits; i++)
{
for (int k = QuantUnitToCoeffIndex[i]; k < QuantUnitToCoeffIndex[i + 1]; k++)
{
spectra[k] *= scales[i - startUnit];
}
}
}
void FillHighFrequencies(double* spectra, int groupABin, int groupBBin, int groupCBin, int totalBins)
{
for (int i = 0; i < groupBBin - groupABin; i++)
{
spectra[groupABin + i] = spectra[groupABin - i - 1];
}
for (int i = 0; i < groupCBin - groupBBin; i++)
{
spectra[groupBBin + i] = spectra[groupBBin - i - 1];
}
for (int i = 0; i < totalBins - groupCBin; i++)
{
spectra[groupCBin + i] = spectra[groupCBin - i - 1];
}
}
void AddNoiseToSpectrum(channel* channel, int index, int count)
{
if (!channel->rng.initialized)
{
int* sf = channel->ScaleFactors;
const unsigned short seed = (unsigned short)(543 * (sf[8] + sf[12] + sf[15] + 1));
rng_init(&channel->rng, seed);
}
for (int i = 0; i < count; i++)
{
channel->Spectra[i + index] = rng_next(&channel->rng) / 65535.0 * 2.0 - 1.0;
}
}
void rng_init(rng_cxt* rng, unsigned short seed)
{
const int startValue = 0x4D93 * (seed ^ (seed >> 14));
rng->stateA = (unsigned short)(3 - startValue);
rng->stateB = (unsigned short)(2 - startValue);
rng->stateC = (unsigned short)(1 - startValue);
rng->stateD = (unsigned short)(0 - startValue);
rng->initialized = TRUE;
}
unsigned short rng_next(rng_cxt* rng)
{
const unsigned short t = (unsigned short)(rng->stateD ^ (rng->stateD << 5));
rng->stateD = rng->stateC;
rng->stateC = rng->stateB;
rng->stateB = rng->stateA;
rng->stateA = (unsigned short)(t ^ rng->stateA ^ ((t ^ (rng->stateA >> 5)) >> 4));
return rng->stateA;
}

View File

@ -1,13 +0,0 @@
#pragma once
#include "structures.h"
void ApplyBandExtension(block* block);
void ApplyBandExtensionChannel(channel* channel);
void ScaleBexQuantUnits(double* spectra, double* scales, int startUnit, int totalUnits);
void FillHighFrequencies(double* spectra, int groupABin, int groupBBin, int groupCBin, int totalBins);
void AddNoiseToSpectrum(channel* channel, int index, int count);
void rng_init(rng_cxt* rng, unsigned short seed);
unsigned short rng_next(rng_cxt* rng);

View File

@ -1,119 +0,0 @@
#include "bit_allocation.h"
#include "tables.h"
#include "utility.h"
#include <string.h>
at9_status CreateGradient(block* block)
{
int valueCount = block->GradientEndValue - block->GradientStartValue;
int unitCount = block->GradientEndUnit - block->GradientStartUnit;
for (int i = 0; i < block->GradientEndUnit; i++)
{
block->Gradient[i] = block->GradientStartValue;
}
for (int i = block->GradientEndUnit; i <= block->QuantizationUnitCount; i++)
{
block->Gradient[i] = block->GradientEndValue;
}
if (unitCount <= 0) return ERR_SUCCESS;
if (valueCount == 0) return ERR_SUCCESS;
const unsigned char* curve = GradientCurves[unitCount - 1];
if (valueCount <= 0)
{
double scale = (-valueCount - 1) / 31.0;
int baseVal = block->GradientStartValue - 1;
for (int i = block->GradientStartUnit; i < block->GradientEndUnit; i++)
{
block->Gradient[i] = baseVal - (int)(curve[i - block->GradientStartUnit] * scale);
}
}
else
{
double scale = (valueCount - 1) / 31.0;
int baseVal = block->GradientStartValue + 1;
for (int i = block->GradientStartUnit; i < block->GradientEndUnit; i++)
{
block->Gradient[i] = baseVal + (int)(curve[i - block->GradientStartUnit] * scale);
}
}
return ERR_SUCCESS;
}
void CalculateMask(channel* channel)
{
memset(channel->PrecisionMask, 0, sizeof(channel->PrecisionMask));
for (int i = 1; i < channel->Block->QuantizationUnitCount; i++)
{
const int delta = channel->ScaleFactors[i] - channel->ScaleFactors[i - 1];
if (delta > 1)
{
channel->PrecisionMask[i] += min(delta - 1, 5);
}
else if (delta < -1)
{
channel->PrecisionMask[i - 1] += min(delta * -1 - 1, 5);
}
}
}
void CalculatePrecisions(channel* channel)
{
block* block = channel->Block;
if (block->GradientMode != 0)
{
for (int i = 0; i < block->QuantizationUnitCount; i++)
{
channel->Precisions[i] = channel->ScaleFactors[i] + channel->PrecisionMask[i] - block->Gradient[i];
if (channel->Precisions[i] > 0)
{
switch (block->GradientMode)
{
case 1:
channel->Precisions[i] /= 2;
break;
case 2:
channel->Precisions[i] = 3 * channel->Precisions[i] / 8;
break;
case 3:
channel->Precisions[i] /= 4;
break;
}
}
}
}
else
{
for (int i = 0; i < block->QuantizationUnitCount; i++)
{
channel->Precisions[i] = channel->ScaleFactors[i] - block->Gradient[i];
}
}
for (int i = 0; i < block->QuantizationUnitCount; i++)
{
if (channel->Precisions[i] < 1)
{
channel->Precisions[i] = 1;
}
}
for (int i = 0; i < block->GradientBoundary; i++)
{
channel->Precisions[i]++;
}
for (int i = 0; i < block->QuantizationUnitCount; i++)
{
channel->PrecisionsFine[i] = 0;
if (channel->Precisions[i] > 15)
{
channel->PrecisionsFine[i] = channel->Precisions[i] - 15;
channel->Precisions[i] = 15;
}
}
}

View File

@ -1,6 +0,0 @@
#pragma once
#include "unpack.h"
at9_status CreateGradient(block* block);
void CalculateMask(channel* channel);
void CalculatePrecisions(channel* channel);

View File

@ -1,110 +0,0 @@
#include "bit_reader.h"
#include "utility.h"
static int peek_int_fallback(bit_reader_cxt* br, int bit_count);
void init_bit_reader_cxt(bit_reader_cxt* br, const void * buffer)
{
br->buffer = buffer;
br->position = 0;
}
int read_int(bit_reader_cxt* br, const int bits)
{
const int value = peek_int(br, bits);
br->position += bits;
return value;
}
int read_signed_int(bit_reader_cxt* br, const int bits)
{
const int value = peek_int(br, bits);
br->position += bits;
return SignExtend32(value, bits);
}
int read_offset_binary(bit_reader_cxt* br, const int bits)
{
const int offset = 1 << (bits - 1);
const int value = peek_int(br, bits) - offset;
br->position += bits;
return value;
}
int peek_int(bit_reader_cxt* br, const int bits)
{
const int byte_index = br->position / 8;
const int bit_index = br->position % 8;
const unsigned char* buffer = br->buffer;
if (bits <= 9)
{
int value = buffer[byte_index] << 8 | buffer[byte_index + 1];
value &= 0xFFFF >> bit_index;
value >>= 16 - bits - bit_index;
return value;
}
if (bits <= 17)
{
int value = buffer[byte_index] << 16 | buffer[byte_index + 1] << 8 | buffer[byte_index + 2];
value &= 0xFFFFFF >> bit_index;
value >>= 24 - bits - bit_index;
return value;
}
if (bits <= 25)
{
int value = buffer[byte_index] << 24
| buffer[byte_index + 1] << 16
| buffer[byte_index + 2] << 8
| buffer[byte_index + 3];
value &= (int)(0xFFFFFFFF >> bit_index);
value >>= 32 - bits - bit_index;
return value;
}
return peek_int_fallback(br, bits);
}
void align_position(bit_reader_cxt* br, const unsigned int multiple)
{
const int position = br->position;
if (position % multiple == 0)
{
return;
}
br->position = position + multiple - position % multiple;
}
static int peek_int_fallback(bit_reader_cxt* br, int bit_count)
{
int value = 0;
int byte_index = br->position / 8;
int bit_index = br->position % 8;
const unsigned char* buffer = br->buffer;
while (bit_count > 0)
{
if (bit_index >= 8)
{
bit_index = 0;
byte_index++;
}
int bits_to_read = bit_count;
if (bits_to_read > 8 - bit_index)
{
bits_to_read = 8 - bit_index;
}
const int mask = 0xFF >> bit_index;
const int current_byte = (mask & buffer[byte_index]) >> (8 - bit_index - bits_to_read);
value = (value << bits_to_read) | current_byte;
bit_index += bits_to_read;
bit_count -= bits_to_read;
}
return value;
}

View File

@ -1,13 +0,0 @@
#pragma once
typedef struct {
const unsigned char * buffer;
int position;
} bit_reader_cxt;
void init_bit_reader_cxt(bit_reader_cxt* br, const void * buffer);
int peek_int(bit_reader_cxt* br, const int bits);
int read_int(bit_reader_cxt* br, const int bits);
int read_signed_int(bit_reader_cxt* br, const int bits);
int read_offset_binary(bit_reader_cxt* br, const int bits);
void align_position(bit_reader_cxt* br, const unsigned int multiple);

View File

@ -1,188 +0,0 @@
#include "bit_reader.h"
#include "decinit.h"
#include "error_codes.h"
#include "structures.h"
#include "tables.h"
#include <string.h>
#include <math.h>
#include "utility.h"
static int BlockTypeToChannelCount(BlockType block_type);
at9_status init_decoder(atrac9_handle* handle, unsigned char* config_data, int wlength)
{
ERROR_CHECK(init_config_data(&handle->config, config_data));
ERROR_CHECK(init_frame(handle));
init_mdct_tables(handle->config.FrameSamplesPower);
init_huffman_codebooks();
handle->wlength = wlength;
handle->initialized = 1;
return ERR_SUCCESS;
}
at9_status init_config_data(ConfigData* config, unsigned char* config_data)
{
memcpy(config->ConfigData, config_data, CONFIG_DATA_SIZE);
ERROR_CHECK(read_config_data(config));
config->FramesPerSuperframe = 1 << config->SuperframeIndex;
config->SuperframeBytes = config->FrameBytes << config->SuperframeIndex;
config->ChannelConfig = ChannelConfigs[config->ChannelConfigIndex];
config->ChannelCount = config->ChannelConfig.ChannelCount;
config->SampleRate = SampleRates[config->SampleRateIndex];
config->HighSampleRate = config->SampleRateIndex > 7;
config->FrameSamplesPower = SamplingRateIndexToFrameSamplesPower[config->SampleRateIndex];
config->FrameSamples = 1 << config->FrameSamplesPower;
config->SuperframeSamples = config->FrameSamples * config->FramesPerSuperframe;
return ERR_SUCCESS;
}
at9_status read_config_data(ConfigData* config)
{
bit_reader_cxt br;
init_bit_reader_cxt(&br, &config->ConfigData);
const int header = read_int(&br, 8);
config->SampleRateIndex = read_int(&br, 4);
config->ChannelConfigIndex = read_int(&br, 3);
const int validation_bit = read_int(&br, 1);
config->FrameBytes = read_int(&br, 11) + 1;
config->SuperframeIndex = read_int(&br, 2);
if (header != 0xFE || validation_bit != 0)
{
return ERR_BAD_CONFIG_DATA;
}
return ERR_SUCCESS;
}
at9_status init_frame(atrac9_handle* handle)
{
const int block_count = handle->config.ChannelConfig.BlockCount;
handle->frame.config = &handle->config;
for (int i = 0; i < block_count; i++)
{
ERROR_CHECK(init_block(&handle->frame.Blocks[i], &handle->frame, i));
}
return ERR_SUCCESS;
}
at9_status init_block(block* block, frame* parent_frame, int block_index)
{
block->Frame = parent_frame;
block->BlockIndex = block_index;
block->config = parent_frame->config;
block->BlockType = block->config->ChannelConfig.Types[block_index];
block->ChannelCount = BlockTypeToChannelCount(block->BlockType);
for (int i = 0; i < block->ChannelCount; i++)
{
ERROR_CHECK(init_channel(&block->Channels[i], block, i));
}
return ERR_SUCCESS;
}
at9_status init_channel(channel* channel, block* parent_block, int channel_index)
{
channel->Block = parent_block;
channel->Frame = parent_block->Frame;
channel->config = parent_block->config;
channel->ChannelIndex = channel_index;
channel->mdct.bits = parent_block->config->FrameSamplesPower;
return ERR_SUCCESS;
}
void init_huffman_codebooks()
{
init_huffman_set(HuffmanScaleFactorsUnsigned, sizeof(HuffmanScaleFactorsUnsigned) / sizeof(HuffmanCodebook));
init_huffman_set(HuffmanScaleFactorsSigned, sizeof(HuffmanScaleFactorsSigned) / sizeof(HuffmanCodebook));
init_huffman_set(HuffmanSpectrum, sizeof(HuffmanSpectrum) / sizeof(HuffmanCodebook));
}
void init_huffman_set(const HuffmanCodebook* codebooks, int count)
{
for (int i = 0; i < count; i++)
{
InitHuffmanCodebook(&codebooks[i]);
}
}
void init_mdct_tables(int frameSizePower)
{
for (int i = 0; i < 9; i++)
{
GenerateTrigTables(i);
GenerateShuffleTable(i);
}
GenerateMdctWindow(frameSizePower);
GenerateImdctWindow(frameSizePower);
}
void GenerateTrigTables(int sizeBits)
{
const int size = 1 << sizeBits;
double* sinTab = SinTables[sizeBits];
double* cosTab = CosTables[sizeBits];
for (int i = 0; i < size; i++)
{
const double value = M_PI * (4 * i + 1) / (4 * size);
sinTab[i] = sin(value);
cosTab[i] = cos(value);
}
}
void GenerateShuffleTable(int sizeBits)
{
const int size = 1 << sizeBits;
int* table = ShuffleTables[sizeBits];
for (int i = 0; i < size; i++)
{
table[i] = BitReverse32(i ^ (i / 2), sizeBits);
}
}
void GenerateMdctWindow(int frameSizePower)
{
const int frameSize = 1 << frameSizePower;
double* mdct = MdctWindow[frameSizePower - 6];
for (int i = 0; i < frameSize; i++)
{
mdct[i] = (sin(((i + 0.5) / frameSize - 0.5) * M_PI) + 1.0) * 0.5;
}
}
void GenerateImdctWindow(int frameSizePower)
{
const int frameSize = 1 << frameSizePower;
double* imdct = ImdctWindow[frameSizePower - 6];
double* mdct = MdctWindow[frameSizePower - 6];
for (int i = 0; i < frameSize; i++)
{
imdct[i] = mdct[i] / (mdct[frameSize - 1 - i] * mdct[frameSize - 1 - i] + mdct[i] * mdct[i]);
}
}
static int BlockTypeToChannelCount(BlockType block_type)
{
switch (block_type)
{
case Mono:
return 1;
case Stereo:
return 2;
case LFE:
return 1;
default:
return 0;
}
}

View File

@ -1,19 +0,0 @@
#pragma once
#include "error_codes.h"
#include "structures.h"
#include "huffCodes.h"
at9_status init_decoder(atrac9_handle* handle, unsigned char * config_data, int wlength);
at9_status init_config_data(ConfigData* config, unsigned char * config_data);
at9_status read_config_data(ConfigData* config);
at9_status init_frame(atrac9_handle* handle);
at9_status init_block(block* block, frame* parent_frame, int block_index);
at9_status init_channel(channel* channel, block* parent_block, int channel_index);
void init_huffman_codebooks();
void init_huffman_set(const HuffmanCodebook* codebooks, int count);
void GenerateTrigTables(int sizeBits);
void GenerateShuffleTable(int sizeBits);
void init_mdct_tables(int frameSizePower);
void GenerateMdctWindow(int frameSizePower);
void GenerateImdctWindow(int frameSizePower);

View File

@ -1,114 +0,0 @@
#include <string.h>
#include "decoder.h"
#include "unpack.h"
#include "quantization.h"
#include "tables.h"
#include "imdct.h"
#include <math.h>
#include "utility.h"
#include "band_extension.h"
at9_status Decode(atrac9_handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed)
{
handle->frame.frameNum++;
bit_reader_cxt br;
init_bit_reader_cxt(&br, audio);
ERROR_CHECK(DecodeFrame(&handle->frame, &br));
PcmFloatToShort(&handle->frame, (short*)pcm);
*bytesUsed = br.position / 8;
return ERR_SUCCESS;
}
at9_status DecodeFrame(frame* frame, bit_reader_cxt* br)
{
ERROR_CHECK(UnpackFrame(frame, br));
for (int i = 0; i < frame->config->ChannelConfig.BlockCount; i++)
{
block* block = &frame->Blocks[i];
DequantizeSpectra(block);
ApplyIntensityStereo(block);
ScaleSpectrumBlock(block);
ApplyBandExtension(block);
ImdctBlock(block);
}
return ERR_SUCCESS;
}
void PcmFloatToShort(frame* frame, short* pcmOut)
{
const int endSample = frame->config->FrameSamples;
short* dest = pcmOut;
for (int d = 0, s = 0; s < endSample; d++, s++)
{
for (int i = 0; i < frame->config->ChannelConfig.BlockCount; i++)
{
block* block = &frame->Blocks[i];
for (int j = 0; j < block->ChannelCount; j++)
{
channel* channel = &block->Channels[j];
double* pcmSrc = channel->Pcm;
const double sample = pcmSrc[d];
const int roundedSample = (int)floor(sample + 0.5);
*dest++ = Clamp16(roundedSample);
}
}
}
}
void ImdctBlock(block* block)
{
for (int i = 0; i < block->ChannelCount; i++)
{
channel* channel = &block->Channels[i];
RunImdct(&channel->mdct, channel->Spectra, channel->Pcm);
}
}
void ApplyIntensityStereo(block* block)
{
if (block->BlockType != Stereo) return;
const int totalUnits = block->QuantizationUnitCount;
const int stereoUnits = block->StereoQuantizationUnit;
if (stereoUnits >= totalUnits) return;
channel* source = &block->Channels[block->PrimaryChannelIndex == 0 ? 0 : 1];
channel* dest = &block->Channels[block->PrimaryChannelIndex == 0 ? 1 : 0];
for (int i = stereoUnits; i < totalUnits; i++)
{
const int sign = block->JointStereoSigns[i];
for (int sb = QuantUnitToCoeffIndex[i]; sb < QuantUnitToCoeffIndex[i + 1]; sb++)
{
if (sign > 0)
{
dest->Spectra[sb] = -source->Spectra[sb];
}
else
{
dest->Spectra[sb] = source->Spectra[sb];
}
}
}
}
int GetCodecInfo(atrac9_handle* handle, CodecInfo * pCodecInfo)
{
pCodecInfo->channels = handle->config.ChannelCount;
pCodecInfo->channelConfigIndex = handle->config.ChannelConfigIndex;
pCodecInfo->samplingRate = handle->config.SampleRate;
pCodecInfo->superframeSize = handle->config.SuperframeBytes;
pCodecInfo->framesInSuperframe = handle->config.FramesPerSuperframe;
pCodecInfo->frameSamples = handle->config.FrameSamples;
pCodecInfo->wlength = handle->wlength;
memcpy(pCodecInfo->configData, handle->config.ConfigData, CONFIG_DATA_SIZE);
return ERR_SUCCESS;
}

View File

@ -1,11 +0,0 @@
#pragma once
#include "bit_reader.h"
#include "error_codes.h"
#include "structures.h"
at9_status Decode(atrac9_handle* handle, const unsigned char* audio, unsigned char* pcm, int* bytesUsed);
at9_status DecodeFrame(frame* frame, bit_reader_cxt* br);
void ImdctBlock(block* block);
void ApplyIntensityStereo(block* block);
void PcmFloatToShort(frame* frame, short* pcmOut);
int GetCodecInfo(atrac9_handle* handle, CodecInfo* pCodecInfo);

View File

@ -1,33 +0,0 @@
#pragma once
typedef enum at9_status
{
ERR_SUCCESS = 0,
ERR_NOT_IMPLEMENTED = 0x80000000,
ERR_BAD_CONFIG_DATA = 0x81000000,
ERR_UNPACK_SUPERFRAME_FLAG_INVALID = 0x82000000,
ERR_UNPACK_REUSE_BAND_PARAMS_INVALID,
ERR_UNPACK_BAND_PARAMS_INVALID,
ERR_UNPACK_GRAD_BOUNDARY_INVALID = 0x82100000,
ERR_UNPACK_GRAD_START_UNIT_OOB,
ERR_UNPACK_GRAD_END_UNIT_OOB,
ERR_UNPACK_GRAD_START_VALUE_OOB,
ERR_UNPACK_GRAD_END_VALUE_OOB,
ERR_UNPACK_GRAD_END_UNIT_INVALID, // start_unit > end_unit
ERR_UNPACK_SCALE_FACTOR_MODE_INVALID,
ERR_UNPACK_SCALE_FACTOR_OOB,
ERR_UNPACK_EXTENSION_DATA_INVALID
} at9_status;
#define ERROR_CHECK(x) do { \
at9_status status = (x); \
if (status != ERR_SUCCESS) { \
return status; \
} \
} while (0)

View File

@ -1,152 +0,0 @@
#include "huffCodes.h"
#include "utility.h"
int ReadHuffmanValue(const HuffmanCodebook* huff, bit_reader_cxt* br, int is_signed)
{
const int code = peek_int(br, huff->MaxBitSize);
const unsigned char value = huff->Lookup[code];
const int bits = huff->Bits[value];
br->position += bits;
return is_signed ? SignExtend32(value, huff->ValueBits) : value;
}
void DecodeHuffmanValues(int* spectrum, int index, int bandCount, const HuffmanCodebook* huff, const int* values)
{
const int valueCount = bandCount >> huff->ValueCountPower;
const int mask = (1 << huff->ValueBits) - 1;
for (int i = 0; i < valueCount; i++)
{
int value = values[i];
for (int j = 0; j < huff->ValueCount; j++)
{
spectrum[index++] = SignExtend32(value & mask, huff->ValueBits);
value >>= huff->ValueBits;
}
}
}
void InitHuffmanCodebook(const HuffmanCodebook* codebook)
{
const int huffLength = codebook->Length;
if (huffLength == 0) return;
unsigned char* dest = codebook->Lookup;
for (int i = 0; i < huffLength; i++)
{
if (codebook->Bits[i] == 0) continue;
const int unusedBits = codebook->MaxBitSize - codebook->Bits[i];
const int start = codebook->Codes[i] << unusedBits;
const int length = 1 << unusedBits;
const int end = start + length;
for (int j = start; j < end; j++)
{
dest[j] = i;
}
}
}
HuffmanCodebook HuffmanScaleFactorsUnsigned[7] = {
{0},
{ScaleFactorsA1Bits, ScaleFactorsA1Codes, ScaleFactorsA1Lookup, 2, 1, 0, 1, 2, 1},
{ScaleFactorsA2Bits, ScaleFactorsA2Codes, ScaleFactorsA2Lookup, 4, 1, 0, 2, 4, 3},
{ScaleFactorsA3Bits, ScaleFactorsA3Codes, ScaleFactorsA3Lookup, 8, 1, 0, 3, 8, 6},
{ScaleFactorsA4Bits, ScaleFactorsA4Codes, ScaleFactorsA4Lookup, 16, 1, 0, 4, 16, 8},
{ScaleFactorsA5Bits, ScaleFactorsA5Codes, ScaleFactorsA5Lookup, 32, 1, 0, 5, 32, 8},
{ScaleFactorsA6Bits, ScaleFactorsA6Codes, ScaleFactorsA6Lookup, 64, 1, 0, 6, 64, 8},
};
HuffmanCodebook HuffmanScaleFactorsSigned[6] = {
{0},
{0},
{ScaleFactorsB2Bits, ScaleFactorsB2Codes, ScaleFactorsB2Lookup, 4, 1, 0, 2, 4, 2},
{ScaleFactorsB3Bits, ScaleFactorsB3Codes, ScaleFactorsB3Lookup, 8, 1, 0, 3, 8, 6},
{ScaleFactorsB4Bits, ScaleFactorsB4Codes, ScaleFactorsB4Lookup, 16, 1, 0, 4, 16, 8},
{ScaleFactorsB5Bits, ScaleFactorsB5Codes, ScaleFactorsB5Lookup, 32, 1, 0, 5, 32, 8},
};
HuffmanCodebook HuffmanSpectrum[2][8][4] = {
{
{0},
{0},
{
{SpectrumA21Bits, SpectrumA21Codes, SpectrumA21Lookup, 16, 2, 1, 2, 4, 3},
{SpectrumA22Bits, SpectrumA22Codes, SpectrumA22Lookup, 256, 4, 2, 2, 4, 8},
{SpectrumA23Bits, SpectrumA23Codes, SpectrumA23Lookup, 256, 4, 2, 2, 4, 9},
{SpectrumA24Bits, SpectrumA24Codes, SpectrumA24Lookup, 256, 4, 2, 2, 4, 10}
},
{
{SpectrumA31Bits, SpectrumA31Codes, SpectrumA31Lookup, 64, 2, 1, 3, 8, 7},
{SpectrumA32Bits, SpectrumA32Codes, SpectrumA32Lookup, 64, 2, 1, 3, 8, 7},
{SpectrumA33Bits, SpectrumA33Codes, SpectrumA33Lookup, 64, 2, 1, 3, 8, 8},
{SpectrumA34Bits, SpectrumA34Codes, SpectrumA34Lookup, 64, 2, 1, 3, 8, 10}
},
{
{SpectrumA41Bits, SpectrumA41Codes, SpectrumA41Lookup, 256, 2, 1, 4, 16, 9},
{SpectrumA42Bits, SpectrumA42Codes, SpectrumA42Lookup, 256, 2, 1, 4, 16, 10},
{SpectrumA43Bits, SpectrumA43Codes, SpectrumA43Lookup, 256, 2, 1, 4, 16, 10},
{SpectrumA44Bits, SpectrumA44Codes, SpectrumA44Lookup, 256, 2, 1, 4, 16, 10}
},
{
{SpectrumA51Bits, SpectrumA51Codes, SpectrumA51Lookup, 32, 1, 0, 5, 32, 6},
{SpectrumA52Bits, SpectrumA52Codes, SpectrumA52Lookup, 32, 1, 0, 5, 32, 6},
{SpectrumA53Bits, SpectrumA53Codes, SpectrumA53Lookup, 32, 1, 0, 5, 32, 7},
{SpectrumA54Bits, SpectrumA54Codes, SpectrumA54Lookup, 32, 1, 0, 5, 32, 8}
},
{
{SpectrumA61Bits, SpectrumA61Codes, SpectrumA61Lookup, 64, 1, 0, 6, 64, 7},
{SpectrumA62Bits, SpectrumA62Codes, SpectrumA62Lookup, 64, 1, 0, 6, 64, 7},
{SpectrumA63Bits, SpectrumA63Codes, SpectrumA63Lookup, 64, 1, 0, 6, 64, 8},
{SpectrumA64Bits, SpectrumA64Codes, SpectrumA64Lookup, 64, 1, 0, 6, 64, 9}
},
{
{SpectrumA71Bits, SpectrumA71Codes, SpectrumA71Lookup, 128, 1, 0, 7, 128, 8},
{SpectrumA72Bits, SpectrumA72Codes, SpectrumA72Lookup, 128, 1, 0, 7, 128, 8},
{SpectrumA73Bits, SpectrumA73Codes, SpectrumA73Lookup, 128, 1, 0, 7, 128, 9},
{SpectrumA74Bits, SpectrumA74Codes, SpectrumA74Lookup, 128, 1, 0, 7, 128, 10}
}
},
{
{0},
{0},
{
{0},
{SpectrumB22Bits, SpectrumB22Codes, SpectrumB22Lookup, 256, 4, 2, 2, 4, 10},
{SpectrumB23Bits, SpectrumB23Codes, SpectrumB23Lookup, 256, 4, 2, 2, 4, 10},
{SpectrumB24Bits, SpectrumB24Codes, SpectrumB24Lookup, 256, 4, 2, 2, 4, 10}
},
{
{0},
{SpectrumB32Bits, SpectrumB32Codes, SpectrumB32Lookup, 64, 2, 1, 3, 8, 9},
{SpectrumB33Bits, SpectrumB33Codes, SpectrumB33Lookup, 64, 2, 1, 3, 8, 10},
{SpectrumB34Bits, SpectrumB34Codes, SpectrumB34Lookup, 64, 2, 1, 3, 8, 10}
},
{
{0},
{SpectrumB42Bits, SpectrumB42Codes, SpectrumB42Lookup, 256, 2, 1, 4, 16, 10},
{SpectrumB43Bits, SpectrumB43Codes, SpectrumB43Lookup, 256, 2, 1, 4, 16, 10},
{SpectrumB44Bits, SpectrumB44Codes, SpectrumB44Lookup, 256, 2, 1, 4, 16, 10}
},
{
{0},
{SpectrumB52Bits, SpectrumB52Codes, SpectrumB52Lookup, 32, 1, 0, 5, 32, 7},
{SpectrumB53Bits, SpectrumB53Codes, SpectrumB53Lookup, 32, 1, 0, 5, 32, 8},
{SpectrumB54Bits, SpectrumB54Codes, SpectrumB54Lookup, 32, 1, 0, 5, 32, 9}
},
{
{0},
{SpectrumB62Bits, SpectrumB62Codes, SpectrumB62Lookup, 64, 1, 0, 6, 64, 8},
{SpectrumB63Bits, SpectrumB63Codes, SpectrumB63Lookup, 64, 1, 0, 6, 64, 9},
{SpectrumB64Bits, SpectrumB64Codes, SpectrumB64Lookup, 64, 1, 0, 6, 64, 10}
},
{
{0},
{SpectrumB72Bits, SpectrumB72Codes, SpectrumB72Lookup, 128, 1, 0, 7, 128, 9},
{SpectrumB73Bits, SpectrumB73Codes, SpectrumB73Lookup, 128, 1, 0, 7, 128, 10},
{SpectrumB74Bits, SpectrumB74Codes, SpectrumB74Lookup, 128, 1, 0, 7, 128, 10}
}
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,80 +0,0 @@
#include "imdct.h"
#include "tables.h"
void RunImdct(mdct* mdct, double* input, double* output)
{
const int size = 1 << mdct->bits;
const int half = size / 2;
double dctOut[MAX_FRAME_SAMPLES];
const double* window = ImdctWindow[mdct->bits - 6];
double* previous = mdct->_imdctPrevious;
Dct4(mdct, input, dctOut);
for (int i = 0; i < half; i++)
{
output[i] = window[i] * dctOut[i + half] + previous[i];
output[i + half] = window[i + half] * -dctOut[size - 1 - i] - previous[i + half];
previous[i] = window[size - 1 - i] * -dctOut[half - i - 1];
previous[i + half] = window[half - i - 1] * dctOut[i];
}
}
void Dct4(mdct* mdct, double* input, double* output)
{
int MdctBits = mdct->bits;
int MdctSize = 1 << MdctBits;
const int* shuffleTable = ShuffleTables[MdctBits];
const double* sinTable = SinTables[MdctBits];
const double* cosTable = CosTables[MdctBits];
double dctTemp[MAX_FRAME_SAMPLES];
int size = MdctSize;
int lastIndex = size - 1;
int halfSize = size / 2;
for (int i = 0; i < halfSize; i++)
{
int i2 = i * 2;
double a = input[i2];
double b = input[lastIndex - i2];
double sin = sinTable[i];
double cos = cosTable[i];
dctTemp[i2] = a * cos + b * sin;
dctTemp[i2 + 1] = a * sin - b * cos;
}
int stageCount = MdctBits - 1;
for (int stage = 0; stage < stageCount; stage++)
{
int blockCount = 1 << stage;
int blockSizeBits = stageCount - stage;
int blockHalfSizeBits = blockSizeBits - 1;
int blockSize = 1 << blockSizeBits;
int blockHalfSize = 1 << blockHalfSizeBits;
sinTable = SinTables[blockHalfSizeBits];
cosTable = CosTables[blockHalfSizeBits];
for (int block = 0; block < blockCount; block++)
{
for (int i = 0; i < blockHalfSize; i++)
{
int frontPos = (block * blockSize + i) * 2;
int backPos = frontPos + blockSize;
double a = dctTemp[frontPos] - dctTemp[backPos];
double b = dctTemp[frontPos + 1] - dctTemp[backPos + 1];
double sin = sinTable[i];
double cos = cosTable[i];
dctTemp[frontPos] += dctTemp[backPos];
dctTemp[frontPos + 1] += dctTemp[backPos + 1];
dctTemp[backPos] = a * cos + b * sin;
dctTemp[backPos + 1] = a * sin - b * cos;
}
}
}
for (int i = 0; i < MdctSize; i++)
{
output[i] = dctTemp[shuffleTable[i]];
}
}

View File

@ -1,6 +0,0 @@
#pragma once
#include "structures.h"
void RunImdct(mdct* mdct, double* input, double* output);
void Dct4(mdct* mdct, double* input, double* output);

View File

@ -1,33 +0,0 @@
#include "libatrac9.h"
#include "structures.h"
#include <stdlib.h>
#include <string.h>
#include "decinit.h"
#include "decoder.h"
void* Atrac9GetHandle()
{
struct atrac9_handle* handle = malloc(sizeof(atrac9_handle));
memset(handle, 0, sizeof(atrac9_handle));
return handle;
}
void Atrac9ReleaseHandle(void* handle)
{
free(handle);
}
int Atrac9InitDecoder(void* handle, unsigned char * pConfigData)
{
return init_decoder(handle, pConfigData, 16);
}
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed)
{
return Decode(handle, pAtrac9Buffer, (unsigned char*)pPcmBuffer, pNBytesUsed);
}
int Atrac9GetCodecInfo(void* handle, Atrac9CodecInfo * pCodecInfo)
{
return GetCodecInfo(handle, (CodecInfo*)pCodecInfo);
}

View File

@ -1,32 +0,0 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define ATRAC9_CONFIG_DATA_SIZE 4
typedef struct {
int channels;
int channelConfigIndex;
int samplingRate;
int superframeSize;
int framesInSuperframe;
int frameSamples;
int wlength;
unsigned char configData[ATRAC9_CONFIG_DATA_SIZE];
double MdctWindow[3][256];
double ImdctWindow[3][256];
} Atrac9CodecInfo;
void* Atrac9GetHandle(void);
void Atrac9ReleaseHandle(void* handle);
int Atrac9InitDecoder(void* handle, unsigned char *pConfigData);
int Atrac9Decode(void* handle, const unsigned char *pAtrac9Buffer, short *pPcmBuffer, int *pNBytesUsed);
int Atrac9GetCodecInfo(void* handle, Atrac9CodecInfo *pCodecInfo);
#ifdef __cplusplus
}
#endif

View File

@ -1,31 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libatrac9", "libatrac9.vcxproj", "{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Debug|x64.ActiveCfg = Debug|x64
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Debug|x64.Build.0 = Debug|x64
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Debug|x86.ActiveCfg = Debug|Win32
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Debug|x86.Build.0 = Debug|Win32
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Release|x64.ActiveCfg = Release|x64
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Release|x64.Build.0 = Release|x64
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Release|x86.ActiveCfg = Release|Win32
{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB003D83-77D8-4E7B-896D-7C9ADA458F73}
EndGlobalSection
EndGlobal

View File

@ -1,162 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{2425F2CC-BB1B-4069-BC10-1C7F535EF8E8}</ProjectGuid>
<RootNamespace>libatrac9</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
<ProjectName>libatrac9</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_WINDLL;COMPILING_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<CompileAs>CompileAsC</CompileAs>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
<PreprocessorDefinitions>_WINDLL;COMPILING_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
<PreprocessorDefinitions>_WINDLL;COMPILING_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Sync</ExceptionHandling>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<CompileAs>CompileAsC</CompileAs>
<PreprocessorDefinitions>_WINDLL;COMPILING_DLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="band_extension.h" />
<ClInclude Include="bit_allocation.h" />
<ClInclude Include="bit_reader.h" />
<ClInclude Include="decinit.h" />
<ClInclude Include="decoder.h" />
<ClInclude Include="error_codes.h" />
<ClInclude Include="huffCodes.h" />
<ClInclude Include="imdct.h" />
<ClInclude Include="libatrac9.h" />
<ClInclude Include="quantization.h" />
<ClInclude Include="scale_factors.h" />
<ClInclude Include="structures.h" />
<ClInclude Include="tables.h" />
<ClInclude Include="unpack.h" />
<ClInclude Include="utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="band_extension.c" />
<ClCompile Include="bit_allocation.c" />
<ClCompile Include="bit_reader.c" />
<ClCompile Include="decinit.c" />
<ClCompile Include="decoder.c" />
<ClCompile Include="huffCodes.c" />
<ClCompile Include="imdct.c" />
<ClCompile Include="libatrac9.c" />
<ClCompile Include="quantization.c" />
<ClCompile Include="scale_factors.c" />
<ClCompile Include="tables.c" />
<ClCompile Include="unpack.c" />
<ClCompile Include="utility.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="libatrac9.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bit_allocation.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="bit_reader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="decinit.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="decoder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="error_codes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="huffCodes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="imdct.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="quantization.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scale_factors.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="structures.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="tables.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="unpack.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="utility.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="band_extension.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="libatrac9.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bit_allocation.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="bit_reader.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decinit.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="decoder.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="huffCodes.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="imdct.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="quantization.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scale_factors.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="unpack.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="utility.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="band_extension.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="tables.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,54 +0,0 @@
#include "quantization.h"
#include <string.h>
#include "tables.h"
void DequantizeSpectra(block* block)
{
for (int i = 0; i < block->ChannelCount; i++)
{
channel* channel = &block->Channels[i];
memset(channel->Spectra, 0, sizeof(channel->Spectra));
for (int j = 0; j < channel->CodedQuantUnits; j++)
{
DequantizeQuantUnit(channel, j);
}
}
}
void DequantizeQuantUnit(channel* channel, int band)
{
const int subBandIndex = QuantUnitToCoeffIndex[band];
const int subBandCount = QuantUnitToCoeffCount[band];
const double stepSize = QuantizerStepSize[channel->Precisions[band]];
const double stepSizeFine = QuantizerFineStepSize[channel->PrecisionsFine[band]];
for (int sb = 0; sb < subBandCount; sb++)
{
const double coarse = channel->QuantizedSpectra[subBandIndex + sb] * stepSize;
const double fine = channel->QuantizedSpectraFine[subBandIndex + sb] * stepSizeFine;
channel->Spectra[subBandIndex + sb] = coarse + fine;
}
}
void ScaleSpectrumBlock(block* block)
{
for (int i = 0; i < block->ChannelCount; i++)
{
ScaleSpectrumChannel(&block->Channels[i]);
}
}
void ScaleSpectrumChannel(channel* channel)
{
const int quantUnitCount = channel->Block->QuantizationUnitCount;
double* spectra = channel->Spectra;
for (int i = 0; i < quantUnitCount; i++)
{
for (int sb = QuantUnitToCoeffIndex[i]; sb < QuantUnitToCoeffIndex[i + 1]; sb++)
{
spectra[sb] *= SpectrumScale[channel->ScaleFactors[i]];
}
}
}

View File

@ -1,8 +0,0 @@
#pragma once
#include "structures.h"
void DequantizeSpectra(block* block);
void DequantizeQuantUnit(channel* channel, int band);
void ScaleSpectrumBlock(block* block);
void ScaleSpectrumChannel(channel* channel);

View File

@ -1,146 +0,0 @@
#include <string.h>
#include "huffCodes.h"
#include "scale_factors.h"
#include "tables.h"
#include "utility.h"
at9_status read_scale_factors(channel * channel, bit_reader_cxt * br)
{
memset(channel->ScaleFactors, 0, sizeof(channel->ScaleFactors));
channel->ScaleFactorCodingMode = read_int(br, 2);
if (channel->ChannelIndex == 0)
{
switch (channel->ScaleFactorCodingMode)
{
case 0:
ReadVlcDeltaOffset(channel, br);
break;
case 1:
ReadClcOffset(channel, br);
break;
case 2:
if (channel->Block->FirstInSuperframe) return ERR_UNPACK_SCALE_FACTOR_MODE_INVALID;
ReadVlcDistanceToBaseline(channel, br, channel->ScaleFactorsPrev, channel->Block->QuantizationUnitsPrev);
break;
case 3:
if (channel->Block->FirstInSuperframe) return ERR_UNPACK_SCALE_FACTOR_MODE_INVALID;
ReadVlcDeltaOffsetWithBaseline(channel, br, channel->ScaleFactorsPrev, channel->Block->QuantizationUnitsPrev);
break;
}
}
else
{
switch (channel->ScaleFactorCodingMode)
{
case 0:
ReadVlcDeltaOffset(channel, br);
break;
case 1:
ReadVlcDistanceToBaseline(channel, br, channel->Block->Channels[0].ScaleFactors, channel->Block->ExtensionUnit);
break;
case 2:
ReadVlcDeltaOffsetWithBaseline(channel, br, channel->Block->Channels[0].ScaleFactors, channel->Block->ExtensionUnit);
break;
case 3:
if (channel->Block->FirstInSuperframe) return ERR_UNPACK_SCALE_FACTOR_MODE_INVALID;
ReadVlcDistanceToBaseline(channel, br, channel->ScaleFactorsPrev, channel->Block->QuantizationUnitsPrev);
break;
}
}
for (int i = 0; i < channel->Block->ExtensionUnit; i++)
{
if (channel->ScaleFactors[i] < 0 || channel->ScaleFactors[i] > 31)
{
return ERR_UNPACK_SCALE_FACTOR_OOB;
}
}
memcpy(channel->ScaleFactorsPrev, channel->ScaleFactors, sizeof(channel->ScaleFactors));
return ERR_SUCCESS;
}
void ReadClcOffset(channel* channel, bit_reader_cxt* br)
{
const int maxBits = 5;
int* sf = channel->ScaleFactors;
const int bitLength = read_int(br, 2) + 2;
const int baseValue = bitLength < maxBits ? read_int(br, maxBits) : 0;
for (int i = 0; i < channel->Block->ExtensionUnit; i++)
{
sf[i] = read_int(br, bitLength) + baseValue;
}
}
void ReadVlcDeltaOffset(channel* channel, bit_reader_cxt* br)
{
const int weightIndex = read_int(br, 3);
const unsigned char* weights = ScaleFactorWeights[weightIndex];
int* sf = channel->ScaleFactors;
const int baseValue = read_int(br, 5);
const int bitLength = read_int(br, 2) + 3;
const HuffmanCodebook* codebook = &HuffmanScaleFactorsUnsigned[bitLength];
sf[0] = read_int(br, bitLength);
for (int i = 1; i < channel->Block->ExtensionUnit; i++)
{
const int delta = ReadHuffmanValue(codebook, br, 0);
sf[i] = (sf[i - 1] + delta) & (codebook->ValueMax - 1);
}
for (int i = 0; i < channel->Block->ExtensionUnit; i++)
{
sf[i] += baseValue - weights[i];
}
}
void ReadVlcDistanceToBaseline(channel* channel, bit_reader_cxt* br, int* baseline, int baselineLength)
{
int* sf = channel->ScaleFactors;
const int bit_length = read_int(br, 2) + 2;
const HuffmanCodebook* codebook = &HuffmanScaleFactorsSigned[bit_length];
const int unitCount = min(channel->Block->ExtensionUnit, baselineLength);
for (int i = 0; i < unitCount; i++)
{
const int distance = ReadHuffmanValue(codebook, br, TRUE);
sf[i] = (baseline[i] + distance) & 31;
}
for (int i = unitCount; i < channel->Block->ExtensionUnit; i++)
{
sf[i] = read_int(br, 5);
}
}
void ReadVlcDeltaOffsetWithBaseline(channel* channel, bit_reader_cxt* br, int* baseline, int baselineLength)
{
int* sf = channel->ScaleFactors;
const int baseValue = read_offset_binary(br, 5);
const int bitLength = read_int(br, 2) + 1;
const HuffmanCodebook* codebook = &HuffmanScaleFactorsUnsigned[bitLength];
const int unitCount = min(channel->Block->ExtensionUnit, baselineLength);
sf[0] = read_int(br, bitLength);
for (int i = 1; i < unitCount; i++)
{
const int delta = ReadHuffmanValue(codebook, br, FALSE);
sf[i] = (sf[i - 1] + delta) & (codebook->ValueMax - 1);
}
for (int i = 0; i < unitCount; i++)
{
sf[i] += baseValue + baseline[i];
}
for (int i = unitCount; i < channel->Block->ExtensionUnit; i++)
{
sf[i] = read_int(br, 5);
}
}

View File

@ -1,8 +0,0 @@
#pragma once
#include "bit_allocation.h"
at9_status read_scale_factors(channel* channel, bit_reader_cxt* br);
void ReadClcOffset(channel* channel, bit_reader_cxt* br);
void ReadVlcDeltaOffset(channel* channel, bit_reader_cxt* br);
void ReadVlcDistanceToBaseline(channel* channel, bit_reader_cxt* br, int* baseline, int baselineLength);
void ReadVlcDeltaOffsetWithBaseline(channel* channel, bit_reader_cxt* br, int* baseline, int baselineLength);

View File

@ -1,160 +0,0 @@
#pragma once
#define CONFIG_DATA_SIZE 4
#define MAX_BLOCK_COUNT 5
#define MAX_BLOCK_CHANNEL_COUNT 2
#define MAX_FRAME_SAMPLES 256
#define MAX_BEX_VALUES 4
#define MAX_QUANT_UNITS 30
typedef struct frame frame;
typedef struct block block;
typedef enum BlockType {
Mono = 0,
Stereo = 1,
LFE = 2
} BlockType;
typedef struct {
int BlockCount;
int ChannelCount;
enum BlockType Types[MAX_BLOCK_COUNT];
} ChannelConfig;
typedef struct {
unsigned char ConfigData[CONFIG_DATA_SIZE];
int SampleRateIndex;
int ChannelConfigIndex;
int FrameBytes;
int SuperframeIndex;
ChannelConfig ChannelConfig;
int ChannelCount;
int SampleRate;
int HighSampleRate;
int FramesPerSuperframe;
int FrameSamplesPower;
int FrameSamples;
int SuperframeBytes;
int SuperframeSamples;
} ConfigData;
typedef struct {
int initialized;
unsigned short stateA;
unsigned short stateB;
unsigned short stateC;
unsigned short stateD;
} rng_cxt;
typedef struct {
int bits;
int size;
double scale;
double _imdctPrevious[MAX_FRAME_SAMPLES];
double* window;
double* sinTable;
double* cosTable;
} mdct;
typedef struct {
frame* Frame;
block* Block;
ConfigData* config;
int ChannelIndex;
mdct mdct;
double Pcm[MAX_FRAME_SAMPLES];
double Spectra[MAX_FRAME_SAMPLES];
int CodedQuantUnits;
int ScaleFactorCodingMode;
int ScaleFactors[31];
int ScaleFactorsPrev[31];
int Precisions[MAX_QUANT_UNITS];
int PrecisionsFine[MAX_QUANT_UNITS];
int PrecisionMask[MAX_QUANT_UNITS];
int CodebookSet[MAX_QUANT_UNITS];
int QuantizedSpectra[MAX_FRAME_SAMPLES];
int QuantizedSpectraFine[MAX_FRAME_SAMPLES];
int BexMode;
int BexValueCount;
int BexValues[MAX_BEX_VALUES];
rng_cxt rng;
} channel;
struct block {
frame* Frame;
ConfigData* config;
enum BlockType BlockType;
int BlockIndex;
channel Channels[MAX_BLOCK_CHANNEL_COUNT];
int ChannelCount;
int FirstInSuperframe;
int ReuseBandParams;
int BandCount;
int StereoBand;
int ExtensionBand;
int QuantizationUnitCount;
int StereoQuantizationUnit;
int ExtensionUnit;
int QuantizationUnitsPrev;
int Gradient[31];
int GradientMode;
int GradientStartUnit;
int GradientStartValue;
int GradientEndUnit;
int GradientEndValue;
int GradientBoundary;
int PrimaryChannelIndex;
int HasJointStereoSigns;
int JointStereoSigns[MAX_QUANT_UNITS];
int BandExtensionEnabled;
int HasExtensionData;
int BexDataLength;
int BexMode;
};
struct frame {
ConfigData* config;
int FrameIndex;
block Blocks[MAX_BLOCK_COUNT];
int frameNum;
};
typedef struct {
int initialized;
int wlength;
ConfigData config;
frame frame;
} atrac9_handle;
typedef struct {
int group_b_unit;
int group_c_unit;
int band_count;
} bex_group;
typedef struct {
int channels;
int channelConfigIndex;
int samplingRate;
int superframeSize;
int framesInSuperframe;
int frameSamples;
int wlength;
unsigned char configData[CONFIG_DATA_SIZE];
} CodecInfo;

View File

@ -1,7 +0,0 @@
#include "tables.h"
double MdctWindow[3][256];
double ImdctWindow[3][256];
double SinTables[9][256];
double CosTables[9][256];
int ShuffleTables[9][256];

View File

@ -1,389 +0,0 @@
#pragma once
#include "structures.h"
static const ChannelConfig ChannelConfigs[6] =
{
{1, 1, Mono},
{2, 2, Mono, Mono},
{1, 2, Stereo},
{4, 6, Stereo, Mono, LFE, Stereo},
{5, 8, Stereo, Mono, LFE, Stereo, Stereo},
{2, 4, Stereo, Stereo},
};
static const int MaxHuffPrecision[2] = { 7, 1 };
static const int MinBandCount[2] = { 3, 1 };
static const int MaxExtensionBand[2] = { 18, 16 };
static const int SamplingRateIndexToFrameSamplesPower[16] =
{ 6, 6, 7, 7, 7, 8, 8, 8, 6, 6, 7, 7, 7, 8, 8, 8 };
static const int MaxBandCount[16] =
{ 8, 8, 12, 12, 12, 18, 18, 18, 8, 8, 12, 12, 12, 16, 16, 16 };
static const int BandToQuantUnitCount[19] =
{ 0, 4, 8, 10, 12, 13, 14, 15, 16, 18, 20, 21, 22, 23, 24, 25, 26, 28, 30 };
static const int QuantUnitToCoeffCount[30] =
{
2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 8, 8, 8,
8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
};
static const int QuantUnitToCoeffIndex[31] =
{
0, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 72, 80, 88, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256
};
static const int QuantUnitToCodebookIndex[30] =
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
static const int SampleRates[16] =
{
11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
};
static const unsigned char GradientCurves[48][48] = {
{ 1 },
{ 1, 16 },
{ 1, 7, 25 },
{ 1, 4, 16, 27 },
{ 1, 3, 10, 21, 28 },
{ 1, 3, 7, 16, 25, 29 },
{ 1, 2, 5, 11, 20, 26, 29 },
{ 1, 2, 4, 9, 16, 23, 27, 29 },
{ 1, 2, 3, 7, 12, 19, 25, 28, 29 },
{ 1, 2, 3, 5, 10, 16, 21, 26, 28, 29 },
{ 1, 2, 3, 5, 8, 12, 19, 23, 26, 28, 29 },
{ 1, 2, 3, 4, 7, 11, 16, 21, 25, 27, 29, 30 },
{ 1, 1, 2, 4, 5, 9, 13, 18, 22, 26, 27, 29, 30 },
{ 1, 1, 2, 3, 5, 8, 11, 16, 20, 23, 26, 28, 29, 30 },
{ 1, 1, 2, 3, 4, 7, 10, 13, 18, 21, 25, 27, 28, 29, 30 },
{ 1, 1, 2, 3, 4, 6, 9, 12, 16, 20, 23, 26, 27, 28, 29, 30 },
{ 1, 1, 2, 3, 4, 5, 7, 10, 13, 18, 21, 24, 26, 27, 28, 29, 30 },
{ 1, 1, 2, 3, 3, 5, 7, 9, 12, 16, 19, 22, 25, 26, 28, 29, 29, 30 },
{ 1, 1, 2, 2, 3, 4, 6, 8, 11, 13, 18, 20, 23, 25, 27, 28, 29, 29, 30 },
{ 1, 1, 2, 2, 3, 4, 5, 7, 10, 12, 16, 19, 21, 24, 26, 27, 28, 29, 29, 30 },
{ 1, 1, 2, 2, 3, 4, 5, 7, 9, 11, 13, 18, 20, 22, 25, 26, 27, 28, 29, 29, 30 },
{ 1, 1, 2, 2, 3, 3, 5, 6, 8, 10, 12, 16, 19, 21, 23, 25, 26, 28, 28, 29, 29,
30 },
{ 1, 1, 2, 2, 3, 3, 4, 5, 7, 9, 11, 13, 18, 20, 22, 24, 26, 27, 28, 28, 29,
29, 30 },
{ 1, 1, 2, 2, 3, 3, 4, 5, 7, 9, 11, 13, 16, 19, 21, 23, 25, 26, 27, 28, 29,
29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 15, 16, 19, 21, 23, 25, 26, 27, 28,
29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 4, 4, 5, 7, 9, 11, 13, 16, 18, 20, 22, 24, 26, 27, 27,
28, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 3, 4, 5, 7, 8, 10, 12, 15, 16, 19, 21, 23, 25, 26, 27,
28, 28, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 3, 4, 5, 6, 8, 9, 11, 13, 16, 18, 20, 22, 23, 25, 26, 27,
28, 28, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 3, 4, 5, 5, 7, 9, 10, 12, 15, 16, 19, 21, 22, 24, 26, 26,
27, 28, 28, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 10, 11, 13, 16, 18, 20, 21, 23, 25, 26,
27, 27, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 8, 9, 11, 12, 15, 16, 19, 20, 22, 23, 25,
26, 27, 28, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 12, 13, 16, 18, 20, 21, 23, 24,
26, 26, 27, 28, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 4, 5, 5, 7, 8, 9, 11, 12, 15, 16, 19, 20, 22, 23,
25, 26, 26, 27, 28, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 9, 10, 12, 13, 16, 18, 19, 21, 22,
24, 25, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 16, 19, 20, 21,
23, 24, 25, 26, 27, 28, 28, 28, 29, 29, 29, 30, 30 },
{ 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 7, 8, 9, 11, 12, 13, 16, 18, 19, 21,
22, 23, 25, 26, 26, 27, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 9, 10, 11, 13, 15, 16, 18, 20,
21, 22, 24, 25, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 7, 8, 9, 11, 12, 13, 16, 18, 19, 20,
22, 23, 24, 25, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 7, 8, 9, 10, 11, 13, 15, 16, 18, 20,
21, 22, 23, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 9, 10, 11, 12, 13, 16, 18, 19,
20, 21, 23, 24, 25, 26, 26, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 8, 9, 10, 12, 13, 15, 16, 18,
19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 7, 8, 9, 10, 11, 12, 13, 16, 18,
19, 20, 21, 22, 23, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 29, 30, 30,
30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16,
18, 19, 20, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 29, 30, 30,
30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 28, 28, 29, 29, 29, 29, 30,
30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 7, 8, 9, 10, 11, 12, 13, 15,
16, 18, 19, 20, 21, 22, 23, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 29,
30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13,
16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29,
29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13,
15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29,
29, 29, 30, 30, 30 },
{ 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13,
15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29,
29, 29, 30, 30, 30, 30 }
};
static const unsigned char ScaleFactorWeights[8][32] = {
{ 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 6, 6,
7, 7, 8, 10, 12, 12, 12 },
{ 3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 2, 3,
3, 4, 5, 7, 10, 10, 10 },
{ 0, 2, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 8, 9, 12, 12, 12 },
{ 0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 8, 8, 10,
11, 11, 12, 13, 13, 13, 13 },
{ 0, 2, 2, 3, 3, 4, 4, 5, 4, 5, 5, 5, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10,
11, 12, 12, 13, 13, 14, 14, 14 },
{ 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5,
6, 7, 7, 9, 11, 11, 11 },
{ 0, 5, 8, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 12, 12, 12, 12, 13, 15, 15, 15 },
{ 0, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11,
11, 12, 12, 12, 12, 13, 13, 15, 15, 15 }
};
static const double SpectrumScale[32] =
{
3.0517578125e-5, 6.1035156250e-5, 1.2207031250e-4, 2.4414062500e-4,
4.8828125000e-4, 9.7656250000e-4, 1.9531250000e-3, 3.9062500000e-3,
7.8125000000e-3, 1.5625000000e-2, 3.1250000000e-2, 6.2500000000e-2,
1.2500000000e-1, 2.5000000000e-1, 5.0000000000e-1, 1.0000000000e+0,
2.0000000000e+0, 4.0000000000e+0, 8.0000000000e+0, 1.6000000000e+1,
3.2000000000e+1, 6.4000000000e+1, 1.2800000000e+2, 2.5600000000e+2,
5.1200000000e+2, 1.0240000000e+3, 2.0480000000e+3, 4.0960000000e+3,
8.1920000000e+3, 1.6384000000e+4, 3.2768000000e+4, 6.5536000000e+4
};
static const double QuantizerInverseStepSize[16] =
{
0.5, 1.5, 3.5, 7.5, 15.5, 31.5, 63.5, 127.5,
255.5, 511.5, 1023.5, 2047.5, 4095.5, 8191.5, 16383.5, 32767.5
};
static const double QuantizerStepSize[16] =
{
2.0000000000000000e+0, 6.6666666666666663e-1, 2.8571428571428570e-1, 1.3333333333333333e-1,
6.4516129032258063e-2, 3.1746031746031744e-2, 1.5748031496062992e-2, 7.8431372549019607e-3,
3.9138943248532287e-3, 1.9550342130987292e-3, 9.7703957010258913e-4, 4.8840048840048840e-4,
2.4417043096081065e-4, 1.2207776353537203e-4, 6.1037018951994385e-5, 3.0518043793392844e-5
};
static const double QuantizerFineStepSize[16] =
{
3.0518043793392844e-05, 1.0172681264464281e-05, 4.3597205419132631e-06, 2.0345362528928561e-06,
9.8445302559331759e-07, 4.8441339354591809e-07, 2.4029955742829012e-07, 1.1967860311134448e-07,
5.9722199204291275e-08, 2.9831909866464167e-08, 1.4908668194134265e-08, 7.4525137468602791e-09,
3.7258019525568114e-09, 1.8627872668859698e-09, 9.3136520869755679e-10, 4.6567549848772173e-10
};
static const bex_group BexGroupInfo[8] =
{
{ 16, 21, 0 },
{ 18, 22, 1 },
{ 20, 22, 2 },
{ 21, 22, 3 },
{ 21, 22, 3 },
{ 23, 24, 4 },
{ 23, 24, 4 },
{ 24, 24, 5 }
};
static const int BexEncodedValueCounts[5][6] =
{
{0, 0, 0, 4, 4, 2},
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 2, 2, 1},
{0, 0, 0, 2, 2, 2},
{1, 1, 1, 0, 0, 0}
};
// [mode][bands][valueIndex]
static const int BexDataLengths[5][6][4] =
{
{
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{5, 4, 3, 3},
{4, 4, 3, 4},
{4, 5, 0, 0}
}, {
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}, {
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{6, 6, 0, 0},
{6, 6, 0, 0},
{6, 0, 0, 0}
}, {
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{4, 4, 0, 0},
{4, 4, 0, 0},
{4, 4, 0, 0}
}, {
{3, 0, 0, 0},
{3, 0, 0, 0},
{3, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
}
};
static const double BexMode0Bands3[5][32] =
{
{
0.000000e+0, 1.988220e-1, 2.514343e-1, 2.960510e-1,
3.263550e-1, 3.771362e-1, 3.786926e-1, 4.540405e-1,
4.877625e-1, 5.262451e-1, 5.447083e-1, 5.737000e-1,
6.212158e-1, 6.222839e-1, 6.560974e-1, 6.896667e-1,
7.555542e-1, 7.677917e-1, 7.918091e-1, 7.971497e-1,
8.188171e-1, 8.446045e-1, 9.790649e-1, 9.822083e-1,
9.846191e-1, 9.859314e-1, 9.863586e-1, 9.863892e-1,
9.873352e-1, 9.881287e-1, 9.898682e-1, 9.913330e-1
}, {
0.000000e+0, 9.982910e-1, 7.592773e-2, 7.179565e-1,
9.851379e-1, 5.340271e-1, 9.013672e-1, 6.349182e-1,
7.226257e-1, 1.948547e-1, 7.628174e-1, 9.873657e-1,
8.112183e-1, 2.715454e-1, 9.734192e-1, 1.443787e-1,
4.640198e-1, 3.249207e-1, 3.790894e-1, 8.276367e-2,
5.954590e-1, 2.864380e-1, 9.806824e-1, 7.929077e-1,
6.292114e-1, 4.887085e-1, 2.905273e-1, 1.301880e-1,
3.140869e-1, 5.482483e-1, 4.210815e-1, 1.182861e-1
}, {
0.000000e+0, 3.155518e-2, 8.581543e-2, 1.364746e-1,
1.858826e-1, 2.368469e-1, 2.888184e-1, 3.432617e-1,
4.012451e-1, 4.623108e-1, 5.271301e-1, 5.954895e-1,
6.681213e-1, 7.448425e-1, 8.245239e-1, 9.097290e-1
}, {
0.000000e+0, 4.418945e-2, 1.303711e-1, 2.273560e-1,
3.395996e-1, 4.735718e-1, 6.267090e-1, 8.003845e-1
}, {
0.000000e+0, 2.804565e-2, 9.683228e-2, 1.849976e-1,
3.005981e-1, 4.470520e-1, 6.168518e-1, 8.007813e-1
}
};
static const double BexMode0Bands4[5][16] =
{
{
0.000000e+0, 2.708740e-1, 3.479614e-1, 3.578186e-1,
5.083618e-1, 5.299072e-1, 5.819092e-1, 6.381836e-1,
7.276917e-1, 7.595520e-1, 7.878723e-1, 9.707336e-1,
9.713135e-1, 9.736023e-1, 9.759827e-1, 9.832458e-1
}, {
0.000000e+0, 2.330627e-1, 5.891418e-1, 7.170410e-1,
2.036438e-1, 1.613464e-1, 6.668701e-1, 9.481201e-1,
9.769897e-1, 5.111694e-1, 3.522644e-1, 8.209534e-1,
2.933960e-1, 9.757690e-1, 5.289917e-1, 4.372253e-1
}, {
0.000000e+0, 4.360962e-2, 1.056519e-1, 1.590576e-1,
2.078857e-1, 2.572937e-1, 3.082581e-1, 3.616028e-1,
4.191589e-1, 4.792175e-1, 5.438538e-1, 6.125183e-1,
6.841125e-1, 7.589417e-1, 8.365173e-1, 9.148254e-1
}, {
0.000000e+0, 4.074097e-2, 1.164551e-1, 2.077026e-1,
3.184509e-1, 4.532166e-1, 6.124268e-1, 7.932129e-1
}, {
0.000000e+0, 8.880615e-3, 2.932739e-2, 5.593872e-2,
8.825684e-2, 1.259155e-1, 1.721497e-1, 2.270813e-1,
2.901611e-1, 3.579712e-1, 4.334106e-1, 5.147095e-1,
6.023254e-1, 6.956177e-1, 7.952881e-1, 8.977356e-1
}
};
static const double BexMode0Bands5[3][32] =
{
{
0.000000e+0, 7.379150e-2, 1.806335e-1, 2.687073e-1,
3.407898e-1, 4.047546e-1, 4.621887e-1, 5.168762e-1,
5.703125e-1, 6.237488e-1, 6.763611e-1, 7.288208e-1,
7.808533e-1, 8.337708e-1, 8.874512e-1, 9.418030e-1
}, {
0.000000e+0, 7.980347e-2, 1.615295e-1, 1.665649e-1,
1.822205e-1, 2.185669e-1, 2.292175e-1, 2.456665e-1,
2.666321e-1, 3.306580e-1, 3.330688e-1, 3.765259e-1,
4.085083e-1, 4.400024e-1, 4.407654e-1, 4.817505e-1,
4.924011e-1, 5.320740e-1, 5.893860e-1, 6.131287e-1,
6.212463e-1, 6.278076e-1, 6.308899e-1, 7.660828e-1,
7.850647e-1, 7.910461e-1, 7.929382e-1, 8.038330e-1,
9.834900e-1, 9.846191e-1, 9.852295e-1, 9.862671e-1
}, {
0.000000e+0, 6.084290e-1, 3.672791e-1, 3.151855e-1,
1.488953e-1, 2.571716e-1, 5.103455e-1, 3.311157e-1,
5.426025e-2, 4.254456e-1, 7.998352e-1, 7.873230e-1,
5.418701e-1, 2.925110e-1, 8.468628e-2, 1.410522e-1,
9.819641e-1, 9.609070e-1, 3.530884e-2, 9.729004e-2,
5.758362e-1, 9.941711e-1, 7.215576e-1, 7.183228e-1,
2.028809e-1, 9.588623e-2, 2.032166e-1, 1.338806e-1,
5.003357e-1, 1.874390e-1, 9.804993e-1, 1.107788e-1
}
};
static const double BexMode2Scale[64] =
{
4.272461e-4, 1.312256e-3, 2.441406e-3, 3.692627e-3,
4.913330e-3, 6.134033e-3, 7.507324e-3, 8.972168e-3,
1.049805e-2, 1.223755e-2, 1.406860e-2, 1.599121e-2,
1.800537e-2, 2.026367e-2, 2.264404e-2, 2.517700e-2,
2.792358e-2, 3.073120e-2, 3.344727e-2, 3.631592e-2,
3.952026e-2, 4.275513e-2, 4.608154e-2, 4.968262e-2,
5.355835e-2, 5.783081e-2, 6.195068e-2, 6.677246e-2,
7.196045e-2, 7.745361e-2, 8.319092e-2, 8.993530e-2,
9.759521e-2, 1.056213e-1, 1.138916e-1, 1.236267e-1,
1.348267e-1, 1.470337e-1, 1.603394e-1, 1.755676e-1,
1.905823e-1, 2.071228e-1, 2.245178e-1, 2.444153e-1,
2.658997e-1, 2.897644e-1, 3.146057e-1, 3.450012e-1,
3.766174e-1, 4.122620e-1, 4.505615e-1, 4.893799e-1,
5.305481e-1, 5.731201e-1, 6.157837e-1, 6.580811e-1,
6.985168e-1, 7.435303e-1, 7.865906e-1, 8.302612e-1,
8.718567e-1, 9.125671e-1, 9.575806e-1, 9.996643e-1
};
static const double BexMode3Initial[16] =
{
3.491211e-1, 5.371094e-1, 6.782227e-1, 7.910156e-1,
9.057617e-1, 1.024902e+0, 1.156250e+0, 1.290527e+0,
1.458984e+0, 1.664551e+0, 1.929688e+0, 2.278320e+0,
2.831543e+0, 3.659180e+0, 5.257813e+0, 8.373047e+0
};
static const double BexMode3Rate[16] =
{
-2.913818e-1, -2.541504e-1, -1.664429e-1, -1.476440e-1,
-1.342163e-1, -1.220703e-1, -1.117554e-1, -1.026611e-1,
-9.436035e-2, -8.483887e-2, -7.476807e-2, -6.304932e-2,
-4.492188e-2, -2.447510e-2, +1.831055e-4, +4.174805e-2
};
static const double BexMode4Multiplier[8] =
{
3.610229e-2, 1.260681e-1, 2.227478e-1, 3.338318e-1,
4.662170e-1, 6.221313e-1, 7.989197e-1, 9.939575e-1
};
extern double MdctWindow[3][256];
extern double ImdctWindow[3][256];
extern double SinTables[9][256];
extern double CosTables[9][256];
extern int ShuffleTables[9][256];

View File

@ -1,423 +0,0 @@
#include "tables.h"
#include "unpack.h"
#include "bit_allocation.h"
#include <string.h>
#include "scale_factors.h"
#include "utility.h"
#include "huffCodes.h"
at9_status UnpackFrame(frame* frame, bit_reader_cxt* br)
{
const int block_count = frame->config->ChannelConfig.BlockCount;
for (int i = 0; i < block_count; i++)
{
ERROR_CHECK(UnpackBlock(&frame->Blocks[i], br));
}
return ERR_SUCCESS;
}
at9_status UnpackBlock(block* block, bit_reader_cxt* br)
{
ERROR_CHECK(ReadBlockHeader(block, br));
if (block->BlockType == LFE)
{
ERROR_CHECK(UnpackLfeBlock(block, br));
}
else
{
ERROR_CHECK(UnpackStandardBlock(block, br));
}
align_position(br, 8);
return ERR_SUCCESS;
}
at9_status ReadBlockHeader(block* block, bit_reader_cxt* br)
{
int firstInSuperframe = block->Frame->FrameIndex == 0;
block->FirstInSuperframe = !read_int(br, 1);
block->ReuseBandParams = read_int(br, 1);
if (block->FirstInSuperframe && block->ReuseBandParams && block->BlockType != LFE)
{
return ERR_UNPACK_REUSE_BAND_PARAMS_INVALID;
}
return ERR_SUCCESS;
}
at9_status UnpackStandardBlock(block* block, bit_reader_cxt* br)
{
if (!block->ReuseBandParams)
{
ERROR_CHECK(ReadBandParams(block, br));
}
ERROR_CHECK(ReadGradientParams(block, br));
ERROR_CHECK(CreateGradient(block));
ERROR_CHECK(ReadStereoParams(block, br));
ERROR_CHECK(ReadExtensionParams(block, br));
for (int i = 0; i < block->ChannelCount; i++)
{
channel* channel = &block->Channels[i];
UpdateCodedUnits(channel);
ERROR_CHECK(read_scale_factors(channel, br));
CalculateMask(channel);
CalculatePrecisions(channel);
CalculateSpectrumCodebookIndex(channel);
ERROR_CHECK(ReadSpectra(channel, br));
ERROR_CHECK(ReadSpectraFine(channel, br));
}
block->QuantizationUnitsPrev = block->BandExtensionEnabled ? block->ExtensionUnit : block->QuantizationUnitCount;
return ERR_SUCCESS;
}
at9_status ReadBandParams(block* block, bit_reader_cxt* br)
{
const int minBandCount = MinBandCount[block->config->HighSampleRate];
const int maxExtensionBand = MaxExtensionBand[block->config->HighSampleRate];
block->BandCount = read_int(br, 4) + minBandCount;
block->QuantizationUnitCount = BandToQuantUnitCount[block->BandCount];
if (block->BandCount < minBandCount || block->BandCount >
MaxBandCount[block->config->SampleRateIndex])
{
return ERR_SUCCESS;
}
if (block->BlockType == Stereo)
{
block->StereoBand = read_int(br, 4);
block->StereoBand += minBandCount;
block->StereoQuantizationUnit = BandToQuantUnitCount[block->StereoBand];
}
else
{
block->StereoBand = block->BandCount;
}
block->BandExtensionEnabled = read_int(br, 1);
if (block->BandExtensionEnabled)
{
block->ExtensionBand = read_int(br, 4);
block->ExtensionBand += minBandCount;
if (block->ExtensionBand < block->BandCount || block->ExtensionBand > maxExtensionBand)
{
return ERR_UNPACK_BAND_PARAMS_INVALID;
}
block->ExtensionUnit = BandToQuantUnitCount[block->ExtensionBand];
}
else
{
block->ExtensionBand = block->BandCount;
block->ExtensionUnit = block->QuantizationUnitCount;
}
return ERR_SUCCESS;
}
at9_status ReadGradientParams(block* block, bit_reader_cxt* br)
{
block->GradientMode = read_int(br, 2);
if (block->GradientMode > 0)
{
block->GradientEndUnit = 31;
block->GradientEndValue = 31;
block->GradientStartUnit = read_int(br, 5);
block->GradientStartValue = read_int(br, 5);
}
else
{
block->GradientStartUnit = read_int(br, 6);
block->GradientEndUnit = read_int(br, 6) + 1;
block->GradientStartValue = read_int(br, 5);
block->GradientEndValue = read_int(br, 5);
}
block->GradientBoundary = read_int(br, 4);
if (block->GradientBoundary > block->QuantizationUnitCount)
{
return ERR_UNPACK_GRAD_BOUNDARY_INVALID;
}
if (block->GradientStartUnit < 1 || block->GradientStartUnit >= 48)
{
return ERR_UNPACK_GRAD_START_UNIT_OOB;
}
if (block->GradientEndUnit < 1 || block->GradientEndUnit >= 48)
{
return ERR_UNPACK_GRAD_END_UNIT_OOB;
}
if (block->GradientStartUnit > block->GradientEndUnit)
{
return ERR_UNPACK_GRAD_END_UNIT_INVALID;
}
if (block->GradientStartValue < 0 || block->GradientStartValue >= 32)
{
return ERR_UNPACK_GRAD_START_VALUE_OOB;
}
if (block->GradientEndValue < 0 || block->GradientEndValue >= 32)
{
return ERR_UNPACK_GRAD_END_VALUE_OOB;
}
return ERR_SUCCESS;
}
at9_status ReadStereoParams(block* block, bit_reader_cxt* br)
{
if (block->BlockType != Stereo) return ERR_SUCCESS;
block->PrimaryChannelIndex = read_int(br, 1);
block->HasJointStereoSigns = read_int(br, 1);
if (block->HasJointStereoSigns)
{
for (int i = block->StereoQuantizationUnit; i < block->QuantizationUnitCount; i++)
{
block->JointStereoSigns[i] = read_int(br, 1);
}
}
else
{
memset(block->JointStereoSigns, 0, sizeof(block->JointStereoSigns));
}
return ERR_SUCCESS;
}
void BexReadHeader(channel* channel, bit_reader_cxt* br, int bexBand)
{
const int bexMode = read_int(br, 2);
channel->BexMode = bexBand > 2 ? bexMode : 4;
channel->BexValueCount = BexEncodedValueCounts[channel->BexMode][bexBand];
}
void BexReadData(channel* channel, bit_reader_cxt* br, int bexBand)
{
for (int i = 0; i < channel->BexValueCount; i++)
{
const int dataLength = BexDataLengths[channel->BexMode][bexBand][i];
channel->BexValues[i] = read_int(br, dataLength);
}
}
at9_status ReadExtensionParams(block* block, bit_reader_cxt* br)
{
int bexBand = 0;
if (block->BandExtensionEnabled)
{
bexBand = BexGroupInfo[block->QuantizationUnitCount - 13].band_count;
if (block->BlockType == Stereo)
{
BexReadHeader(&block->Channels[1], br, bexBand);
}
else
{
br->position += 1;
}
}
block->HasExtensionData = read_int(br, 1);
if (!block->HasExtensionData) return ERR_SUCCESS;
if (!block->BandExtensionEnabled)
{
block->BexMode = read_int(br, 2);
block->BexDataLength = read_int(br, 5);
br->position += block->BexDataLength;
return ERR_SUCCESS;
}
BexReadHeader(&block->Channels[0], br, bexBand);
block->BexDataLength = read_int(br, 5);
if (block->BexDataLength <= 0) return ERR_SUCCESS;
const int bexDataEnd = br->position + block->BexDataLength;
BexReadData(&block->Channels[0], br, bexBand);
if (block->BlockType == Stereo)
{
BexReadData(&block->Channels[1], br, bexBand);
}
// Make sure we didn't read too many bits
if (br->position > bexDataEnd)
{
return ERR_UNPACK_EXTENSION_DATA_INVALID;
}
return ERR_SUCCESS;
}
void UpdateCodedUnits(channel* channel)
{
if (channel->Block->PrimaryChannelIndex == channel->ChannelIndex)
{
channel->CodedQuantUnits = channel->Block->QuantizationUnitCount;
}
else
{
channel->CodedQuantUnits = channel->Block->StereoQuantizationUnit;
}
}
void CalculateSpectrumCodebookIndex(channel* channel)
{
memset(channel->CodebookSet, 0, sizeof(channel->CodebookSet));
const int quantUnits = channel->CodedQuantUnits;
int* sf = channel->ScaleFactors;
if (quantUnits <= 1) return;
if (channel->config->HighSampleRate) return;
// Temporarily setting this value allows for simpler code by
// making the last value a non-special case.
const int originalScaleTmp = sf[quantUnits];
sf[quantUnits] = sf[quantUnits - 1];
int avg = 0;
if (quantUnits > 12)
{
for (int i = 0; i < 12; i++)
{
avg += sf[i];
}
avg = (avg + 6) / 12;
}
for (int i = 8; i < quantUnits; i++)
{
const int prevSf = sf[i - 1];
const int nextSf = sf[i + 1];
const int minSf = min(prevSf, nextSf);
if (sf[i] - minSf >= 3 || sf[i] - prevSf + sf[i] - nextSf >= 3)
{
channel->CodebookSet[i] = 1;
}
}
for (int i = 12; i < quantUnits; i++)
{
if (channel->CodebookSet[i] == 0)
{
const int minSf = min(sf[i - 1], sf[i + 1]);
if (sf[i] - minSf >= 2 && sf[i] >= avg - (QuantUnitToCoeffCount[i] == 16 ? 1 : 0))
{
channel->CodebookSet[i] = 1;
}
}
}
sf[quantUnits] = originalScaleTmp;
}
at9_status ReadSpectra(channel* channel, bit_reader_cxt* br)
{
int values[16];
memset(channel->QuantizedSpectra, 0, sizeof(channel->QuantizedSpectra));
const int maxHuffPrecision = MaxHuffPrecision[channel->config->HighSampleRate];
for (int i = 0; i < channel->CodedQuantUnits; i++)
{
const int subbandCount = QuantUnitToCoeffCount[i];
const int precision = channel->Precisions[i] + 1;
if (precision <= maxHuffPrecision)
{
const HuffmanCodebook* huff = &HuffmanSpectrum[channel->CodebookSet[i]][precision][QuantUnitToCodebookIndex[i]];
const int groupCount = subbandCount >> huff->ValueCountPower;
for (int j = 0; j < groupCount; j++)
{
values[j] = ReadHuffmanValue(huff, br, FALSE);
}
DecodeHuffmanValues(channel->QuantizedSpectra, QuantUnitToCoeffIndex[i], subbandCount, huff, values);
}
else
{
const int subbandIndex = QuantUnitToCoeffIndex[i];
for (int j = subbandIndex; j < QuantUnitToCoeffIndex[i + 1]; j++)
{
channel->QuantizedSpectra[j] = read_signed_int(br, precision);
}
}
}
return ERR_SUCCESS;
}
at9_status ReadSpectraFine(channel* channel, bit_reader_cxt* br)
{
memset(channel->QuantizedSpectraFine, 0, sizeof(channel->QuantizedSpectraFine));
for (int i = 0; i < channel->CodedQuantUnits; i++)
{
if (channel->PrecisionsFine[i] > 0)
{
const int overflowBits = channel->PrecisionsFine[i] + 1;
const int startSubband = QuantUnitToCoeffIndex[i];
const int endSubband = QuantUnitToCoeffIndex[i + 1];
for (int j = startSubband; j < endSubband; j++)
{
channel->QuantizedSpectraFine[j] = read_signed_int(br, overflowBits);
}
}
}
return ERR_SUCCESS;
}
at9_status UnpackLfeBlock(block* block, bit_reader_cxt* br)
{
channel* channel = &block->Channels[0];
block->QuantizationUnitCount = 2;
DecodeLfeScaleFactors(channel, br);
CalculateLfePrecision(channel);
channel->CodedQuantUnits = block->QuantizationUnitCount;
ReadLfeSpectra(channel, br);
return ERR_SUCCESS;
}
void DecodeLfeScaleFactors(channel* channel, bit_reader_cxt* br)
{
memset(channel->ScaleFactors, 0, sizeof(channel->ScaleFactors));
for (int i = 0; i < channel->Block->QuantizationUnitCount; i++)
{
channel->ScaleFactors[i] = read_int(br, 5);
}
}
void CalculateLfePrecision(channel* channel)
{
block* block = channel->Block;
const int precision = block->ReuseBandParams ? 8 : 4;
for (int i = 0; i < block->QuantizationUnitCount; i++)
{
channel->Precisions[i] = precision;
channel->PrecisionsFine[i] = 0;
}
}
void ReadLfeSpectra(channel* channel, bit_reader_cxt* br)
{
memset(channel->QuantizedSpectra, 0, sizeof(channel->QuantizedSpectra));
for (int i = 0; i < channel->CodedQuantUnits; i++)
{
if (channel->Precisions[i] <= 0) continue;
const int precision = channel->Precisions[i] + 1;
for (int j = QuantUnitToCoeffIndex[i]; j < QuantUnitToCoeffIndex[i + 1]; j++)
{
channel->QuantizedSpectra[j] = read_signed_int(br, precision);
}
}
}

View File

@ -1,23 +0,0 @@
#pragma once
#include "bit_reader.h"
#include "error_codes.h"
#include "structures.h"
at9_status UnpackFrame(frame* frame, bit_reader_cxt* br);
at9_status UnpackBlock(block* block, bit_reader_cxt* br);
at9_status ReadBlockHeader(block* block, bit_reader_cxt* br);
at9_status UnpackStandardBlock(block* block, bit_reader_cxt* br);
at9_status ReadBandParams(block* block, bit_reader_cxt* br);
at9_status ReadGradientParams(block* block, bit_reader_cxt* br);
at9_status ReadStereoParams(block* block, bit_reader_cxt* br);
at9_status ReadExtensionParams(block* block, bit_reader_cxt* br);
void UpdateCodedUnits(channel* channel);
void CalculateSpectrumCodebookIndex(channel* channel);
at9_status ReadSpectra(channel* channel, bit_reader_cxt* br);
at9_status ReadSpectraFine(channel* channel, bit_reader_cxt* br);
at9_status UnpackLfeBlock(block* block, bit_reader_cxt* br);
void DecodeLfeScaleFactors(channel* channel, bit_reader_cxt* br);
void CalculateLfePrecision(channel* channel);
void ReadLfeSpectra(channel* channel, bit_reader_cxt* br);

View File

@ -1,30 +0,0 @@
#include "utility.h"
#include <limits.h>
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a > b ? b : a; }
unsigned int BitReverse32(unsigned int value, int bitCount)
{
value = ((value & 0xaaaaaaaa) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xcccccccc) >> 2) | ((value & 0x33333333) << 2);
value = ((value & 0xf0f0f0f0) >> 4) | ((value & 0x0f0f0f0f) << 4);
value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8);
value = (value >> 16) | (value << 16);
return value >> (32 - bitCount);
}
int SignExtend32(int value, int bits)
{
const int shift = 8 * sizeof(int) - bits;
return (value << shift) >> shift;
}
short Clamp16(int value)
{
if (value > SHRT_MAX)
return SHRT_MAX;
if (value < SHRT_MIN)
return SHRT_MIN;
return (short)value;
}

View File

@ -1,15 +0,0 @@
#pragma once
#define FALSE 0
#define TRUE 1
#define NULL 0
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
int max(int a, int b);
int min(int a, int b);
unsigned int BitReverse32(unsigned int value, int bitCount);
int SignExtend32(int value, int bits);
short Clamp16(int value);

View File

@ -1,42 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2003
MinimumVisualStudioVersion = 15.0.26124.0
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibAtrac9", "LibAtrac9\LibAtrac9.csproj", "{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|ARM.Build.0 = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|x64.ActiveCfg = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|x64.Build.0 = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|x86.ActiveCfg = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Debug|x86.Build.0 = Debug|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|Any CPU.Build.0 = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|ARM.ActiveCfg = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|ARM.Build.0 = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|x64.ActiveCfg = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|x64.Build.0 = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|x86.ActiveCfg = Release|Any CPU
{2414DAA9-779C-4E7E-A97F-4DE09B22B88F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2AFD09F0-D995-47ED-AA86-FFA93824A514}
EndGlobalSection
EndGlobal

View File

@ -1,119 +0,0 @@
using System.IO;
using LibAtrac9.Utilities;
namespace LibAtrac9
{
/// <summary>
/// Stores the configuration data needed to decode or encode an ATRAC9 stream.
/// </summary>
public class Atrac9Config
{
/// <summary>
/// The 4-byte ATRAC9 configuration data.
/// </summary>
public byte[] ConfigData { get; }
/// <summary>
/// A 4-bit value specifying one of 16 sample rates.
/// </summary>
public int SampleRateIndex { get; }
/// <summary>
/// A 3-bit value specifying one of 6 substream channel mappings.
/// </summary>
public int ChannelConfigIndex { get; }
/// <summary>
/// An 11-bit value containing the average size of a single frame.
/// </summary>
public int FrameBytes { get; }
/// <summary>
/// A 2-bit value indicating how many frames are in each superframe.
/// </summary>
public int SuperframeIndex { get; }
/// <summary>
/// The channel mapping used by the ATRAC9 stream.
/// </summary>
public ChannelConfig ChannelConfig { get; }
/// <summary>
/// The total number of channels in the ATRAC9 stream.
/// </summary>
public int ChannelCount { get; }
/// <summary>
/// The sample rate of the ATRAC9 stream.
/// </summary>
public int SampleRate { get; }
/// <summary>
/// Indicates whether the ATRAC9 stream has a <see cref="SampleRateIndex"/> of 8 or above.
/// </summary>
public bool HighSampleRate { get; }
/// <summary>
/// The number of frames in each superframe.
/// </summary>
public int FramesPerSuperframe { get; }
/// <summary>
/// The number of samples in one frame as an exponent of 2.
/// <see cref="FrameSamples"/> = 2^<see cref="FrameSamplesPower"/>.
/// </summary>
public int FrameSamplesPower { get; }
/// <summary>
/// The number of samples in one frame.
/// </summary>
public int FrameSamples { get; }
/// <summary>
/// The number of bytes in one superframe.
/// </summary>
public int SuperframeBytes { get; }
/// <summary>
/// The number of samples in one superframe.
/// </summary>
public int SuperframeSamples { get; }
/// <summary>
/// Reads ATRAC9 configuration data and calculates the stream parameters from it.
/// </summary>
/// <param name="configData">The processed ATRAC9 configuration.</param>
public Atrac9Config(byte[] configData)
{
if (configData == null || configData.Length != 4)
{
throw new InvalidDataException("Config data must be 4 bytes long");
}
ReadConfigData(configData, out int a, out int b, out int c, out int d);
SampleRateIndex = a;
ChannelConfigIndex = b;
FrameBytes = c;
SuperframeIndex = d;
ConfigData = configData;
FramesPerSuperframe = 1 << SuperframeIndex;
SuperframeBytes = FrameBytes << SuperframeIndex;
ChannelConfig = Tables.ChannelConfig[ChannelConfigIndex];
ChannelCount = ChannelConfig.ChannelCount;
SampleRate = Tables.SampleRates[SampleRateIndex];
HighSampleRate = SampleRateIndex > 7;
FrameSamplesPower = Tables.SamplingRateIndexToFrameSamplesPower[SampleRateIndex];
FrameSamples = 1 << FrameSamplesPower;
SuperframeSamples = FrameSamples * FramesPerSuperframe;
}
private static void ReadConfigData(byte[] configData, out int sampleRateIndex, out int channelConfigIndex, out int frameBytes, out int superframeIndex)
{
var reader = new BitReader(configData);
int header = reader.ReadInt(8);
sampleRateIndex = reader.ReadInt(4);
channelConfigIndex = reader.ReadInt(3);
int validationBit = reader.ReadInt(1);
frameBytes = reader.ReadInt(11) + 1;
superframeIndex = reader.ReadInt(2);
if (header != 0xFE || validationBit != 0)
{
throw new InvalidDataException("ATRAC9 Config Data is invalid");
}
}
}
}

View File

@ -1,127 +0,0 @@
using System;
using LibAtrac9.Utilities;
namespace LibAtrac9
{
/// <summary>
/// Decodes an ATRAC9 stream into 16-bit PCM.
/// </summary>
public class Atrac9Decoder
{
/// <summary>
/// The config data for the current ATRAC9 stream.
/// </summary>
public Atrac9Config Config { get; private set; }
private Frame Frame { get; set; }
private BitReader Reader { get; set; }
private bool _initialized;
/// <summary>
/// Sets up the decoder to decode an ATRAC9 stream based on the information in <paramref name="configData"/>.
/// </summary>
/// <param name="configData">A 4-byte value containing information about the ATRAC9 stream.</param>
public void Initialize(byte[] configData)
{
Config = new Atrac9Config(configData);
Frame = new Frame(Config);
Reader = new BitReader(null);
_initialized = true;
}
/// <summary>
/// Decodes one superframe of ATRAC9 data.
/// </summary>
/// <param name="atrac9Data">The ATRAC9 data to decode. The array must be at least
/// <see cref="Config"/>.<see cref="Atrac9Config.SuperframeBytes"/> bytes long.</param>
/// <param name="pcmOut">A buffer that the decoded PCM data will be placed in.
/// The array must have dimensions of at least [<see cref="Config"/>.<see cref="Atrac9Config.ChannelCount"/>]
/// [<see cref="Config"/>.<see cref="Atrac9Config.SuperframeSamples"/>].</param>
public void Decode(byte[] atrac9Data, short[][] pcmOut)
{
if (!_initialized) throw new InvalidOperationException("Decoder must be initialized before decoding.");
ValidateDecodeBuffers(atrac9Data, pcmOut);
Reader.SetBuffer(atrac9Data);
DecodeSuperFrame(pcmOut);
}
private void ValidateDecodeBuffers(byte[] atrac9Buffer, short[][] pcmBuffer)
{
if (atrac9Buffer == null) throw new ArgumentNullException(nameof(atrac9Buffer));
if (pcmBuffer == null) throw new ArgumentNullException(nameof(pcmBuffer));
if (atrac9Buffer.Length < Config.SuperframeBytes)
{
throw new ArgumentException("ATRAC9 buffer is too small");
}
if (pcmBuffer.Length < Config.ChannelCount)
{
throw new ArgumentException("PCM buffer is too small");
}
for (int i = 0; i < Config.ChannelCount; i++)
{
if (pcmBuffer[i]?.Length < Config.SuperframeSamples)
{
throw new ArgumentException("PCM buffer is too small");
}
}
}
private void DecodeSuperFrame(short[][] pcmOut)
{
for (int i = 0; i < Config.FramesPerSuperframe; i++)
{
Frame.FrameIndex = i;
DecodeFrame(Reader, Frame);
PcmFloatToShort(pcmOut, i * Config.FrameSamples);
Reader.AlignPosition(8);
}
}
private void PcmFloatToShort(short[][] pcmOut, int start)
{
int endSample = start + Config.FrameSamples;
int channelNum = 0;
foreach (Block block in Frame.Blocks)
{
foreach (Channel channel in block.Channels)
{
double[] pcmSrc = channel.Pcm;
short[] pcmDest = pcmOut[channelNum++];
for (int d = 0, s = start; s < endSample; d++, s++)
{
double sample = pcmSrc[d];
// Not using Math.Round because it's ~20x slower on 64-bit
int roundedSample = (int)Math.Floor(sample + 0.5);
pcmDest[s] = Helpers.Clamp16(roundedSample);
}
}
}
}
private static void DecodeFrame(BitReader reader, Frame frame)
{
Unpack.UnpackFrame(reader, frame);
foreach (Block block in frame.Blocks)
{
Quantization.DequantizeSpectra(block);
Stereo.ApplyIntensityStereo(block);
Quantization.ScaleSpectrum(block);
BandExtension.ApplyBandExtension(block);
ImdctBlock(block);
}
}
private static void ImdctBlock(Block block)
{
foreach (Channel channel in block.Channels)
{
channel.Mdct.RunImdct(channel.Spectra, channel.Pcm);
}
}
}
}

View File

@ -1,33 +0,0 @@
namespace LibAtrac9
{
/// <summary>
/// An Xorshift RNG used by the ATRAC9 codec
/// </summary>
internal class Atrac9Rng
{
private ushort _stateA;
private ushort _stateB;
private ushort _stateC;
private ushort _stateD;
public Atrac9Rng(ushort seed)
{
int startValue = 0x4D93 * (seed ^ (seed >> 14));
_stateA = (ushort)(3 - startValue);
_stateB = (ushort)(2 - startValue);
_stateC = (ushort)(1 - startValue);
_stateD = (ushort)(0 - startValue);
}
public ushort Next()
{
ushort t = (ushort)(_stateD ^ (_stateD << 5));
_stateD = _stateC;
_stateC = _stateB;
_stateB = _stateA;
_stateA = (ushort)(t ^ _stateA ^ ((t ^ (_stateA >> 5)) >> 4));
return _stateA;
}
}
}

View File

@ -1,372 +0,0 @@
using System;
namespace LibAtrac9
{
internal static class BandExtension
{
public static void ApplyBandExtension(Block block)
{
if (!block.BandExtensionEnabled || !block.HasExtensionData) return;
foreach (Channel channel in block.Channels)
{
ApplyBandExtensionChannel(channel);
}
}
private static void ApplyBandExtensionChannel(Channel channel)
{
int groupAUnit = channel.Block.QuantizationUnitCount;
int[] scaleFactors = channel.ScaleFactors;
double[] spectra = channel.Spectra;
double[] scales = channel.BexScales;
int[] values = channel.BexValues;
GetBexBandInfo(out int bandCount, out int groupBUnit, out int groupCUnit, groupAUnit);
int totalUnits = Math.Max(groupCUnit, 22);
int groupABin = Tables.QuantUnitToCoeffIndex[groupAUnit];
int groupBBin = Tables.QuantUnitToCoeffIndex[groupBUnit];
int groupCBin = Tables.QuantUnitToCoeffIndex[groupCUnit];
int totalBins = Tables.QuantUnitToCoeffIndex[totalUnits];
FillHighFrequencies(spectra, groupABin, groupBBin, groupCBin, totalBins);
switch (channel.BexMode)
{
case 0:
int bexQuantUnits = totalUnits - groupAUnit;
switch (bandCount)
{
case 3:
scales[0] = BexMode0Bands3[0][values[0]];
scales[1] = BexMode0Bands3[1][values[0]];
scales[2] = BexMode0Bands3[2][values[1]];
scales[3] = BexMode0Bands3[3][values[2]];
scales[4] = BexMode0Bands3[4][values[3]];
break;
case 4:
scales[0] = BexMode0Bands4[0][values[0]];
scales[1] = BexMode0Bands4[1][values[0]];
scales[2] = BexMode0Bands4[2][values[1]];
scales[3] = BexMode0Bands4[3][values[2]];
scales[4] = BexMode0Bands4[4][values[3]];
break;
case 5:
scales[0] = BexMode0Bands5[0][values[0]];
scales[1] = BexMode0Bands5[1][values[1]];
scales[2] = BexMode0Bands5[2][values[1]];
break;
}
scales[bexQuantUnits - 1] = Tables.SpectrumScale[scaleFactors[groupAUnit]];
AddNoiseToSpectrum(channel, Tables.QuantUnitToCoeffIndex[totalUnits - 1],
Tables.QuantUnitToCoeffCount[totalUnits - 1]);
ScaleBexQuantUnits(spectra, scales, groupAUnit, totalUnits);
break;
case 1:
for (int i = groupAUnit; i < totalUnits; i++)
{
scales[i - groupAUnit] = Tables.SpectrumScale[scaleFactors[i]];
}
AddNoiseToSpectrum(channel, groupABin, totalBins - groupABin);
ScaleBexQuantUnits(spectra, scales, groupAUnit, totalUnits);
break;
case 2:
double groupAScale2 = BexMode2Scale[values[0]];
double groupBScale2 = BexMode2Scale[values[1]];
for (int i = groupABin; i < groupBBin; i++)
{
spectra[i] *= groupAScale2;
}
for (int i = groupBBin; i < groupCBin; i++)
{
spectra[i] *= groupBScale2;
}
return;
case 3:
double rate = Math.Pow(2, BexMode3Rate[values[1]]);
double scale = BexMode3Initial[values[0]];
for (int i = groupABin; i < totalBins; i++)
{
scale *= rate;
spectra[i] *= scale;
}
return;
case 4:
double mult = BexMode4Multiplier[values[0]];
double groupAScale4 = 0.7079468 * mult;
double groupBScale4 = 0.5011902 * mult;
double groupCScale4 = 0.3548279 * mult;
for (int i = groupABin; i < groupBBin; i++)
{
spectra[i] *= groupAScale4;
}
for (int i = groupBBin; i < groupCBin; i++)
{
spectra[i] *= groupBScale4;
}
for (int i = groupCBin; i < totalBins; i++)
{
spectra[i] *= groupCScale4;
}
return;
}
}
private static void ScaleBexQuantUnits(double[] spectra, double[] scales, int startUnit, int totalUnits)
{
for (int i = startUnit; i < totalUnits; i++)
{
for (int k = Tables.QuantUnitToCoeffIndex[i]; k < Tables.QuantUnitToCoeffIndex[i + 1]; k++)
{
spectra[k] *= scales[i - startUnit];
}
}
}
private static void FillHighFrequencies(double[] spectra, int groupABin, int groupBBin, int groupCBin, int totalBins)
{
for (int i = 0; i < groupBBin - groupABin; i++)
{
spectra[groupABin + i] = spectra[groupABin - i - 1];
}
for (int i = 0; i < groupCBin - groupBBin; i++)
{
spectra[groupBBin + i] = spectra[groupBBin - i - 1];
}
for (int i = 0; i < totalBins - groupCBin; i++)
{
spectra[groupCBin + i] = spectra[groupCBin - i - 1];
}
}
private static void AddNoiseToSpectrum(Channel channel, int index, int count)
{
if (channel.Rng == null)
{
int[] sf = channel.ScaleFactors;
ushort seed = (ushort)(543 * (sf[8] + sf[12] + sf[15] + 1));
channel.Rng = new Atrac9Rng(seed);
}
for (int i = 0; i < count; i++)
{
channel.Spectra[i + index] = channel.Rng.Next() / 65535.0 * 2.0 - 1.0;
}
}
public static void GetBexBandInfo(out int bandCount, out int groupAUnit, out int groupBUnit, int quantUnits)
{
groupAUnit = BexGroupInfo[quantUnits - 13][0];
groupBUnit = BexGroupInfo[quantUnits - 13][1];
bandCount = BexGroupInfo[quantUnits - 13][2];
}
public static readonly byte[][] BexGroupInfo =
{
new byte[] {16, 21, 0},
new byte[] {18, 22, 1},
new byte[] {20, 22, 2},
new byte[] {21, 22, 3},
new byte[] {21, 22, 3},
new byte[] {23, 24, 4},
new byte[] {23, 24, 4},
new byte[] {24, 24, 5}
};
// [mode][bands]
public static readonly byte[][] BexEncodedValueCounts =
{
new byte[] {0, 0, 0, 4, 4, 2},
new byte[] {0, 0, 0, 0, 0, 0},
new byte[] {0, 0, 0, 2, 2, 1},
new byte[] {0, 0, 0, 2, 2, 2},
new byte[] {1, 1, 1, 0, 0, 0}
};
// [mode][bands][valueIndex]
public static readonly byte[][][] BexDataLengths =
{
new[] {
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {5, 4, 3, 3},
new byte[] {4, 4, 3, 4},
new byte[] {4, 5, 0, 0}
}, new[] {
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0}
}, new[] {
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {6, 6, 0, 0},
new byte[] {6, 6, 0, 0},
new byte[] {6, 0, 0, 0}
}, new[] {
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {4, 4, 0, 0},
new byte[] {4, 4, 0, 0},
new byte[] {4, 4, 0, 0}
}, new[] {
new byte[] {3, 0, 0, 0},
new byte[] {3, 0, 0, 0},
new byte[] {3, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0},
new byte[] {0, 0, 0, 0}
}
};
public static readonly double[][] BexMode0Bands3 =
{
new[] {
0.000000e+0, 1.988220e-1, 2.514343e-1, 2.960510e-1,
3.263550e-1, 3.771362e-1, 3.786926e-1, 4.540405e-1,
4.877625e-1, 5.262451e-1, 5.447083e-1, 5.737000e-1,
6.212158e-1, 6.222839e-1, 6.560974e-1, 6.896667e-1,
7.555542e-1, 7.677917e-1, 7.918091e-1, 7.971497e-1,
8.188171e-1, 8.446045e-1, 9.790649e-1, 9.822083e-1,
9.846191e-1, 9.859314e-1, 9.863586e-1, 9.863892e-1,
9.873352e-1, 9.881287e-1, 9.898682e-1, 9.913330e-1
}, new[] {
0.000000e+0, 9.982910e-1, 7.592773e-2, 7.179565e-1,
9.851379e-1, 5.340271e-1, 9.013672e-1, 6.349182e-1,
7.226257e-1, 1.948547e-1, 7.628174e-1, 9.873657e-1,
8.112183e-1, 2.715454e-1, 9.734192e-1, 1.443787e-1,
4.640198e-1, 3.249207e-1, 3.790894e-1, 8.276367e-2,
5.954590e-1, 2.864380e-1, 9.806824e-1, 7.929077e-1,
6.292114e-1, 4.887085e-1, 2.905273e-1, 1.301880e-1,
3.140869e-1, 5.482483e-1, 4.210815e-1, 1.182861e-1
}, new[] {
0.000000e+0, 3.155518e-2, 8.581543e-2, 1.364746e-1,
1.858826e-1, 2.368469e-1, 2.888184e-1, 3.432617e-1,
4.012451e-1, 4.623108e-1, 5.271301e-1, 5.954895e-1,
6.681213e-1, 7.448425e-1, 8.245239e-1, 9.097290e-1
}, new[] {
0.000000e+0, 4.418945e-2, 1.303711e-1, 2.273560e-1,
3.395996e-1, 4.735718e-1, 6.267090e-1, 8.003845e-1
}, new[] {
0.000000e+0, 2.804565e-2, 9.683228e-2, 1.849976e-1,
3.005981e-1, 4.470520e-1, 6.168518e-1, 8.007813e-1
}
};
public static readonly double[][] BexMode0Bands4 =
{
new[] {
0.000000e+0, 2.708740e-1, 3.479614e-1, 3.578186e-1,
5.083618e-1, 5.299072e-1, 5.819092e-1, 6.381836e-1,
7.276917e-1, 7.595520e-1, 7.878723e-1, 9.707336e-1,
9.713135e-1, 9.736023e-1, 9.759827e-1, 9.832458e-1
}, new[] {
0.000000e+0, 2.330627e-1, 5.891418e-1, 7.170410e-1,
2.036438e-1, 1.613464e-1, 6.668701e-1, 9.481201e-1,
9.769897e-1, 5.111694e-1, 3.522644e-1, 8.209534e-1,
2.933960e-1, 9.757690e-1, 5.289917e-1, 4.372253e-1
}, new[] {
0.000000e+0, 4.360962e-2, 1.056519e-1, 1.590576e-1,
2.078857e-1, 2.572937e-1, 3.082581e-1, 3.616028e-1,
4.191589e-1, 4.792175e-1, 5.438538e-1, 6.125183e-1,
6.841125e-1, 7.589417e-1, 8.365173e-1, 9.148254e-1
}, new[] {
0.000000e+0, 4.074097e-2, 1.164551e-1, 2.077026e-1,
3.184509e-1, 4.532166e-1, 6.124268e-1, 7.932129e-1
}, new[] {
0.000000e+0, 8.880615e-3, 2.932739e-2, 5.593872e-2,
8.825684e-2, 1.259155e-1, 1.721497e-1, 2.270813e-1,
2.901611e-1, 3.579712e-1, 4.334106e-1, 5.147095e-1,
6.023254e-1, 6.956177e-1, 7.952881e-1, 8.977356e-1
}
};
public static readonly double[][] BexMode0Bands5 =
{
new[] {
0.000000e+0, 7.379150e-2, 1.806335e-1, 2.687073e-1,
3.407898e-1, 4.047546e-1, 4.621887e-1, 5.168762e-1,
5.703125e-1, 6.237488e-1, 6.763611e-1, 7.288208e-1,
7.808533e-1, 8.337708e-1, 8.874512e-1, 9.418030e-1
}, new[] {
0.000000e+0, 7.980347e-2, 1.615295e-1, 1.665649e-1,
1.822205e-1, 2.185669e-1, 2.292175e-1, 2.456665e-1,
2.666321e-1, 3.306580e-1, 3.330688e-1, 3.765259e-1,
4.085083e-1, 4.400024e-1, 4.407654e-1, 4.817505e-1,
4.924011e-1, 5.320740e-1, 5.893860e-1, 6.131287e-1,
6.212463e-1, 6.278076e-1, 6.308899e-1, 7.660828e-1,
7.850647e-1, 7.910461e-1, 7.929382e-1, 8.038330e-1,
9.834900e-1, 9.846191e-1, 9.852295e-1, 9.862671e-1
}, new[] {
0.000000e+0, 6.084290e-1, 3.672791e-1, 3.151855e-1,
1.488953e-1, 2.571716e-1, 5.103455e-1, 3.311157e-1,
5.426025e-2, 4.254456e-1, 7.998352e-1, 7.873230e-1,
5.418701e-1, 2.925110e-1, 8.468628e-2, 1.410522e-1,
9.819641e-1, 9.609070e-1, 3.530884e-2, 9.729004e-2,
5.758362e-1, 9.941711e-1, 7.215576e-1, 7.183228e-1,
2.028809e-1, 9.588623e-2, 2.032166e-1, 1.338806e-1,
5.003357e-1, 1.874390e-1, 9.804993e-1, 1.107788e-1
}
};
public static readonly double[] BexMode2Scale =
{
4.272461e-4, 1.312256e-3, 2.441406e-3, 3.692627e-3,
4.913330e-3, 6.134033e-3, 7.507324e-3, 8.972168e-3,
1.049805e-2, 1.223755e-2, 1.406860e-2, 1.599121e-2,
1.800537e-2, 2.026367e-2, 2.264404e-2, 2.517700e-2,
2.792358e-2, 3.073120e-2, 3.344727e-2, 3.631592e-2,
3.952026e-2, 4.275513e-2, 4.608154e-2, 4.968262e-2,
5.355835e-2, 5.783081e-2, 6.195068e-2, 6.677246e-2,
7.196045e-2, 7.745361e-2, 8.319092e-2, 8.993530e-2,
9.759521e-2, 1.056213e-1, 1.138916e-1, 1.236267e-1,
1.348267e-1, 1.470337e-1, 1.603394e-1, 1.755676e-1,
1.905823e-1, 2.071228e-1, 2.245178e-1, 2.444153e-1,
2.658997e-1, 2.897644e-1, 3.146057e-1, 3.450012e-1,
3.766174e-1, 4.122620e-1, 4.505615e-1, 4.893799e-1,
5.305481e-1, 5.731201e-1, 6.157837e-1, 6.580811e-1,
6.985168e-1, 7.435303e-1, 7.865906e-1, 8.302612e-1,
8.718567e-1, 9.125671e-1, 9.575806e-1, 9.996643e-1
};
public static readonly double[] BexMode3Initial =
{
3.491211e-1, 5.371094e-1, 6.782227e-1, 7.910156e-1,
9.057617e-1, 1.024902e+0, 1.156250e+0, 1.290527e+0,
1.458984e+0, 1.664551e+0, 1.929688e+0, 2.278320e+0,
2.831543e+0, 3.659180e+0, 5.257813e+0, 8.373047e+0
};
public static readonly double[] BexMode3Rate =
{
-2.913818e-1, -2.541504e-1, -1.664429e-1, -1.476440e-1,
-1.342163e-1, -1.220703e-1, -1.117554e-1, -1.026611e-1,
-9.436035e-2, -8.483887e-2, -7.476807e-2, -6.304932e-2,
-4.492188e-2, -2.447510e-2, +1.831055e-4, +4.174805e-2
};
public static readonly double[] BexMode4Multiplier =
{
3.610229e-2, 1.260681e-1, 2.227478e-1, 3.338318e-1,
4.662170e-1, 6.221313e-1, 7.989197e-1, 9.939575e-1
};
}
}

View File

@ -1,140 +0,0 @@
using System;
namespace LibAtrac9
{
internal static class BitAllocation
{
public static void CreateGradient(Block block)
{
int valueCount = block.GradientEndValue - block.GradientStartValue;
int unitCount = block.GradientEndUnit - block.GradientStartUnit;
for (int i = 0; i < block.GradientEndUnit; i++)
{
block.Gradient[i] = block.GradientStartValue;
}
for (int i = block.GradientEndUnit; i <= block.QuantizationUnitCount; i++)
{
block.Gradient[i] = block.GradientEndValue;
}
if (unitCount <= 0) return;
if (valueCount == 0) return;
byte[] curve = Tables.GradientCurves[unitCount - 1];
if (valueCount <= 0)
{
double scale = (-valueCount - 1) / 31.0;
int baseVal = block.GradientStartValue - 1;
for (int i = block.GradientStartUnit; i < block.GradientEndUnit; i++)
{
block.Gradient[i] = baseVal - (int)(curve[i - block.GradientStartUnit] * scale);
}
}
else
{
double scale = (valueCount - 1) / 31.0;
int baseVal = block.GradientStartValue + 1;
for (int i = block.GradientStartUnit; i < block.GradientEndUnit; i++)
{
block.Gradient[i] = baseVal + (int)(curve[i - block.GradientStartUnit] * scale);
}
}
}
public static void CalculateMask(Channel channel)
{
Array.Clear(channel.PrecisionMask, 0, channel.PrecisionMask.Length);
for (int i = 1; i < channel.Block.QuantizationUnitCount; i++)
{
int delta = channel.ScaleFactors[i] - channel.ScaleFactors[i - 1];
if (delta > 1)
{
channel.PrecisionMask[i] += Math.Min(delta - 1, 5);
}
else if (delta < -1)
{
channel.PrecisionMask[i - 1] += Math.Min(delta * -1 - 1, 5);
}
}
}
public static void CalculatePrecisions(Channel channel)
{
Block block = channel.Block;
if (block.GradientMode != 0)
{
for (int i = 0; i < block.QuantizationUnitCount; i++)
{
channel.Precisions[i] = channel.ScaleFactors[i] + channel.PrecisionMask[i] - block.Gradient[i];
if (channel.Precisions[i] > 0)
{
switch (block.GradientMode)
{
case 1:
channel.Precisions[i] /= 2;
break;
case 2:
channel.Precisions[i] = 3 * channel.Precisions[i] / 8;
break;
case 3:
channel.Precisions[i] /= 4;
break;
}
}
}
}
else
{
for (int i = 0; i < block.QuantizationUnitCount; i++)
{
channel.Precisions[i] = channel.ScaleFactors[i] - block.Gradient[i];
}
}
for (int i = 0; i < block.QuantizationUnitCount; i++)
{
if (channel.Precisions[i] < 1)
{
channel.Precisions[i] = 1;
}
}
for (int i = 0; i < block.GradientBoundary; i++)
{
channel.Precisions[i]++;
}
for (int i = 0; i < block.QuantizationUnitCount; i++)
{
channel.PrecisionsFine[i] = 0;
if (channel.Precisions[i] > 15)
{
channel.PrecisionsFine[i] = channel.Precisions[i] - 15;
channel.Precisions[i] = 15;
}
}
}
public static byte[][] GenerateGradientCurves()
{
byte[] main =
{
01, 01, 01, 01, 02, 02, 02, 02, 03, 03, 03, 04, 04, 05, 05, 06, 07, 08, 09, 10, 11, 12, 13, 15,
16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30
};
var curves = new byte[main.Length][];
for (int length = 1; length <= main.Length; length++)
{
curves[length - 1] = new byte[length];
for (int i = 0; i < length; i++)
{
curves[length - 1][i] = main[i * main.Length / length];
}
}
return curves;
}
}
}

View File

@ -1,91 +0,0 @@
namespace LibAtrac9
{
internal class Block
{
public Atrac9Config Config { get; }
public BlockType BlockType { get; }
public int BlockIndex { get; }
public Frame Frame { get; }
public Channel[] Channels { get; }
public int ChannelCount { get; }
public bool FirstInSuperframe { get; set; }
public bool ReuseBandParams { get; set; }
public int BandCount { get; set; }
public int StereoBand { get; set; }
public int ExtensionBand { get; set; }
public int QuantizationUnitCount { get; set; }
public int StereoQuantizationUnit { get; set; }
public int ExtensionUnit { get; set; }
public int QuantizationUnitsPrev { get; set; }
public int[] Gradient { get; } = new int[31];
public int GradientMode { get; set; }
public int GradientStartUnit { get; set; }
public int GradientStartValue { get; set; }
public int GradientEndUnit { get; set; }
public int GradientEndValue { get; set; }
public int GradientBoundary { get; set; }
public int PrimaryChannelIndex { get; set; }
public int[] JointStereoSigns { get; } = new int[30];
public bool HasJointStereoSigns { get; set; }
public Channel PrimaryChannel => Channels[PrimaryChannelIndex == 0 ? 0 : 1];
public Channel SecondaryChannel => Channels[PrimaryChannelIndex == 0 ? 1 : 0];
public bool BandExtensionEnabled { get; set; }
public bool HasExtensionData { get; set; }
public int BexDataLength { get; set; }
public int BexMode { get; set; }
public Block(Frame parentFrame, int blockIndex)
{
Frame = parentFrame;
BlockIndex = blockIndex;
Config = parentFrame.Config;
BlockType = Config.ChannelConfig.BlockTypes[blockIndex];
ChannelCount = BlockTypeToChannelCount(BlockType);
Channels = new Channel[ChannelCount];
for (int i = 0; i < ChannelCount; i++)
{
Channels[i] = new Channel(this, i);
}
}
public static int BlockTypeToChannelCount(BlockType blockType)
{
switch (blockType)
{
case BlockType.Mono:
return 1;
case BlockType.Stereo:
return 2;
case BlockType.LFE:
return 1;
default:
return 0;
}
}
}
/// <summary>
/// An ATRAC9 block (substream) type
/// </summary>
public enum BlockType
{
/// <summary>
/// Mono ATRAC9 block
/// </summary>
Mono = 0,
/// <summary>
/// Stereo ATRAC9 block
/// </summary>
Stereo = 1,
/// <summary>
/// Low-frequency effects ATRAC9 block
/// </summary>
LFE = 2
}
}

View File

@ -1,48 +0,0 @@
using LibAtrac9.Utilities;
namespace LibAtrac9
{
internal class Channel
{
public Atrac9Config Config { get; }
public int ChannelIndex { get; }
public bool IsPrimary => Block.PrimaryChannelIndex == ChannelIndex;
public Block Block { get; }
public Mdct Mdct { get; }
public double[] Pcm { get; } = new double[256];
public double[] Spectra { get; } = new double[256];
public int CodedQuantUnits { get; set; }
public int ScaleFactorCodingMode { get; set; }
public int[] ScaleFactors { get; } = new int[31];
public int[] ScaleFactorsPrev { get; } = new int[31];
public int[] Precisions { get; } = new int[30];
public int[] PrecisionsFine { get; } = new int[30];
public int[] PrecisionMask { get; } = new int[30];
public int[] SpectraValuesBuffer { get; } = new int[16];
public int[] CodebookSet { get; } = new int[30];
public int[] QuantizedSpectra { get; } = new int[256];
public int[] QuantizedSpectraFine { get; } = new int[256];
public int BexMode { get; set; }
public int BexValueCount { get; set; }
public int[] BexValues { get; } = new int[4];
public double[] BexScales { get; } = new double[6];
public Atrac9Rng Rng { get; set; }
public Channel(Block parentBlock, int channelIndex)
{
Block = parentBlock;
ChannelIndex = channelIndex;
Config = parentBlock.Config;
Mdct = new Mdct(Config.FrameSamplesPower, Tables.ImdctWindow[Config.FrameSamplesPower - 6]);
}
public void UpdateCodedUnits() =>
CodedQuantUnits = IsPrimary ? Block.QuantizationUnitCount : Block.StereoQuantizationUnit;
}
}

View File

@ -1,33 +0,0 @@
namespace LibAtrac9
{
/// <summary>
/// Describes the channel mapping for an ATRAC9 stream
/// </summary>
public class ChannelConfig
{
internal ChannelConfig(params BlockType[] blockTypes)
{
BlockCount = blockTypes.Length;
BlockTypes = blockTypes;
foreach (BlockType type in blockTypes)
{
ChannelCount += Block.BlockTypeToChannelCount(type);
}
}
/// <summary>
/// The number of blocks or substreams in the ATRAC9 stream
/// </summary>
public int BlockCount { get; }
/// <summary>
/// The type of each block or substream in the ATRAC9 stream
/// </summary>
public BlockType[] BlockTypes { get; }
/// <summary>
/// The number of channels in the ATRAC9 stream
/// </summary>
public int ChannelCount { get; }
}
}

View File

@ -1,20 +0,0 @@
namespace LibAtrac9
{
internal class Frame
{
public Atrac9Config Config { get; }
public int FrameIndex { get; set; }
public Block[] Blocks { get; }
public Frame(Atrac9Config config)
{
Config = config;
Blocks = new Block[config.ChannelConfig.BlockCount];
for (int i = 0; i < config.ChannelConfig.BlockCount; i++)
{
Blocks[i] = new Block(this, i);
}
}
}
}

View File

@ -1,62 +0,0 @@
using System;
using LibAtrac9.Utilities;
namespace LibAtrac9
{
internal class HuffmanCodebook
{
public HuffmanCodebook(short[] codes, byte[] bits, byte valueCountPower)
{
Codes = codes;
Bits = bits;
if (Codes == null || Bits == null) return;
ValueCount = 1 << valueCountPower;
ValueCountPower = valueCountPower;
ValueBits = Helpers.Log2(codes.Length) >> valueCountPower;
ValueMax = 1 << ValueBits;
int max = 0;
foreach (byte bitSize in bits)
{
max = Math.Max(max, bitSize);
}
MaxBitSize = max;
Lookup = CreateLookupTable();
}
private byte[] CreateLookupTable()
{
if (Codes == null || Bits == null) return null;
int tableSize = 1 << MaxBitSize;
var dest = new byte[tableSize];
for (int i = 0; i < Bits.Length; i++)
{
if (Bits[i] == 0) continue;
int unusedBits = MaxBitSize - Bits[i];
int start = Codes[i] << unusedBits;
int length = 1 << unusedBits;
int end = start + length;
for (int j = start; j < end; j++)
{
dest[j] = (byte)i;
}
}
return dest;
}
public short[] Codes { get; }
public byte[] Bits { get; }
public byte[] Lookup { get; }
public int ValueCount { get; }
public int ValueCountPower { get; }
public int ValueBits { get; }
public int ValueMax { get; }
public int MaxBitSize { get; }
}
}

View File

@ -1,8 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
</Project>

View File

@ -1,57 +0,0 @@
using System;
namespace LibAtrac9
{
internal static class Quantization
{
public static void DequantizeSpectra(Block block)
{
foreach (Channel channel in block.Channels)
{
Array.Clear(channel.Spectra, 0, channel.Spectra.Length);
for (int i = 0; i < channel.CodedQuantUnits; i++)
{
DequantizeQuantUnit(channel, i);
}
}
}
private static void DequantizeQuantUnit(Channel channel, int band)
{
int subBandIndex = Tables.QuantUnitToCoeffIndex[band];
int subBandCount = Tables.QuantUnitToCoeffCount[band];
double stepSize = Tables.QuantizerStepSize[channel.Precisions[band]];
double stepSizeFine = Tables.QuantizerFineStepSize[channel.PrecisionsFine[band]];
for (int sb = 0; sb < subBandCount; sb++)
{
double coarse = channel.QuantizedSpectra[subBandIndex + sb] * stepSize;
double fine = channel.QuantizedSpectraFine[subBandIndex + sb] * stepSizeFine;
channel.Spectra[subBandIndex + sb] = coarse + fine;
}
}
public static void ScaleSpectrum(Block block)
{
foreach (Channel channel in block.Channels)
{
ScaleSpectrum(channel);
}
}
private static void ScaleSpectrum(Channel channel)
{
int quantUnitCount = channel.Block.QuantizationUnitCount;
double[] spectra = channel.Spectra;
for (int i = 0; i < quantUnitCount; i++)
{
for (int sb = Tables.QuantUnitToCoeffIndex[i]; sb < Tables.QuantUnitToCoeffIndex[i + 1]; sb++)
{
spectra[sb] *= Tables.SpectrumScale[channel.ScaleFactors[i]];
}
}
}
}
}

View File

@ -1,171 +0,0 @@
using System;
using System.IO;
using LibAtrac9.Utilities;
namespace LibAtrac9
{
internal static class ScaleFactors
{
public static void Read(BitReader reader, Channel channel)
{
Array.Clear(channel.ScaleFactors, 0, channel.ScaleFactors.Length);
channel.ScaleFactorCodingMode = reader.ReadInt(2);
if (channel.ChannelIndex == 0)
{
switch (channel.ScaleFactorCodingMode)
{
case 0:
ReadVlcDeltaOffset(reader, channel);
break;
case 1:
ReadClcOffset(reader, channel);
break;
case 2:
if (channel.Block.FirstInSuperframe) throw new InvalidDataException();
ReadVlcDistanceToBaseline(reader, channel, channel.ScaleFactorsPrev, channel.Block.QuantizationUnitsPrev);
break;
case 3:
if (channel.Block.FirstInSuperframe) throw new InvalidDataException();
ReadVlcDeltaOffsetWithBaseline(reader, channel, channel.ScaleFactorsPrev, channel.Block.QuantizationUnitsPrev);
break;
}
}
else
{
switch (channel.ScaleFactorCodingMode)
{
case 0:
ReadVlcDeltaOffset(reader, channel);
break;
case 1:
ReadVlcDistanceToBaseline(reader, channel, channel.Block.Channels[0].ScaleFactors, channel.Block.ExtensionUnit);
break;
case 2:
ReadVlcDeltaOffsetWithBaseline(reader, channel, channel.Block.Channels[0].ScaleFactors, channel.Block.ExtensionUnit);
break;
case 3:
if (channel.Block.FirstInSuperframe) throw new InvalidDataException();
ReadVlcDistanceToBaseline(reader, channel, channel.ScaleFactorsPrev, channel.Block.QuantizationUnitsPrev);
break;
}
}
for (int i = 0; i < channel.Block.ExtensionUnit; i++)
{
if (channel.ScaleFactors[i] < 0 || channel.ScaleFactors[i] > 31)
{
throw new InvalidDataException("Scale factor values are out of range.");
}
}
Array.Copy(channel.ScaleFactors, channel.ScaleFactorsPrev, channel.ScaleFactors.Length);
}
private static void ReadClcOffset(BitReader reader, Channel channel)
{
const int maxBits = 5;
int[] sf = channel.ScaleFactors;
int bitLength = reader.ReadInt(2) + 2;
int baseValue = bitLength < maxBits ? reader.ReadInt(maxBits) : 0;
for (int i = 0; i < channel.Block.ExtensionUnit; i++)
{
sf[i] = reader.ReadInt(bitLength) + baseValue;
}
}
private static void ReadVlcDeltaOffset(BitReader reader, Channel channel)
{
int weightIndex = reader.ReadInt(3);
byte[] weights = ScaleFactorWeights[weightIndex];
int[] sf = channel.ScaleFactors;
int baseValue = reader.ReadInt(5);
int bitLength = reader.ReadInt(2) + 3;
HuffmanCodebook codebook = Tables.HuffmanScaleFactorsUnsigned[bitLength];
sf[0] = reader.ReadInt(bitLength);
for (int i = 1; i < channel.Block.ExtensionUnit; i++)
{
int delta = Unpack.ReadHuffmanValue(codebook, reader);
sf[i] = (sf[i - 1] + delta) & (codebook.ValueMax - 1);
}
for (int i = 0; i < channel.Block.ExtensionUnit; i++)
{
sf[i] += baseValue - weights[i];
}
}
private static void ReadVlcDistanceToBaseline(BitReader reader, Channel channel, int[] baseline, int baselineLength)
{
int[] sf = channel.ScaleFactors;
int bitLength = reader.ReadInt(2) + 2;
HuffmanCodebook codebook = Tables.HuffmanScaleFactorsSigned[bitLength];
int unitCount = Math.Min(channel.Block.ExtensionUnit, baselineLength);
for (int i = 0; i < unitCount; i++)
{
int distance = Unpack.ReadHuffmanValue(codebook, reader, true);
sf[i] = (baseline[i] + distance) & 31;
}
for (int i = unitCount; i < channel.Block.ExtensionUnit; i++)
{
sf[i] = reader.ReadInt(5);
}
}
private static void ReadVlcDeltaOffsetWithBaseline(BitReader reader, Channel channel, int[] baseline, int baselineLength)
{
int[] sf = channel.ScaleFactors;
int baseValue = reader.ReadOffsetBinary(5, BitReader.OffsetBias.Negative);
int bitLength = reader.ReadInt(2) + 1;
HuffmanCodebook codebook = Tables.HuffmanScaleFactorsUnsigned[bitLength];
int unitCount = Math.Min(channel.Block.ExtensionUnit, baselineLength);
sf[0] = reader.ReadInt(bitLength);
for (int i = 1; i < unitCount; i++)
{
int delta = Unpack.ReadHuffmanValue(codebook, reader);
sf[i] = (sf[i - 1] + delta) & (codebook.ValueMax - 1);
}
for (int i = 0; i < unitCount; i++)
{
sf[i] += baseValue + baseline[i];
}
for (int i = unitCount; i < channel.Block.ExtensionUnit; i++)
{
sf[i] = reader.ReadInt(5);
}
}
public static readonly byte[][] ScaleFactorWeights =
{
new byte[] {
0, 0, 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8, 10, 12, 12, 12
}, new byte[] {
3, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 5, 7, 10, 10, 10
}, new byte[] {
0, 2, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 8, 9, 12, 12, 12
}, new byte[] {
0, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 8, 8, 10, 11, 11, 12, 13, 13, 13, 13
}, new byte[] {
0, 2, 2, 3, 3, 4, 4, 5, 4, 5, 5, 5, 5, 6, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 14, 14
}, new byte[] {
1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 7, 9, 11, 11, 11
}, new byte[] {
0, 5, 8, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12,
12, 13, 15, 15, 15
}, new byte[] {
0, 2, 3, 4, 5, 6, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13,
15, 15, 15
}
};
}
}

View File

@ -1,33 +0,0 @@
namespace LibAtrac9
{
internal static class Stereo
{
public static void ApplyIntensityStereo(Block block)
{
if (block.BlockType != BlockType.Stereo) return;
int totalUnits = block.QuantizationUnitCount;
int stereoUnits = block.StereoQuantizationUnit;
if (stereoUnits >= totalUnits) return;
Channel source = block.PrimaryChannel;
Channel dest = block.SecondaryChannel;
for (int i = stereoUnits; i < totalUnits; i++)
{
int sign = block.JointStereoSigns[i];
for (int sb = Tables.QuantUnitToCoeffIndex[i]; sb < Tables.QuantUnitToCoeffIndex[i + 1]; sb++)
{
if (sign > 0)
{
dest.Spectra[sb] = -source.Spectra[sb];
}
else
{
dest.Spectra[sb] = source.Spectra[sb];
}
}
}
}
}
}

View File

@ -1,115 +0,0 @@
using System;
using static LibAtrac9.HuffmanCodebooks;
namespace LibAtrac9
{
internal static class Tables
{
public static int MaxHuffPrecision(bool highSampleRate) => highSampleRate ? 1 : 7;
public static int MinBandCount(bool highSampleRate) => highSampleRate ? 1 : 3;
public static int MaxExtensionBand(bool highSampleRate) => highSampleRate ? 16 : 18;
public static readonly int[] SampleRates =
{
11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000
};
public static readonly byte[] SamplingRateIndexToFrameSamplesPower = { 6, 6, 7, 7, 7, 8, 8, 8, 6, 6, 7, 7, 7, 8, 8, 8 };
// From sampling rate index
public static readonly byte[] MaxBandCount = { 8, 8, 12, 12, 12, 18, 18, 18, 8, 8, 12, 12, 12, 16, 16, 16 };
public static readonly byte[] BandToQuantUnitCount = { 0, 4, 8, 10, 12, 13, 14, 15, 16, 18, 20, 21, 22, 23, 24, 25, 26, 28, 30 };
public static readonly byte[] QuantUnitToCoeffCount =
{
02, 02, 02, 02, 02, 02, 02, 02, 04, 04, 04, 04, 08, 08, 08,
08, 08, 08, 08, 08, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16
};
public static readonly short[] QuantUnitToCoeffIndex =
{
0, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
64, 72, 80, 88, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256
};
public static readonly byte[] QuantUnitToCodebookIndex =
{
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
};
public static readonly ChannelConfig[] ChannelConfig =
{
new ChannelConfig(BlockType.Mono),
new ChannelConfig(BlockType.Mono, BlockType.Mono),
new ChannelConfig(BlockType.Stereo),
new ChannelConfig(BlockType.Stereo, BlockType.Mono, BlockType.LFE, BlockType.Stereo),
new ChannelConfig(BlockType.Stereo, BlockType.Mono, BlockType.LFE, BlockType.Stereo, BlockType.Stereo),
new ChannelConfig(BlockType.Stereo, BlockType.Stereo)
};
public static readonly HuffmanCodebook[] HuffmanScaleFactorsUnsigned =
GenerateHuffmanCodebooks(HuffmanScaleFactorsACodes, HuffmanScaleFactorsABits, HuffmanScaleFactorsGroupSizes);
public static readonly HuffmanCodebook[] HuffmanScaleFactorsSigned =
GenerateHuffmanCodebooks(HuffmanScaleFactorsBCodes, HuffmanScaleFactorsBBits, HuffmanScaleFactorsGroupSizes);
public static readonly HuffmanCodebook[][][] HuffmanSpectrum =
{
GenerateHuffmanCodebooks(HuffmanSpectrumACodes, HuffmanSpectrumABits, HuffmanSpectrumAGroupSizes),
GenerateHuffmanCodebooks(HuffmanSpectrumBCodes, HuffmanSpectrumBBits, HuffmanSpectrumBGroupSizes)
};
public static readonly double[][] ImdctWindow = { GenerateImdctWindow(6), GenerateImdctWindow(7), GenerateImdctWindow(8) };
public static readonly double[] SpectrumScale = Generate(32, SpectrumScaleFunction);
public static readonly double[] QuantizerStepSize = Generate(16, QuantizerStepSizeFunction);
public static readonly double[] QuantizerFineStepSize = Generate(16, QuantizerFineStepSizeFunction);
public static readonly byte[][] GradientCurves = BitAllocation.GenerateGradientCurves();
private static double QuantizerStepSizeFunction(int x) => 2.0 / ((1 << (x + 1)) - 1);
private static double QuantizerFineStepSizeFunction(int x) => QuantizerStepSizeFunction(x) / ushort.MaxValue;
private static double SpectrumScaleFunction(int x) => Math.Pow(2, x - 15);
private static double[] GenerateImdctWindow(int frameSizePower)
{
int frameSize = 1 << frameSizePower;
var output = new double[frameSize];
double[] a1 = GenerateMdctWindow(frameSizePower);
for (int i = 0; i < frameSize; i++)
{
output[i] = a1[i] / (a1[frameSize - 1 - i] * a1[frameSize - 1 - i] + a1[i] * a1[i]);
}
return output;
}
private static double[] GenerateMdctWindow(int frameSizePower)
{
int frameSize = 1 << frameSizePower;
var output = new double[frameSize];
for (int i = 0; i < frameSize; i++)
{
output[i] = (Math.Sin(((i + 0.5) / frameSize - 0.5) * Math.PI) + 1.0) * 0.5;
}
return output;
}
private static T[] Generate<T>(int count, Func<int, T> elementGenerator)
{
var table = new T[count];
for (int i = 0; i < count; i++)
{
table[i] = elementGenerator(i);
}
return table;
}
}
}

View File

@ -1,425 +0,0 @@
using System;
using System.IO;
using LibAtrac9.Utilities;
namespace LibAtrac9
{
internal static class Unpack
{
public static void UnpackFrame(BitReader reader, Frame frame)
{
foreach (Block block in frame.Blocks)
{
UnpackBlock(reader, block);
}
}
private static void UnpackBlock(BitReader reader, Block block)
{
ReadBlockHeader(reader, block);
if (block.BlockType == BlockType.LFE)
{
UnpackLfeBlock(reader, block);
}
else
{
UnpackStandardBlock(reader, block);
}
reader.AlignPosition(8);
}
private static void ReadBlockHeader(BitReader reader, Block block)
{
bool firstInSuperframe = block.Frame.FrameIndex == 0;
block.FirstInSuperframe = !reader.ReadBool();
block.ReuseBandParams = reader.ReadBool();
if (block.FirstInSuperframe != firstInSuperframe)
{
throw new InvalidDataException();
}
if (firstInSuperframe && block.ReuseBandParams && block.BlockType != BlockType.LFE)
{
throw new InvalidDataException();
}
}
private static void UnpackStandardBlock(BitReader reader, Block block)
{
Channel[] channels = block.Channels;
if (!block.ReuseBandParams)
{
ReadBandParams(reader, block);
}
ReadGradientParams(reader, block);
BitAllocation.CreateGradient(block);
ReadStereoParams(reader, block);
ReadExtensionParams(reader, block);
foreach (Channel channel in channels)
{
channel.UpdateCodedUnits();
ScaleFactors.Read(reader, channel);
BitAllocation.CalculateMask(channel);
BitAllocation.CalculatePrecisions(channel);
CalculateSpectrumCodebookIndex(channel);
ReadSpectra(reader, channel);
ReadSpectraFine(reader, channel);
}
block.QuantizationUnitsPrev = block.BandExtensionEnabled ? block.ExtensionUnit : block.QuantizationUnitCount;
}
private static void ReadBandParams(BitReader reader, Block block)
{
int minBandCount = Tables.MinBandCount(block.Config.HighSampleRate);
int maxExtensionBand = Tables.MaxExtensionBand(block.Config.HighSampleRate);
block.BandCount = reader.ReadInt(4);
block.BandCount += minBandCount;
block.QuantizationUnitCount = Tables.BandToQuantUnitCount[block.BandCount];
if (block.BandCount < minBandCount || block.BandCount >
Tables.MaxBandCount[block.Config.SampleRateIndex])
{
return;
}
if (block.BlockType == BlockType.Stereo)
{
block.StereoBand = reader.ReadInt(4);
block.StereoBand += minBandCount;
block.StereoQuantizationUnit = Tables.BandToQuantUnitCount[block.StereoBand];
}
else
{
block.StereoBand = block.BandCount;
}
block.BandExtensionEnabled = reader.ReadBool();
if (block.BandExtensionEnabled)
{
block.ExtensionBand = reader.ReadInt(4);
block.ExtensionBand += minBandCount;
if (block.ExtensionBand < block.BandCount || block.ExtensionBand > maxExtensionBand)
{
throw new InvalidDataException();
}
block.ExtensionUnit = Tables.BandToQuantUnitCount[block.ExtensionBand];
}
else
{
block.ExtensionBand = block.BandCount;
block.ExtensionUnit = block.QuantizationUnitCount;
}
}
private static void ReadGradientParams(BitReader reader, Block block)
{
block.GradientMode = reader.ReadInt(2);
if (block.GradientMode > 0)
{
block.GradientEndUnit = 31;
block.GradientEndValue = 31;
block.GradientStartUnit = reader.ReadInt(5);
block.GradientStartValue = reader.ReadInt(5);
}
else
{
block.GradientStartUnit = reader.ReadInt(6);
block.GradientEndUnit = reader.ReadInt(6) + 1;
block.GradientStartValue = reader.ReadInt(5);
block.GradientEndValue = reader.ReadInt(5);
}
block.GradientBoundary = reader.ReadInt(4);
if (block.GradientBoundary > block.QuantizationUnitCount)
{
throw new InvalidDataException();
}
if (block.GradientStartUnit < 1 || block.GradientStartUnit >= 48)
{
throw new InvalidDataException();
}
if (block.GradientEndUnit < 1 || block.GradientEndUnit >= 48)
{
throw new InvalidDataException();
}
if (block.GradientStartUnit > block.GradientEndUnit)
{
throw new InvalidDataException();
}
if (block.GradientStartValue < 0 || block.GradientStartValue >= 32)
{
throw new InvalidDataException();
}
if (block.GradientEndValue < 0 || block.GradientEndValue >= 32)
{
throw new InvalidDataException();
}
}
private static void ReadStereoParams(BitReader reader, Block block)
{
if (block.BlockType != BlockType.Stereo) return;
block.PrimaryChannelIndex = reader.ReadInt(1);
block.HasJointStereoSigns = reader.ReadBool();
if (block.HasJointStereoSigns)
{
for (int i = block.StereoQuantizationUnit; i < block.QuantizationUnitCount; i++)
{
block.JointStereoSigns[i] = reader.ReadInt(1);
}
}
else
{
Array.Clear(block.JointStereoSigns, 0, block.JointStereoSigns.Length);
}
}
private static void ReadExtensionParams(BitReader reader, Block block)
{
// ReSharper disable once RedundantAssignment
int bexBand = 0;
if (block.BandExtensionEnabled)
{
BandExtension.GetBexBandInfo(out bexBand, out _, out _, block.QuantizationUnitCount);
if (block.BlockType == BlockType.Stereo)
{
ReadHeader(block.Channels[1]);
}
else
{
reader.Position += 1;
}
}
block.HasExtensionData = reader.ReadBool();
if (!block.HasExtensionData) return;
if (!block.BandExtensionEnabled)
{
block.BexMode = reader.ReadInt(2);
block.BexDataLength = reader.ReadInt(5);
reader.Position += block.BexDataLength;
return;
}
ReadHeader(block.Channels[0]);
block.BexDataLength = reader.ReadInt(5);
if (block.BexDataLength <= 0) return;
int bexDataEnd = reader.Position + block.BexDataLength;
ReadData(block.Channels[0]);
if (block.BlockType == BlockType.Stereo)
{
ReadData(block.Channels[1]);
}
// Make sure we didn't read too many bits
if (reader.Position > bexDataEnd)
{
throw new InvalidDataException();
}
void ReadHeader(Channel channel)
{
int bexMode = reader.ReadInt(2);
channel.BexMode = bexBand > 2 ? bexMode : 4;
channel.BexValueCount = BandExtension.BexEncodedValueCounts[channel.BexMode][bexBand];
}
void ReadData(Channel channel)
{
for (int i = 0; i < channel.BexValueCount; i++)
{
int dataLength = BandExtension.BexDataLengths[channel.BexMode][bexBand][i];
channel.BexValues[i] = reader.ReadInt(dataLength);
}
}
}
private static void CalculateSpectrumCodebookIndex(Channel channel)
{
Array.Clear(channel.CodebookSet, 0, channel.CodebookSet.Length);
int quantUnits = channel.CodedQuantUnits;
int[] sf = channel.ScaleFactors;
if (quantUnits <= 1) return;
if (channel.Config.HighSampleRate) return;
// Temporarily setting this value allows for simpler code by
// making the last value a non-special case.
int originalScaleTmp = sf[quantUnits];
sf[quantUnits] = sf[quantUnits - 1];
int avg = 0;
if (quantUnits > 12)
{
for (int i = 0; i < 12; i++)
{
avg += sf[i];
}
avg = (avg + 6) / 12;
}
for (int i = 8; i < quantUnits; i++)
{
int prevSf = sf[i - 1];
int nextSf = sf[i + 1];
int minSf = Math.Min(prevSf, nextSf);
if (sf[i] - minSf >= 3 || sf[i] - prevSf + sf[i] - nextSf >= 3)
{
channel.CodebookSet[i] = 1;
}
}
for (int i = 12; i < quantUnits; i++)
{
if (channel.CodebookSet[i] == 0)
{
int minSf = Math.Min(sf[i - 1], sf[i + 1]);
if (sf[i] - minSf >= 2 && sf[i] >= avg - (Tables.QuantUnitToCoeffCount[i] == 16 ? 1 : 0))
{
channel.CodebookSet[i] = 1;
}
}
}
sf[quantUnits] = originalScaleTmp;
}
private static void ReadSpectra(BitReader reader, Channel channel)
{
int[] values = channel.SpectraValuesBuffer;
Array.Clear(channel.QuantizedSpectra, 0, channel.QuantizedSpectra.Length);
int maxHuffPrecision = Tables.MaxHuffPrecision(channel.Config.HighSampleRate);
for (int i = 0; i < channel.CodedQuantUnits; i++)
{
int subbandCount = Tables.QuantUnitToCoeffCount[i];
int precision = channel.Precisions[i] + 1;
if (precision <= maxHuffPrecision)
{
HuffmanCodebook huff = Tables.HuffmanSpectrum[channel.CodebookSet[i]][precision][Tables.QuantUnitToCodebookIndex[i]];
int groupCount = subbandCount >> huff.ValueCountPower;
for (int j = 0; j < groupCount; j++)
{
values[j] = ReadHuffmanValue(huff, reader);
}
DecodeHuffmanValues(channel.QuantizedSpectra, Tables.QuantUnitToCoeffIndex[i], subbandCount, huff, values);
}
else
{
int subbandIndex = Tables.QuantUnitToCoeffIndex[i];
for (int j = subbandIndex; j < Tables.QuantUnitToCoeffIndex[i + 1]; j++)
{
channel.QuantizedSpectra[j] = reader.ReadSignedInt(precision);
}
}
}
}
private static void ReadSpectraFine(BitReader reader, Channel channel)
{
Array.Clear(channel.QuantizedSpectraFine, 0, channel.QuantizedSpectraFine.Length);
for (int i = 0; i < channel.CodedQuantUnits; i++)
{
if (channel.PrecisionsFine[i] > 0)
{
int overflowBits = channel.PrecisionsFine[i] + 1;
int startSubband = Tables.QuantUnitToCoeffIndex[i];
int endSubband = Tables.QuantUnitToCoeffIndex[i + 1];
for (int j = startSubband; j < endSubband; j++)
{
channel.QuantizedSpectraFine[j] = reader.ReadSignedInt(overflowBits);
}
}
}
}
private static void DecodeHuffmanValues(int[] spectrum, int index, int bandCount, HuffmanCodebook huff, int[] values)
{
int valueCount = bandCount >> huff.ValueCountPower;
int mask = (1 << huff.ValueBits) - 1;
for (int i = 0; i < valueCount; i++)
{
int value = values[i];
for (int j = 0; j < huff.ValueCount; j++)
{
spectrum[index++] = Bit.SignExtend32(value & mask, huff.ValueBits);
value >>= huff.ValueBits;
}
}
}
public static int ReadHuffmanValue(HuffmanCodebook huff, BitReader reader, bool signed = false)
{
int code = reader.PeekInt(huff.MaxBitSize);
byte value = huff.Lookup[code];
int bits = huff.Bits[value];
reader.Position += bits;
return signed ? Bit.SignExtend32(value, huff.ValueBits) : value;
}
private static void UnpackLfeBlock(BitReader reader, Block block)
{
Channel channel = block.Channels[0];
block.QuantizationUnitCount = 2;
DecodeLfeScaleFactors(reader, channel);
CalculateLfePrecision(channel);
channel.CodedQuantUnits = block.QuantizationUnitCount;
ReadLfeSpectra(reader, channel);
}
private static void DecodeLfeScaleFactors(BitReader reader, Channel channel)
{
Array.Clear(channel.ScaleFactors, 0, channel.ScaleFactors.Length);
for (int i = 0; i < channel.Block.QuantizationUnitCount; i++)
{
channel.ScaleFactors[i] = reader.ReadInt(5);
}
}
private static void CalculateLfePrecision(Channel channel)
{
Block block = channel.Block;
int precision = block.ReuseBandParams ? 8 : 4;
for (int i = 0; i < block.QuantizationUnitCount; i++)
{
channel.Precisions[i] = precision;
channel.PrecisionsFine[i] = 0;
}
}
private static void ReadLfeSpectra(BitReader reader, Channel channel)
{
Array.Clear(channel.QuantizedSpectra, 0, channel.QuantizedSpectra.Length);
for (int i = 0; i < channel.CodedQuantUnits; i++)
{
if (channel.Precisions[i] <= 0) continue;
int precision = channel.Precisions[i] + 1;
for (int j = Tables.QuantUnitToCoeffIndex[i]; j < Tables.QuantUnitToCoeffIndex[i + 1]; j++)
{
channel.QuantizedSpectra[j] = reader.ReadSignedInt(precision);
}
}
}
}
}

View File

@ -1,22 +0,0 @@
namespace LibAtrac9.Utilities
{
internal static class Bit
{
private static uint BitReverse32(uint value)
{
value = ((value & 0xaaaaaaaa) >> 1) | ((value & 0x55555555) << 1);
value = ((value & 0xcccccccc) >> 2) | ((value & 0x33333333) << 2);
value = ((value & 0xf0f0f0f0) >> 4) | ((value & 0x0f0f0f0f) << 4);
value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8);
return (value >> 16) | (value << 16);
}
private static uint BitReverse32(uint value, int bitCount) => BitReverse32(value) >> (32 - bitCount);
public static int BitReverse32(int value, int bitCount) => (int) BitReverse32((uint) value, bitCount);
public static int SignExtend32(int value, int bits)
{
int shift = 8 * sizeof(int) - bits;
return (value << shift) >> shift;
}
}
}

View File

@ -1,132 +0,0 @@
using System;
using System.Diagnostics;
namespace LibAtrac9.Utilities
{
internal class BitReader
{
private byte[] Buffer { get; set; }
private int LengthBits { get; set; }
public int Position { get; set; }
private int Remaining => LengthBits - Position;
public BitReader(byte[] buffer) => SetBuffer(buffer);
public void SetBuffer(byte[] buffer)
{
Buffer = buffer;
LengthBits = Buffer?.Length * 8 ?? 0;
Position = 0;
}
public int ReadInt(int bitCount)
{
int value = PeekInt(bitCount);
Position += bitCount;
return value;
}
public int ReadSignedInt(int bitCount)
{
int value = PeekInt(bitCount);
Position += bitCount;
return Bit.SignExtend32(value, bitCount);
}
public bool ReadBool() => ReadInt(1) == 1;
public int ReadOffsetBinary(int bitCount, OffsetBias bias)
{
int offset = (1 << (bitCount - 1)) - (int)bias;
int value = PeekInt(bitCount) - offset;
Position += bitCount;
return value;
}
public void AlignPosition(int multiple)
{
Position = Helpers.GetNextMultiple(Position, multiple);
}
public int PeekInt(int bitCount)
{
Debug.Assert(bitCount >= 0 && bitCount <= 32);
if (bitCount > Remaining)
{
if (Position >= LengthBits) return 0;
int extraBits = bitCount - Remaining;
return PeekIntFallback(Remaining) << extraBits;
}
int byteIndex = Position / 8;
int bitIndex = Position % 8;
if (bitCount <= 9 && Remaining >= 16)
{
int value = Buffer[byteIndex] << 8 | Buffer[byteIndex + 1];
value &= 0xFFFF >> bitIndex;
value >>= 16 - bitCount - bitIndex;
return value;
}
if (bitCount <= 17 && Remaining >= 24)
{
int value = Buffer[byteIndex] << 16 | Buffer[byteIndex + 1] << 8 | Buffer[byteIndex + 2];
value &= 0xFFFFFF >> bitIndex;
value >>= 24 - bitCount - bitIndex;
return value;
}
if (bitCount <= 25 && Remaining >= 32)
{
int value = Buffer[byteIndex] << 24 | Buffer[byteIndex + 1] << 16 | Buffer[byteIndex + 2] << 8 | Buffer[byteIndex + 3];
value &= (int)(0xFFFFFFFF >> bitIndex);
value >>= 32 - bitCount - bitIndex;
return value;
}
return PeekIntFallback(bitCount);
}
private int PeekIntFallback(int bitCount)
{
int value = 0;
int byteIndex = Position / 8;
int bitIndex = Position % 8;
while (bitCount > 0)
{
if (bitIndex >= 8)
{
bitIndex = 0;
byteIndex++;
}
int bitsToRead = Math.Min(bitCount, 8 - bitIndex);
int mask = 0xFF >> bitIndex;
int currentByte = (mask & Buffer[byteIndex]) >> (8 - bitIndex - bitsToRead);
value = (value << bitsToRead) | currentByte;
bitIndex += bitsToRead;
bitCount -= bitsToRead;
}
return value;
}
/// <summary>
/// Specifies the bias of an offset binary value. A positive bias can represent one more
/// positive value than negative value, and a negative bias can represent one more
/// negative value than positive value.
/// </summary>
/// <remarks>Example:
/// A 4-bit offset binary value with a positive bias can store
/// the values 8 through -7 inclusive.
/// A 4-bit offset binary value with a positive bias can store
/// the values 7 through -8 inclusive.</remarks>
public enum OffsetBias
{
Negative = 0
}
}
}

View File

@ -1,50 +0,0 @@
using System.Runtime.CompilerServices;
namespace LibAtrac9.Utilities
{
internal static class Helpers
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static short Clamp16(int value)
{
if (value > short.MaxValue)
return short.MaxValue;
if (value < short.MinValue)
return short.MinValue;
return (short)value;
}
public static int GetNextMultiple(int value, int multiple)
{
if (multiple <= 0)
return value;
if (value % multiple == 0)
return value;
return value + multiple - value % multiple;
}
/// <summary>
/// Returns the floor of the base 2 logarithm of a specified number.
/// </summary>
/// <param name="value">The number whose logarithm is to be found.</param>
/// <returns>The floor of the base 2 logarithm of <paramref name="value"/>.</returns>
public static int Log2(int value)
{
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
return MultiplyDeBruijnBitPosition[(uint)(value * 0x07C4ACDDU) >> 27];
}
private static readonly int[] MultiplyDeBruijnBitPosition =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
}
}

View File

@ -1,177 +0,0 @@
using System;
using System.Collections.Generic;
namespace LibAtrac9.Utilities
{
internal class Mdct
{
private int MdctBits { get; }
private int MdctSize { get; }
private double Scale { get; }
private static readonly object TableLock = new object();
private static int _tableBits = -1;
private static readonly List<double[]> SinTables = new List<double[]>();
private static readonly List<double[]> CosTables = new List<double[]>();
private static readonly List<int[]> ShuffleTables = new List<int[]>();
private readonly double[] _imdctPrevious;
private readonly double[] _imdctWindow;
private readonly double[] _scratchMdct;
private readonly double[] _scratchDct;
public Mdct(int mdctBits, double[] window, double scale = 1)
{
SetTables(mdctBits);
MdctBits = mdctBits;
MdctSize = 1 << mdctBits;
Scale = scale;
if (window.Length < MdctSize)
{
throw new ArgumentException("Window must be as long as the MDCT size.", nameof(window));
}
_imdctPrevious = new double[MdctSize];
_scratchMdct = new double[MdctSize];
_scratchDct = new double[MdctSize];
_imdctWindow = window;
}
private static void SetTables(int maxBits)
{
lock (TableLock)
{
if (maxBits > _tableBits)
{
for (int i = _tableBits + 1; i <= maxBits; i++)
{
GenerateTrigTables(i, out double[] sin, out double[] cos);
SinTables.Add(sin);
CosTables.Add(cos);
ShuffleTables.Add(GenerateShuffleTable(i));
}
_tableBits = maxBits;
}
}
}
public void RunImdct(double[] input, double[] output)
{
if (input.Length < MdctSize)
{
throw new ArgumentException("Input must be as long as the MDCT size.", nameof(input));
}
if (output.Length < MdctSize)
{
throw new ArgumentException("Output must be as long as the MDCT size.", nameof(output));
}
int size = MdctSize;
int half = size / 2;
double[] dctOut = _scratchMdct;
Dct4(input, dctOut);
for (int i = 0; i < half; i++)
{
output[i] = _imdctWindow[i] * dctOut[i + half] + _imdctPrevious[i];
output[i + half] = _imdctWindow[i + half] * -dctOut[size - 1 - i] - _imdctPrevious[i + half];
_imdctPrevious[i] = _imdctWindow[size - 1 - i] * -dctOut[half - i - 1];
_imdctPrevious[i + half] = _imdctWindow[half - i - 1] * dctOut[i];
}
}
/// <summary>
/// Does a Type-4 DCT.
/// </summary>
/// <param name="input">The input array containing the time or frequency-domain samples</param>
/// <param name="output">The output array that will contain the transformed time or frequency-domain samples</param>
private void Dct4(double[] input, double[] output)
{
int[] shuffleTable = ShuffleTables[MdctBits];
double[] sinTable = SinTables[MdctBits];
double[] cosTable = CosTables[MdctBits];
double[] dctTemp = _scratchDct;
int size = MdctSize;
int lastIndex = size - 1;
int halfSize = size / 2;
for (int i = 0; i < halfSize; i++)
{
int i2 = i * 2;
double a = input[i2];
double b = input[lastIndex - i2];
double sin = sinTable[i];
double cos = cosTable[i];
dctTemp[i2] = a * cos + b * sin;
dctTemp[i2 + 1] = a * sin - b * cos;
}
int stageCount = MdctBits - 1;
for (int stage = 0; stage < stageCount; stage++)
{
int blockCount = 1 << stage;
int blockSizeBits = stageCount - stage;
int blockHalfSizeBits = blockSizeBits - 1;
int blockSize = 1 << blockSizeBits;
int blockHalfSize = 1 << blockHalfSizeBits;
sinTable = SinTables[blockHalfSizeBits];
cosTable = CosTables[blockHalfSizeBits];
for (int block = 0; block < blockCount; block++)
{
for (int i = 0; i < blockHalfSize; i++)
{
int frontPos = (block * blockSize + i) * 2;
int backPos = frontPos + blockSize;
double a = dctTemp[frontPos] - dctTemp[backPos];
double b = dctTemp[frontPos + 1] - dctTemp[backPos + 1];
double sin = sinTable[i];
double cos = cosTable[i];
dctTemp[frontPos] += dctTemp[backPos];
dctTemp[frontPos + 1] += dctTemp[backPos + 1];
dctTemp[backPos] = a * cos + b * sin;
dctTemp[backPos + 1] = a * sin - b * cos;
}
}
}
for (int i = 0; i < MdctSize; i++)
{
output[i] = dctTemp[shuffleTable[i]] * Scale;
}
}
internal static void GenerateTrigTables(int sizeBits, out double[] sin, out double[] cos)
{
int size = 1 << sizeBits;
sin = new double[size];
cos = new double[size];
for (int i = 0; i < size; i++)
{
double value = Math.PI * (4 * i + 1) / (4 * size);
sin[i] = Math.Sin(value);
cos[i] = Math.Cos(value);
}
}
internal static int[] GenerateShuffleTable(int sizeBits)
{
int size = 1 << sizeBits;
var table = new int[size];
for (int i = 0; i < size; i++)
{
table[i] = Bit.BitReverse32(i ^ (i / 2), sizeBits);
}
return table;
}
}
}

View File

@ -119,7 +119,7 @@
TargetAttributes = {
83D3C67A201D37D8005564CB = {
CreatedOnToolsVersion = 9.2;
ProvisioningStyle = Automatic;
ProvisioningStyle = Manual;
};
};
};
@ -283,9 +283,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
@ -296,6 +296,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libbinio;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Debug;
@ -304,9 +305,9 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_STYLE = Automatic;
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
@ -317,6 +318,7 @@
MACOSX_DEPLOYMENT_TARGET = 10.7;
PRODUCT_BUNDLE_IDENTIFIER = net.kode54.libbinio;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
};
name = Release;

View File

@ -320,6 +320,12 @@
attributes = {
LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Christopher Snowhill";
TargetAttributes = {
8313E30E1901FBDC00B4B6F1 = {
DevelopmentTeam = N6E749HJ2X;
ProvisioningStyle = Manual;
};
};
};
buildConfigurationList = 8313E3091901FBDC00B4B6F1 /* Build configuration list for PBXProject "mpg123" */;
compatibilityVersion = "Xcode 3.2";
@ -446,7 +452,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
SKIP_INSTALL = YES;
};
@ -494,7 +500,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INSTALL_PATH = "@loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.7;
MACOSX_DEPLOYMENT_TARGET = 10.8;
SKIP_INSTALL = YES;
};
name = Release;
@ -502,13 +508,17 @@
8313E3381901FBDC00B4B6F1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;
INFOPLIST_FILE = "mpg123/mpg123-Info.plist";
PRODUCT_BUNDLE_IDENTIFIER = "NoWork-Inc.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
WRAPPER_EXTENSION = framework;
};
name = Debug;
@ -516,8 +526,9 @@
8313E3391901FBDC00B4B6F1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "";
CODE_SIGN_IDENTITY = "-";
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = N6E749HJ2X;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_VERSION = A;

View File

@ -68,8 +68,6 @@
830EBE102004655D0023AA10 /* atrac9_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBE0F2004655D0023AA10 /* atrac9_decoder.c */; };
830EBE132004656E0023AA10 /* xnb.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBE112004656E0023AA10 /* xnb.c */; };
830EBE142004656E0023AA10 /* ktss.c in Sources */ = {isa = PBXBuildFile; fileRef = 830EBE122004656E0023AA10 /* ktss.c */; };
830EBE19200465B00023AA10 /* libatrac9.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 830EBD9720045F1B0023AA10 /* libatrac9.framework */; };
830EBE1A200465C00023AA10 /* libatrac9.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 830EBD9720045F1B0023AA10 /* libatrac9.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
8313E3E61902020400B4B6F1 /* mpg123.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8313E3431901FBDD00B4B6F1 /* mpg123.framework */; };
8313E3E71902021800B4B6F1 /* mpg123.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8313E3431901FBDD00B4B6F1 /* mpg123.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8315958720FEC832007002F0 /* asf_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8315958320FEC831007002F0 /* asf_decoder.c */; };
@ -214,6 +212,8 @@
8351F32F2212B57000A606E4 /* dsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8351F32C2212B57000A606E4 /* dsf.c */; };
835C883622CC17BE001B4B3F /* bwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 835C883122CC17BD001B4B3F /* bwav.c */; };
835C883722CC17BE001B4B3F /* ogg_vorbis_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 835C883522CC17BE001B4B3F /* ogg_vorbis_streamfile.h */; };
836C052B23F62F1A00FA07C7 /* libatrac9.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 835FC6C623F62AEF006960FA /* libatrac9.framework */; };
836C052C23F62F3100FA07C7 /* libatrac9.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835FC6C623F62AEF006960FA /* libatrac9.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
836F6B4718BDB8880095E648 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 836F6B4518BDB8880095E648 /* InfoPlist.strings */; };
836F6F1E18BDC2190095E648 /* acm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6DE018BDC2180095E648 /* acm_decoder.c */; };
836F6F2018BDC2190095E648 /* adx_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6DE218BDC2180095E648 /* adx_decoder.c */; };
@ -437,6 +437,23 @@
83709E091ECBC1A4005C03D3 /* ta_aac.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E031ECBC1A4005C03D3 /* ta_aac.c */; };
83709E0D1ECBC1C3005C03D3 /* mc3_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E0B1ECBC1C3005C03D3 /* mc3_decoder.c */; };
83709E0E1ECBC1C3005C03D3 /* psv_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E0C1ECBC1C3005C03D3 /* psv_decoder.c */; };
8373341623F60C7B00DE14DC /* g7221_decoder_aes.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373340E23F60C7A00DE14DC /* g7221_decoder_aes.h */; };
8373341723F60C7B00DE14DC /* g7221_decoder_aes.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373340F23F60C7A00DE14DC /* g7221_decoder_aes.c */; };
8373341823F60C7B00DE14DC /* tgcadpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373341023F60C7A00DE14DC /* tgcadpcm_decoder.c */; };
8373341923F60C7B00DE14DC /* g7221_decoder_lib_data.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341123F60C7A00DE14DC /* g7221_decoder_lib_data.h */; };
8373341A23F60C7B00DE14DC /* relic_decoder_mixfft.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373341223F60C7B00DE14DC /* relic_decoder_mixfft.c */; };
8373341B23F60C7B00DE14DC /* g7221_decoder_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373341323F60C7B00DE14DC /* g7221_decoder_lib.c */; };
8373341C23F60C7B00DE14DC /* relic_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373341423F60C7B00DE14DC /* relic_decoder.c */; };
8373341D23F60C7B00DE14DC /* g7221_decoder_lib.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341523F60C7B00DE14DC /* g7221_decoder_lib.h */; };
8373342623F60CDC00DE14DC /* deblock_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341E23F60CDB00DE14DC /* deblock_streamfile.h */; };
8373342723F60CDC00DE14DC /* lrmd_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */; };
8373342823F60CDC00DE14DC /* fda.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342023F60CDB00DE14DC /* fda.c */; };
8373342923F60CDC00DE14DC /* deblock_streamfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342123F60CDB00DE14DC /* deblock_streamfile.c */; };
8373342A23F60CDC00DE14DC /* lrmd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342223F60CDB00DE14DC /* lrmd.c */; };
8373342B23F60CDC00DE14DC /* fwse.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342323F60CDB00DE14DC /* fwse.c */; };
8373342C23F60CDC00DE14DC /* kwb.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342423F60CDB00DE14DC /* kwb.c */; };
8373342D23F60CDC00DE14DC /* bnsf_keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373342523F60CDC00DE14DC /* bnsf_keys.h */; };
8373342F23F60D4100DE14DC /* tgc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8373342E23F60D4100DE14DC /* tgc.c */; };
8375737321F9507D00F01AF5 /* oki_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8375737221F9507D00F01AF5 /* oki_decoder.c */; };
8375737621F950ED00F01AF5 /* gin.c in Sources */ = {isa = PBXBuildFile; fileRef = 8375737421F950EC00F01AF5 /* gin.c */; };
8375737721F950ED00F01AF5 /* ubi_sb_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8375737521F950EC00F01AF5 /* ubi_sb_streamfile.h */; };
@ -444,7 +461,6 @@
837CEA7923487E2500E62A4A /* ubi_adpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEA7623487E2400E62A4A /* ubi_adpcm_decoder.c */; };
837CEA7A23487E2500E62A4A /* ffmpeg_decoder_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEA7723487E2400E62A4A /* ffmpeg_decoder_utils.c */; };
837CEAD823487E8300E62A4A /* bmp_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAD423487E8300E62A4A /* bmp_konami.c */; };
837CEAD923487E8300E62A4A /* acb_utf.h in Headers */ = {isa = PBXBuildFile; fileRef = 837CEAD523487E8300E62A4A /* acb_utf.h */; };
837CEADA23487E8300E62A4A /* acb.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEAD623487E8300E62A4A /* acb.c */; };
837CEADB23487E8300E62A4A /* bgw_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 837CEAD723487E8300E62A4A /* bgw_streamfile.h */; };
837CEAF123487F2C00E62A4A /* xvas.c in Sources */ = {isa = PBXBuildFile; fileRef = 837CEADC23487F2900E62A4A /* xvas.c */; };
@ -550,8 +566,6 @@
83C7282A22BC8C1500678B4A /* plugins.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C7282622BC8C1400678B4A /* plugins.c */; };
83CD428A1F787879000F77BE /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83CD42851F787878000F77BE /* libswresample.a */; };
83D2F58E2356B266007646ED /* libopus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D2F58A2356B266007646ED /* libopus.a */; };
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; };
83D731111A7394D300CA1366 /* g7221.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83D731891A749D1500CA1366 /* g719.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D7313E1A74968A00CA1366 /* g719.framework */; };
83D7318A1A749D2200CA1366 /* g719.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83D7313E1A74968A00CA1366 /* g719.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83D7318C1A749EEE00CA1366 /* g719_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83D7318B1A749EEE00CA1366 /* g719_decoder.c */; };
@ -588,20 +602,6 @@
/* End PBXBuildRule section */
/* Begin PBXContainerItemProxy section */
830EBD9620045F1B0023AA10 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 830EBD9220045F190023AA10 /* libatrac9.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 830EBD8720045F190023AA10;
remoteInfo = libatrac9;
};
830EBE152004659B0023AA10 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 830EBD9220045F190023AA10 /* libatrac9.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 830EBD8620045F190023AA10;
remoteInfo = libatrac9;
};
8313E3421901FBDD00B4B6F1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */;
@ -623,19 +623,19 @@
remoteGlobalIDString = 730F23A1091827B100AB638C;
remoteInfo = Vorbis;
};
83D730EA1A738EB300CA1366 /* PBXContainerItemProxy */ = {
835FC6C523F62AEF006960FA /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83D730E51A738EB200CA1366 /* g7221.xcodeproj */;
containerPortal = 835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 83D730C91A738EB200CA1366;
remoteInfo = g7221;
remoteGlobalIDString = 835FC6B023F61BF0006960FA;
remoteInfo = libatrac9;
};
83D7310E1A7394B500CA1366 /* PBXContainerItemProxy */ = {
836C052523F62F0000FA07C7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83D730E51A738EB200CA1366 /* g7221.xcodeproj */;
containerPortal = 835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 83D730C81A738EB200CA1366;
remoteInfo = g7221;
remoteGlobalIDString = 835FC6AF23F61BF0006960FA;
remoteInfo = libatrac9;
};
83D7313D1A74968A00CA1366 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@ -688,10 +688,9 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
830EBE1A200465C00023AA10 /* libatrac9.framework in CopyFiles */,
836C052C23F62F3100FA07C7 /* libatrac9.framework in CopyFiles */,
832C70BF1E9335E400BD7B4E /* Vorbis.framework in CopyFiles */,
83D7318A1A749D2200CA1366 /* g719.framework in CopyFiles */,
83D731111A7394D300CA1366 /* g7221.framework in CopyFiles */,
8313E3E71902021800B4B6F1 /* mpg123.framework in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -757,7 +756,6 @@
8306B0D520984590000302D4 /* atsl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atsl.c; sourceTree = "<group>"; };
8306B0D620984590000302D4 /* ppst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ppst.c; sourceTree = "<group>"; };
8306B0D720984590000302D4 /* ubi_jade.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_jade.c; sourceTree = "<group>"; };
830EBD9220045F190023AA10 /* libatrac9.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libatrac9.xcodeproj; path = ../libatrac9/libatrac9.xcodeproj; sourceTree = "<group>"; };
830EBE0F2004655D0023AA10 /* atrac9_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = atrac9_decoder.c; sourceTree = "<group>"; };
830EBE112004656E0023AA10 /* xnb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xnb.c; sourceTree = "<group>"; };
830EBE122004656E0023AA10 /* ktss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ktss.c; sourceTree = "<group>"; };
@ -903,6 +901,7 @@
8351F32C2212B57000A606E4 /* dsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsf.c; sourceTree = "<group>"; };
835C883122CC17BD001B4B3F /* bwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bwav.c; sourceTree = "<group>"; };
835C883522CC17BE001B4B3F /* ogg_vorbis_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ogg_vorbis_streamfile.h; sourceTree = "<group>"; };
835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libatrac9.xcodeproj; path = ../libatrac9/libatrac9.xcodeproj; sourceTree = "<group>"; };
836F6B3918BDB8880095E648 /* libvgmstream.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libvgmstream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
836F6B4418BDB8880095E648 /* libvgmstream-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "libvgmstream-Info.plist"; sourceTree = "<group>"; };
836F6B4618BDB8880095E648 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@ -1128,6 +1127,23 @@
83709E031ECBC1A4005C03D3 /* ta_aac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ta_aac.c; sourceTree = "<group>"; };
83709E0B1ECBC1C3005C03D3 /* mc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3_decoder.c; sourceTree = "<group>"; };
83709E0C1ECBC1C3005C03D3 /* psv_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = psv_decoder.c; sourceTree = "<group>"; };
8373340E23F60C7A00DE14DC /* g7221_decoder_aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g7221_decoder_aes.h; sourceTree = "<group>"; };
8373340F23F60C7A00DE14DC /* g7221_decoder_aes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g7221_decoder_aes.c; sourceTree = "<group>"; };
8373341023F60C7A00DE14DC /* tgcadpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tgcadpcm_decoder.c; sourceTree = "<group>"; };
8373341123F60C7A00DE14DC /* g7221_decoder_lib_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g7221_decoder_lib_data.h; sourceTree = "<group>"; };
8373341223F60C7B00DE14DC /* relic_decoder_mixfft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = relic_decoder_mixfft.c; sourceTree = "<group>"; };
8373341323F60C7B00DE14DC /* g7221_decoder_lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g7221_decoder_lib.c; sourceTree = "<group>"; };
8373341423F60C7B00DE14DC /* relic_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = relic_decoder.c; sourceTree = "<group>"; };
8373341523F60C7B00DE14DC /* g7221_decoder_lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = g7221_decoder_lib.h; sourceTree = "<group>"; };
8373341E23F60CDB00DE14DC /* deblock_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deblock_streamfile.h; sourceTree = "<group>"; };
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lrmd_streamfile.h; sourceTree = "<group>"; };
8373342023F60CDB00DE14DC /* fda.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fda.c; sourceTree = "<group>"; };
8373342123F60CDB00DE14DC /* deblock_streamfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = deblock_streamfile.c; sourceTree = "<group>"; };
8373342223F60CDB00DE14DC /* lrmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lrmd.c; sourceTree = "<group>"; };
8373342323F60CDB00DE14DC /* fwse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fwse.c; sourceTree = "<group>"; };
8373342423F60CDB00DE14DC /* kwb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kwb.c; sourceTree = "<group>"; };
8373342523F60CDC00DE14DC /* bnsf_keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bnsf_keys.h; sourceTree = "<group>"; };
8373342E23F60D4100DE14DC /* tgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tgc.c; sourceTree = "<group>"; };
8375737221F9507D00F01AF5 /* oki_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oki_decoder.c; sourceTree = "<group>"; };
8375737421F950EC00F01AF5 /* gin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gin.c; sourceTree = "<group>"; };
8375737521F950EC00F01AF5 /* ubi_sb_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubi_sb_streamfile.h; sourceTree = "<group>"; };
@ -1135,7 +1151,6 @@
837CEA7623487E2400E62A4A /* ubi_adpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_adpcm_decoder.c; sourceTree = "<group>"; };
837CEA7723487E2400E62A4A /* ffmpeg_decoder_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ffmpeg_decoder_utils.c; sourceTree = "<group>"; };
837CEAD423487E8300E62A4A /* bmp_konami.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bmp_konami.c; sourceTree = "<group>"; };
837CEAD523487E8300E62A4A /* acb_utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = acb_utf.h; sourceTree = "<group>"; };
837CEAD623487E8300E62A4A /* acb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = acb.c; sourceTree = "<group>"; };
837CEAD723487E8300E62A4A /* bgw_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgw_streamfile.h; sourceTree = "<group>"; };
837CEADC23487F2900E62A4A /* xvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xvas.c; sourceTree = "<group>"; };
@ -1240,7 +1255,6 @@
83C7282622BC8C1400678B4A /* plugins.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = plugins.c; sourceTree = "<group>"; };
83CD42851F787878000F77BE /* libswresample.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libswresample.a; path = ../../ThirdParty/ffmpeg/lib/libswresample.a; sourceTree = "<group>"; };
83D2F58A2356B266007646ED /* libopus.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopus.a; path = ../../ThirdParty/ffmpeg/lib/libopus.a; sourceTree = "<group>"; };
83D730E51A738EB200CA1366 /* g7221.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g7221.xcodeproj; path = ../g7221/g7221.xcodeproj; sourceTree = "<group>"; };
83D731381A74968900CA1366 /* g719.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g719.xcodeproj; path = ../g719/g719.xcodeproj; sourceTree = "<group>"; };
83D7318B1A749EEE00CA1366 /* g719_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = g719_decoder.c; sourceTree = "<group>"; };
83E56BA01F2EE3500026BC60 /* vorbis_custom_utils_ogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_utils_ogl.c; sourceTree = "<group>"; };
@ -1267,7 +1281,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
830EBE19200465B00023AA10 /* libatrac9.framework in Frameworks */,
838BDB7F1D3B1FD10022CA6F /* Cocoa.framework in Frameworks */,
838BDB7D1D3B1FCC0022CA6F /* CoreVideo.framework in Frameworks */,
838BDB7B1D3B1FC20022CA6F /* CoreMedia.framework in Frameworks */,
@ -1281,26 +1294,18 @@
83D2F58E2356B266007646ED /* libopus.a in Frameworks */,
83CD428A1F787879000F77BE /* libswresample.a in Frameworks */,
83D731891A749D1500CA1366 /* g719.framework in Frameworks */,
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */,
838BDB641D3AF08C0022CA6F /* libavcodec.a in Frameworks */,
838BDB651D3AF08C0022CA6F /* libavformat.a in Frameworks */,
838BDB661D3AF08C0022CA6F /* libavutil.a in Frameworks */,
8313E3E61902020400B4B6F1 /* mpg123.framework in Frameworks */,
834D795520E4F0D400C4A5CC /* Vorbis.framework in Frameworks */,
836C052B23F62F1A00FA07C7 /* libatrac9.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
830EBD9320045F190023AA10 /* Products */ = {
isa = PBXGroup;
children = (
830EBD9720045F1B0023AA10 /* libatrac9.framework */,
);
name = Products;
sourceTree = "<group>";
};
8313E33E1901FBDC00B4B6F1 /* Products */ = {
isa = PBXGroup;
children = (
@ -1318,6 +1323,14 @@
path = ext_libs;
sourceTree = "<group>";
};
835FC6C223F62AEE006960FA /* Products */ = {
isa = PBXGroup;
children = (
835FC6C623F62AEF006960FA /* libatrac9.framework */,
);
name = Products;
sourceTree = "<group>";
};
836F6B2F18BDB8880095E648 = {
isa = PBXGroup;
children = (
@ -1358,14 +1371,13 @@
836F6B3E18BDB8880095E648 /* Other Frameworks */ = {
isa = PBXGroup;
children = (
830EBD9220045F190023AA10 /* libatrac9.xcodeproj */,
835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */,
838BDB611D3AF08C0022CA6F /* libavcodec.a */,
838BDB621D3AF08C0022CA6F /* libavformat.a */,
838BDB631D3AF08C0022CA6F /* libavutil.a */,
83CD42851F787878000F77BE /* libswresample.a */,
8313E33D1901FBDC00B4B6F1 /* mpg123.xcodeproj */,
83F412871E932F9A002E37D0 /* Vorbis.xcodeproj */,
83D730E51A738EB200CA1366 /* g7221.xcodeproj */,
83D731381A74968900CA1366 /* g719.xcodeproj */,
);
name = "Other Frameworks";
@ -1441,6 +1453,11 @@
836F6DE918BDC2180095E648 /* g72x_state.h */,
83D7318B1A749EEE00CA1366 /* g719_decoder.c */,
836F6DE718BDC2180095E648 /* g721_decoder.c */,
8373340F23F60C7A00DE14DC /* g7221_decoder_aes.c */,
8373340E23F60C7A00DE14DC /* g7221_decoder_aes.h */,
8373341123F60C7A00DE14DC /* g7221_decoder_lib_data.h */,
8373341323F60C7B00DE14DC /* g7221_decoder_lib.c */,
8373341523F60C7B00DE14DC /* g7221_decoder_lib.h */,
836F6DE818BDC2180095E648 /* g7221_decoder.c */,
832389511D224C0800482226 /* hca_decoder.c */,
836F6DEA18BDC2180095E648 /* ima_decoder.c */,
@ -1470,8 +1487,11 @@
83709E0C1ECBC1C3005C03D3 /* psv_decoder.c */,
836F6DFA18BDC2180095E648 /* psx_decoder.c */,
837CEA7523487E2400E62A4A /* ptadpcm_decoder.c */,
8373341223F60C7B00DE14DC /* relic_decoder_mixfft.c */,
8373341423F60C7B00DE14DC /* relic_decoder.c */,
836F6DFB18BDC2180095E648 /* SASSC_decoder.c */,
836F6DFC18BDC2180095E648 /* sdx2_decoder.c */,
8373341023F60C7A00DE14DC /* tgcadpcm_decoder.c */,
837CEA7623487E2400E62A4A /* ubi_adpcm_decoder.c */,
839E21D61F2EDAF000EE54D7 /* vorbis_custom_data_fsb.h */,
839E21DC1F2EDAF000EE54D7 /* vorbis_custom_data_wwise.h */,
@ -1550,7 +1570,6 @@
8351F32A2212B57000A606E4 /* 208.c */,
834FE0C8215C79E7000A5D3D /* a2m.c */,
836F6E2A18BDC2180095E648 /* aax.c */,
837CEAD523487E8300E62A4A /* acb_utf.h */,
837CEAD623487E8300E62A4A /* acb.c */,
836F6E2B18BDC2180095E648 /* acm.c */,
834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */,
@ -1588,6 +1607,7 @@
83299FCE1E7660C7003A3242 /* bik.c */,
837CEAD423487E8300E62A4A /* bmp_konami.c */,
834FE0CA215C79E7000A5D3D /* bnk_sony.c */,
8373342523F60CDC00DE14DC /* bnsf_keys.h */,
836F6E3918BDC2180095E648 /* bnsf.c */,
836F6E3A18BDC2180095E648 /* brstm.c */,
83EDE5D71A70951A005F5D84 /* btsnd.c */,
@ -1605,6 +1625,8 @@
836F6E4018BDC2180095E648 /* dc_kcey.c */,
836F6E4118BDC2180095E648 /* dc_str.c */,
83C7280C22BC893D00678B4A /* dcs_wav.c */,
8373342123F60CDB00DE14DC /* deblock_streamfile.c */,
8373341E23F60CDB00DE14DC /* deblock_streamfile.h */,
8349A8EE1FE6257C00E26435 /* dec.c */,
834FE0CD215C79E8000A5D3D /* derf.c */,
836F6E4318BDC2180095E648 /* dmsg_segh.c */,
@ -1625,6 +1647,7 @@
836F6E4A18BDC2180095E648 /* excitebots.c */,
8349A8EF1FE6257C00E26435 /* ezw.c */,
832BF80821E05135006F50F1 /* fag.c */,
8373342023F60CDB00DE14DC /* fda.c */,
83C7280022BC893A00678B4A /* ffdl.c */,
838BDB6D1D3B043C0022CA6F /* ffmpeg.c */,
836F6E4B18BDC2180095E648 /* ffw.c */,
@ -1636,6 +1659,7 @@
83C7280522BC893B00678B4A /* fsb5_fev.c */,
834FE0E3215C79EC000A5D3D /* fsb5_interleave_streamfile.h */,
83F5F8821908D0A400C8E65F /* fsb5.c */,
8373342323F60CDB00DE14DC /* fwse.c */,
834D3A6D19F47C98001C54F6 /* g1l.c */,
836F6E4D18BDC2180095E648 /* gca.c */,
836F6E4E18BDC2180095E648 /* gcsw.c */,
@ -1666,6 +1690,9 @@
83A21F83201D8981000F04B9 /* kma9.c */,
836F6E5918BDC2180095E648 /* kraw.c */,
830EBE122004656E0023AA10 /* ktss.c */,
8373342423F60CDB00DE14DC /* kwb.c */,
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */,
8373342223F60CDB00DE14DC /* lrmd.c */,
836F6E5A18BDC2180095E648 /* lsf.c */,
836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */,
836F6E5D18BDC2180095E648 /* maxis_xa.c */,
@ -1868,6 +1895,7 @@
836F6EF918BDC2190095E648 /* svs.c */,
831BA6121EAC61A500CF89B0 /* sxd.c */,
83709E031ECBC1A4005C03D3 /* ta_aac.c */,
8373342E23F60D4100DE14DC /* tgc.c */,
836F6EFA18BDC2190095E648 /* thp.c */,
836F6EFB18BDC2190095E648 /* tun.c */,
83C7280122BC893A00678B4A /* txth_streamfile.h */,
@ -1956,14 +1984,6 @@
path = meta;
sourceTree = "<group>";
};
83D730E61A738EB200CA1366 /* Products */ = {
isa = PBXGroup;
children = (
83D730EB1A738EB300CA1366 /* g7221.framework */,
);
name = Products;
sourceTree = "<group>";
};
83D731391A74968900CA1366 /* Products */ = {
isa = PBXGroup;
children = (
@ -2013,6 +2033,7 @@
839E21E01F2EDAF100EE54D7 /* vorbis_custom_data_fsb.h in Headers */,
836F705418BDC2190095E648 /* streamfile.h in Headers */,
83A3F0761E3AD8B900D6A794 /* stack_alloc.h in Headers */,
8373342723F60CDC00DE14DC /* lrmd_streamfile.h in Headers */,
8323894B1D22419B00482226 /* clHCA.h in Headers */,
83C7281122BC893D00678B4A /* 9tav_streamfile.h in Headers */,
83C7280F22BC893D00678B4A /* xwb_xsb.h in Headers */,
@ -2020,15 +2041,16 @@
839E21E81F2EDAF100EE54D7 /* mpeg_decoder.h in Headers */,
834FE10C215C79ED000A5D3D /* fsb5_interleave_streamfile.h in Headers */,
839E21E51F2EDAF100EE54D7 /* vorbis_custom_decoder.h in Headers */,
837CEAD923487E8300E62A4A /* acb_utf.h in Headers */,
837CEADB23487E8300E62A4A /* bgw_streamfile.h in Headers */,
837CEB0323487F2C00E62A4A /* xavs_streamfile.h in Headers */,
8306B0E120984590000302D4 /* ubi_lyn_ogg_streamfile.h in Headers */,
836F705918BDC2190095E648 /* vgmstream.h in Headers */,
8373342623F60CDC00DE14DC /* deblock_streamfile.h in Headers */,
83C7281522BC893D00678B4A /* txth_streamfile.h in Headers */,
8306B0DE20984590000302D4 /* awc_xma_streamfile.h in Headers */,
834FE0B5215C798C000A5D3D /* acm_decoder_libacm.h in Headers */,
839E21E61F2EDAF100EE54D7 /* vorbis_custom_data_wwise.h in Headers */,
8373342D23F60CDC00DE14DC /* bnsf_keys.h in Headers */,
834FE103215C79ED000A5D3D /* ea_schl_streamfile.h in Headers */,
83F0AA6021E2028C004BBC04 /* vsv_streamfile.h in Headers */,
83FBD506235D31F800D35BCD /* riff_ogg_streamfile.h in Headers */,
@ -2037,7 +2059,10 @@
836F6F9A18BDC2190095E648 /* meta.h in Headers */,
8306B0D820984590000302D4 /* ea_eaac_streamfile.h in Headers */,
837CEB0523487F2C00E62A4A /* sqex_sead_streamfile.h in Headers */,
8373341D23F60C7B00DE14DC /* g7221_decoder_lib.h in Headers */,
8306B0E820984590000302D4 /* opus_interleave_streamfile.h in Headers */,
8373341623F60C7B00DE14DC /* g7221_decoder_aes.h in Headers */,
8373341923F60C7B00DE14DC /* g7221_decoder_lib_data.h in Headers */,
83AFABBD23795202002F3947 /* ea_eaac_opus_streamfile.h in Headers */,
83C7281822BC893D00678B4A /* sfh_streamfile.h in Headers */,
834FE0EF215C79ED000A5D3D /* xvag_streamfile.h in Headers */,
@ -2068,10 +2093,9 @@
48C265101A5D424500A0A3D6 /* PBXBuildRule */,
);
dependencies = (
836C052623F62F0000FA07C7 /* PBXTargetDependency */,
834D795420E4F0B900C4A5CC /* PBXTargetDependency */,
830EBE162004659B0023AA10 /* PBXTargetDependency */,
83D731881A749D0D00CA1366 /* PBXTargetDependency */,
83D7310F1A7394B500CA1366 /* PBXTargetDependency */,
8313E3E91902021F00B4B6F1 /* PBXTargetDependency */,
);
name = libvgmstream;
@ -2111,12 +2135,8 @@
ProjectRef = 83D731381A74968900CA1366 /* g719.xcodeproj */;
},
{
ProductGroup = 83D730E61A738EB200CA1366 /* Products */;
ProjectRef = 83D730E51A738EB200CA1366 /* g7221.xcodeproj */;
},
{
ProductGroup = 830EBD9320045F190023AA10 /* Products */;
ProjectRef = 830EBD9220045F190023AA10 /* libatrac9.xcodeproj */;
ProductGroup = 835FC6C223F62AEE006960FA /* Products */;
ProjectRef = 835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */;
},
{
ProductGroup = 8313E33E1901FBDC00B4B6F1 /* Products */;
@ -2135,13 +2155,6 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
830EBD9720045F1B0023AA10 /* libatrac9.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = libatrac9.framework;
remoteRef = 830EBD9620045F1B0023AA10 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
8313E3431901FBDD00B4B6F1 /* mpg123.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
@ -2149,11 +2162,11 @@
remoteRef = 8313E3421901FBDD00B4B6F1 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
83D730EB1A738EB300CA1366 /* g7221.framework */ = {
835FC6C623F62AEF006960FA /* libatrac9.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = g7221.framework;
remoteRef = 83D730EA1A738EB300CA1366 /* PBXContainerItemProxy */;
path = libatrac9.framework;
remoteRef = 835FC6C523F62AEF006960FA /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
83D7313E1A74968A00CA1366 /* g719.framework */ = {
@ -2239,6 +2252,7 @@
836F6FAD18BDC2190095E648 /* ngc_dsp_konami.c in Sources */,
836F6FF818BDC2190095E648 /* ps2_smpl.c in Sources */,
836F703818BDC2190095E648 /* ubi_ckd.c in Sources */,
8373341B23F60C7B00DE14DC /* g7221_decoder_lib.c in Sources */,
836F705318BDC2190095E648 /* streamfile.c in Sources */,
836F6F7418BDC2190095E648 /* bgw.c in Sources */,
836F6F7218BDC2190095E648 /* baf.c in Sources */,
@ -2247,6 +2261,7 @@
836F700C18BDC2190095E648 /* ps2_wb.c in Sources */,
836F6F7D18BDC2190095E648 /* dc_str.c in Sources */,
83A5F75F198DF021009AF94C /* bfwav.c in Sources */,
8373341723F60C7B00DE14DC /* g7221_decoder_aes.c in Sources */,
836F702018BDC2190095E648 /* rkv.c in Sources */,
834FE0F4215C79ED000A5D3D /* wsi.c in Sources */,
836F703218BDC2190095E648 /* str_asr.c in Sources */,
@ -2281,6 +2296,7 @@
836F702318BDC2190095E648 /* rsf.c in Sources */,
834FE109215C79ED000A5D3D /* idsp_ie.c in Sources */,
83299FD01E7660C7003A3242 /* bik.c in Sources */,
8373341823F60C7B00DE14DC /* tgcadpcm_decoder.c in Sources */,
836F6F3318BDC2190095E648 /* ngc_dtk_decoder.c in Sources */,
83C7281322BC893D00678B4A /* mta2.c in Sources */,
8306B0EF20984590000302D4 /* ubi_bao.c in Sources */,
@ -2382,6 +2398,7 @@
836F6F6F18BDC2190095E648 /* akb.c in Sources */,
83EED5D6203A8BD7008BEB45 /* blocked_ea_swvr.c in Sources */,
8349A9181FE6258200E26435 /* ea_1snh.c in Sources */,
8373342C23F60CDC00DE14DC /* kwb.c in Sources */,
83EED5D4203A8BC7008BEB45 /* aus.c in Sources */,
836F6F7F18BDC2190095E648 /* dmsg_segh.c in Sources */,
832BF81D21E0514B006F50F1 /* msf_tamasoft.c in Sources */,
@ -2408,6 +2425,7 @@
836F6FF918BDC2190095E648 /* ps2_snd.c in Sources */,
836F6F2918BDC2190095E648 /* l5_555_decoder.c in Sources */,
836F6FF318BDC2190095E648 /* ps2_rstm.c in Sources */,
8373342923F60CDC00DE14DC /* deblock_streamfile.c in Sources */,
836F6F7918BDC2190095E648 /* dc_asd.c in Sources */,
836F6FC118BDC2190095E648 /* pc_adp.c in Sources */,
836F703B18BDC2190095E648 /* vsf.c in Sources */,
@ -2442,6 +2460,7 @@
837CEAD823487E8300E62A4A /* bmp_konami.c in Sources */,
8306B0A220984552000302D4 /* blocked_bdsp.c in Sources */,
836F700118BDC2190095E648 /* ps2_tec.c in Sources */,
8373341C23F60C7B00DE14DC /* relic_decoder.c in Sources */,
832BF82121E0514B006F50F1 /* zsnd.c in Sources */,
836F703018BDC2190095E648 /* sqex_scd.c in Sources */,
8306B0A320984552000302D4 /* blocked_ast.c in Sources */,
@ -2459,7 +2478,9 @@
8306B0BA20984552000302D4 /* blocked_wsi.c in Sources */,
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */,
836F704418BDC2190095E648 /* ws_aud.c in Sources */,
8373342F23F60D4100DE14DC /* tgc.c in Sources */,
83709E081ECBC1A4005C03D3 /* ps2_rxws.c in Sources */,
8373342823F60CDC00DE14DC /* fda.c in Sources */,
836F6F6D18BDC2190095E648 /* aifc.c in Sources */,
836F702218BDC2190095E648 /* rsd.c in Sources */,
8349A90D1FE6258200E26435 /* ubi_sb.c in Sources */,
@ -2498,6 +2519,7 @@
836F6F3718BDC2190095E648 /* pcm_decoder.c in Sources */,
834FE106215C79ED000A5D3D /* utk.c in Sources */,
831BA6281EAC61CB00CF89B0 /* coding_utils.c in Sources */,
8373342B23F60CDC00DE14DC /* fwse.c in Sources */,
837CEAFF23487F2C00E62A4A /* raw_snds.c in Sources */,
836F700218BDC2190095E648 /* ps2_tk5.c in Sources */,
83AA5D271F6E2F9C0020821C /* stm.c in Sources */,
@ -2601,6 +2623,7 @@
834FE10F215C79ED000A5D3D /* sdf.c in Sources */,
83FC177123AC59A800E1025F /* cri_utf.c in Sources */,
834FE0FF215C79ED000A5D3D /* sqex_scd_sscf.c in Sources */,
8373341A23F60C7B00DE14DC /* relic_decoder_mixfft.c in Sources */,
836F6FAA18BDC2190095E648 /* ngc_bh2pcm.c in Sources */,
831BA6211EAC61A500CF89B0 /* x360_pasx.c in Sources */,
832BF82621E0514B006F50F1 /* nwav.c in Sources */,
@ -2656,6 +2679,7 @@
836F6FBF18BDC2190095E648 /* otm.c in Sources */,
8306B0B420984552000302D4 /* blocked_tra.c in Sources */,
834FE0B8215C798C000A5D3D /* acm_decoder_decode.c in Sources */,
8373342A23F60CDC00DE14DC /* lrmd.c in Sources */,
836F6FBD18BDC2190095E648 /* nwa.c in Sources */,
837CEAFC23487F2C00E62A4A /* raw_wavm.c in Sources */,
834FE0F7215C79ED000A5D3D /* vis.c in Sources */,
@ -2695,11 +2719,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
830EBE162004659B0023AA10 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = libatrac9;
targetProxy = 830EBE152004659B0023AA10 /* PBXContainerItemProxy */;
};
8313E3E91902021F00B4B6F1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = mpg123;
@ -2710,10 +2729,10 @@
name = Vorbis;
targetProxy = 834D795320E4F0B900C4A5CC /* PBXContainerItemProxy */;
};
83D7310F1A7394B500CA1366 /* PBXTargetDependency */ = {
836C052623F62F0000FA07C7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = g7221;
targetProxy = 83D7310E1A7394B500CA1366 /* PBXContainerItemProxy */;
name = libatrac9;
targetProxy = 836C052523F62F0000FA07C7 /* PBXContainerItemProxy */;
};
83D731881A749D0D00CA1366 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
@ -2869,7 +2888,10 @@
836F6B6218BDB8880095E648 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = (
@ -2887,6 +2909,7 @@
INFOPLIST_FILE = "vgmstream/libvgmstream-Info.plist";
PRODUCT_BUNDLE_IDENTIFIER = "NoWork-Inc.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};
@ -2895,7 +2918,10 @@
836F6B6318BDB8880095E648 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Manual;
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
FRAMEWORK_SEARCH_PATHS = (
@ -2913,6 +2939,7 @@
INFOPLIST_FILE = "vgmstream/libvgmstream-Info.plist";
PRODUCT_BUNDLE_IDENTIFIER = "NoWork-Inc.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
WRAPPER_EXTENSION = framework;
};

View File

@ -20,6 +20,7 @@ void decode_wv6_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspa
void decode_alp_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_blitz_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_mtf_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo);
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
@ -137,6 +138,9 @@ void decode_nxap(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacin
size_t yamaha_bytes_to_samples(size_t bytes, int channels);
size_t aska_bytes_to_samples(size_t bytes, int channels);
/* tgcadpcm_decoder */
void decode_tgc(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do);
/* nds_procyon_decoder */
void decode_nds_procyon(VGMSTREAMCHANNEL *stream, sample_t *outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
@ -203,9 +207,16 @@ void flush_ea_mt(VGMSTREAM *vgmstream);
void seek_ea_mt(VGMSTREAM * vgmstream, int32_t num_sample);
void free_ea_mt(ea_mt_codec_data *data, int channels);
/* relic_decoder */
relic_codec_data* init_relic(int channels, int bitrate, int codec_rate);
void decode_relic(VGMSTREAMCHANNEL* stream, relic_codec_data* data, sample_t* outbuf, int32_t samples_to_do);
void reset_relic(relic_codec_data* data);
void seek_relic(relic_codec_data* data, int32_t num_sample);
void free_relic(relic_codec_data* data);
/* hca_decoder */
hca_codec_data *init_hca(STREAMFILE *streamFile);
void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do);
void decode_hca(hca_codec_data * data, sample_t * outbuf, int32_t samples_to_do);
void reset_hca(hca_codec_data * data);
void loop_hca(hca_codec_data * data, int32_t num_sample);
void free_hca(hca_codec_data * data);
@ -248,10 +259,12 @@ long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data *data);
#ifdef VGM_USE_G7221
/* g7221_decoder */
g7221_codec_data *init_g7221(int channel_count, int frame_size);
void decode_g7221(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
void reset_g7221(VGMSTREAM *vgmstream);
void free_g7221(VGMSTREAM *vgmstream);
g7221_codec_data* init_g7221(int channel_count, int frame_size);
void decode_g7221(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t samples_to_do, int channel);
void reset_g7221(g7221_codec_data* data);
void free_g7221(g7221_codec_data* data);
void set_key_g7221(g7221_codec_data* data, const uint8_t* key);
int test_key_g7221(g7221_codec_data* data, off_t start, STREAMFILE* sf);
#endif
#ifdef VGM_USE_G719

View File

@ -1,48 +1,68 @@
#include "coding.h"
#include "g7221_decoder_lib.h"
#ifdef VGM_USE_G7221
#define G7221_MAX_CODES (960/8) /* max frame 0xF0 uint8s = 0xF0/2 uint16s = 960/8 */
#define G7221_MAX_FRAME_SIZE 0x78 /* 960/8 */
#define G7221_MAX_FRAME_SAMPLES 640 /* 32000/50 */
struct g7221_codec_data {
int channels;
int frame_size;
struct g7221_channel_data {
sample_t buffer[G7221_MAX_FRAME_SAMPLES];
g7221_handle* handle;
} *ch;
};
g7221_codec_data * init_g7221(int channel_count, int frame_size) {
g7221_codec_data* init_g7221(int channels, int frame_size) {
int i;
g7221_codec_data *data = NULL;
g7221_codec_data* data = NULL;
if (frame_size / sizeof(int16_t) > G7221_MAX_CODES)
if (frame_size > G7221_MAX_FRAME_SIZE)
goto fail;
data = calloc(channel_count, sizeof(g7221_codec_data)); /* one decoder per channel */
data = calloc(1, sizeof(g7221_codec_data));
if (!data) goto fail;
for (i = 0; i < channel_count; i++) {
data[i].handle = g7221_init(frame_size, 14000); /* Siren 14 == 14khz bandwidth */
if (!data[i].handle) goto fail;
data->channels = channels;
data->frame_size = frame_size;
data->ch = calloc(channels, sizeof(struct g7221_channel_data));
if (!data->ch) goto fail;
for (i = 0; i < data->channels; i++) {
data->ch[i].handle = g7221_init(frame_size);
if (!data->ch[i].handle) goto fail;
}
return data;
fail:
if (data) {
for (i = 0; i < channel_count; i++) {
g7221_free(data[i].handle);
}
}
free(data);
free_g7221(data);
return NULL;
}
void decode_g7221(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel) {
VGMSTREAMCHANNEL *ch = &vgmstream->ch[channel];
g7221_codec_data *data = vgmstream->codec_data;
g7221_codec_data *ch_data = &data[channel];
void decode_g7221(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t samples_to_do, int channel) {
VGMSTREAMCHANNEL* ch = &vgmstream->ch[channel];
g7221_codec_data* data = vgmstream->codec_data;
struct g7221_channel_data* ch_data = &data->ch[channel];
int i;
if (0 == vgmstream->samples_into_block) {
int16_t code_buffer[G7221_MAX_CODES];
vgmstream->ch[channel].streamfile->read(ch->streamfile, (uint8_t*)code_buffer, ch->offset, vgmstream->interleave_block_size);
g7221_decode_frame(ch_data->handle, code_buffer, ch_data->buffer);
uint8_t buf[G7221_MAX_FRAME_SIZE];
size_t bytes;
size_t read = data->frame_size;
bytes = read_streamfile(buf, ch->offset, read, ch->streamfile);
if (bytes != read) {
//g7221_decode_empty(ch_data->handle, ch_data->buffer);
memset(ch_data->buffer, 0, sizeof(ch_data->buffer));
VGM_LOG("S14: EOF read\n");
}
else {
g7221_decode_frame(ch_data->handle, buf, ch_data->buffer);
}
}
for (i = 0; i < samples_to_do; i++) {
@ -51,25 +71,89 @@ void decode_g7221(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, in
}
void reset_g7221(VGMSTREAM *vgmstream) {
g7221_codec_data *data = vgmstream->codec_data;
void reset_g7221(g7221_codec_data* data) {
int i;
if (!data) return;
for (i = 0; i < vgmstream->channels; i++) {
g7221_reset(data[i].handle);
for (i = 0; i < data->channels; i++) {
g7221_reset(data->ch[i].handle);
}
}
void free_g7221(VGMSTREAM *vgmstream) {
g7221_codec_data *data = (g7221_codec_data *) vgmstream->codec_data;
void free_g7221(g7221_codec_data* data) {
int i;
if (!data) return;
for (i = 0; i < vgmstream->channels; i++) {
g7221_free(data[i].handle);
for (i = 0; i < data->channels; i++) {
g7221_free(data->ch[i].handle);
}
free(data->ch);
free(data);
}
void set_key_g7221(g7221_codec_data* data, const uint8_t* key) {
int i;
if (!data) return;
for (i = 0; i < data->channels; i++) {
g7221_set_key(data->ch[i].handle, key);
}
}
/* just in case but very few should be enough */
#define S14_KEY_MIN_TEST_FRAMES 3
#define S14_KEY_MAX_TEST_FRAMES 5
/* Test a number of frames to check if current key decrypts correctly.
* Returns score: <0: error/wrong, 0: unknown/silent, >0: good (closer to 1 is better). */
int test_key_g7221(g7221_codec_data* data, off_t start, STREAMFILE* sf) {
size_t test_frames = 0, current_frame = 0;
int total_score = 0;
int max_frames = (get_streamfile_size(sf) - start) / data->frame_size;
int cur_ch = 0;
/* assumes key was set before this call */
while (test_frames < S14_KEY_MAX_TEST_FRAMES && current_frame < max_frames) {
int score, ok;
size_t bytes;
uint8_t buf[G7221_MAX_FRAME_SIZE];
bytes = read_streamfile(buf, start, data->frame_size, sf);
if (bytes != data->frame_size) {
total_score = -1;
break;
}
ok = g7221_decode_frame(data->ch[cur_ch].handle, buf, data->ch[cur_ch].buffer);
if (!ok) {
total_score = -1;
break;
}
/* alternate channels (decode may affect scores otherwise) */
cur_ch = (cur_ch + 1) % data->channels;
/* good key if it decodes without error, encryption is easily detectable */
score = 1;
test_frames++;
total_score += score;
start += data->frame_size;
}
/* signal best possible score (many perfect frames and few blank frames) */
if (test_frames > S14_KEY_MIN_TEST_FRAMES && total_score > 0 && total_score <= test_frames) {
total_score = 1;
}
/* clean up decoders */
reset_g7221(data);
return total_score;
}
#endif

View File

@ -0,0 +1,326 @@
#include <stdlib.h>
#include "g7221_decoder_aes.h"
/* Namco's NUS AES is just standard AES-192 in ECB mode, so this can be swapped with another lib,
* if more code needs AES. Most implementations out there either use pre-calculated look-up tables,
* or calculate manually every AES op. Namco's code calculates tables first in a slightly different
* layout, so it may be interesting as a sort of doc piece. */
struct s14aes_handle {
/* substitution box look-up table and the inverse */
uint8_t sbox[256];
uint8_t ibox[256];
/* helper for various tables, not too sure about it */
uint8_t xors[256];
/* round constant, though only sets up to 8 */
uint8_t rcon[16];
/* MixColumn(?) LUTs, unlike normal Rijndael which uses 4 tables: Td0a Td0b..., Td1a Td1b..., ...
* layout is: Td0a Td1a Td2a Td3a, Td0b Td0b Td1b Td2b, ... (better for CPU cache?) */
uint32_t tds[256*4];
/* expanded roundkey, actual final key */
uint32_t rk[52];
} ;
#define GET_U32LE(p) (((p)[0] << 0 ) | ((p)[1] << 8 ) | ((p)[2] << 16) | ((p)[3] << 24))
#define GET_U32BE(p) (((p)[3] << 0 ) | ((p)[2] << 8 ) | ((p)[1] << 16) | ((p)[0] << 24))
#define GET_B0(x) (((x) >> 0 ) & 0xFF)
#define GET_B1(x) (((x) >> 8 ) & 0xFF)
#define GET_B2(x) (((x) >> 16) & 0xFF)
#define GET_B3(x) (((x) >> 24) & 0xFF)
static void aes_key_expand(s14aes_handle* ctx, const uint8_t* key, uint32_t* rk) {
int i;
rk[0] = GET_U32LE(key + 0);
rk[1] = GET_U32LE(key + 4);
rk[2] = GET_U32LE(key + 8);
rk[3] = GET_U32LE(key + 12);
rk[4] = GET_U32LE(key + 16);
rk[5] = GET_U32LE(key + 20);
for (i = 6; i < 52; i++) {
uint8_t temp0 = (rk[5] >> 0 ) & 0xFF;
uint8_t temp1 = (rk[5] >> 8 ) & 0xFF;
uint8_t temp2 = (rk[5] >> 16) & 0xFF;
uint8_t temp3 = (rk[5] >> 24) & 0xFF;
if (i == 6 * (i / 6)) {
uint8_t sv = ctx->sbox[temp1];
temp1 = ctx->sbox[temp2];
temp2 = ctx->sbox[temp3];
temp3 = ctx->sbox[temp0];
temp0 = ctx->rcon[i / 6u - 1] ^ sv;
}
rk[6] = ((temp0 ^ ((rk[0] >> 0 ) & 0xFF)) << 0 ) |
((temp1 ^ ((rk[0] >> 8 ) & 0xFF)) << 8 ) |
((temp2 ^ ((rk[0] >> 16) & 0xFF)) << 16) |
((temp3 ^ ((rk[0] >> 24) & 0xFF)) << 24);
rk++;
}
}
static void aes_init_key(s14aes_handle* ctx, const uint8_t* key) {
const uint8_t invcols[4][4] = {
{0x0E,0x0B,0x0D,0x09},
{0x09,0x0E,0x0B,0x0D},
{0x0D,0x09,0x0E,0x0B},
{0x0B,0x0D,0x09,0x0E}
};
unsigned int roundkey[52];
int i, j, row, col, b;
aes_key_expand(ctx, key, roundkey);
for (i = 0; i < 4; i++) {
ctx->rk[i] = ((roundkey[i] << 24) & 0xFF000000) |
((roundkey[i] << 8 ) & 0x00FF0000) |
((roundkey[i] >> 8 ) & 0x0000FF00) |
((roundkey[i] >> 24) & 0x000000FF);
}
for (i = 4; i < 48; i += 4) {
for (j = i; j < i + 4; j++) {
uint32_t val = 0;
for (row = 0; row < 4; row++) {
uint8_t xv = 0;
for (col = 0; col < 4; col++) {
uint16_t rv1 = 0;
uint16_t rv2 = (roundkey[j] >> (col * 8)) & 0xFF;
uint8_t ic = invcols[row][col];
for (b = 0; b < 8; b++) {
if (ic & (1 << b))
rv1 ^= rv2;
rv2 *= 2;
}
xv ^= rv1 ^ ctx->xors[rv1 >> 8];
}
val = (val << 8) | xv;
}
ctx->rk[j] = val;
}
}
for (i = 48; i < 52; i++) {
ctx->rk[i] = ((roundkey[i] << 24) & 0xFF000000) |
((roundkey[i] << 8 ) & 0x00FF0000) |
((roundkey[i] >> 8 ) & 0x0000FF00) |
((roundkey[i] >> 24) & 0x000000FF);
}
}
static void aes_init_state(s14aes_handle* ctx) {
const uint8_t invcol[4] = {
0x0E, 0x0B, 0x0D, 0x09
};
unsigned int *tds_ptr;
uint8_t rcon[32];
uint8_t box[256];
int i, j, k, b;
for (i = 0; i < 32; i++) {
uint16_t rv;
if (i >= 8) {
rv = 128;
for (j = 0; j < i - 7; j++) {
rv *= 2;
if (rv & 256)
rv ^= 0x11Bu;
}
}
else {
rv = 1 << i;
}
rcon[i] = rv;
}
for (i = 0; i < 256; i++) {
uint8_t xv = 0;
for (j = 0; j < 8; j++) {
if (i & (1 << j))
xv ^= rcon[j + 8];
}
ctx->xors[i] = xv;
}
tds_ptr = ctx->tds;
for (i = 0; i < 256; i++) {
uint32_t val = 0;
for (j = 0; j < 4; j++) {
uint16_t tv1 = 0;
uint16_t tv2 = invcol[j];
for (b = 0; b < 8; b++) {
if (i & (1 << b))
tv1 ^= tv2;
tv2 *= 2;
}
val = ((val >> 8u) & 0x00FFFFFF) | ((val << 24u) & 0xFF000000);
val = ((uint8_t)tv1 ^ ctx->xors[tv1 >> 8]) | val;
}
val = ((val >> 16u) & 0x0000FFFF) | ((val << 16u) & 0xFFFF0000);
for (j = 0; j < 4; j++) {
*tds_ptr++ = val;
val = ((val >> 8u) & 0x00FFFFFF) | ((val << 24u) & 0xFF000000);
}
}
box[0] = 0;
for (i = 1; i < 256; i++) {
for (j = 1; j < 256; j++) {
uint16_t bv1 = 0;
uint16_t bv2 = j;
for (k = 0; k < 8; k++) {
if (i & (1 << k))
bv1 ^= bv2;
bv2 *= 2;
}
if (((uint8_t)bv1 ^ ctx->xors[bv1 >> 8]) == 1)
break;
}
box[i] = j;
if (j == 256) /* ??? */
return;
}
for (i = 0; i < 256; i += 16) {
for (j = 0; j < 16; j++) {
uint8_t val = 0;
for (k = 0; k < 8; k++) {
val |= box[i | j] & (1 << k);
for (b = 0; b < 4; b++) {
uint8_t bv = box[i | j];
if (bv & (1 << ((b + k - 4) & 7)))
val ^= 1 << k;
}
}
ctx->sbox[i + j] = val ^ 0x63;
ctx->ibox[val ^ 0x63] = i + j;
}
}
/* originally recalculated in Namco's code (inlined?) */
for (i = 0; i < 8; i++) {
ctx->rcon[i] = rcon[i];
}
}
static void aes_decrypt_block(s14aes_handle* ctx, uint8_t* buf) {
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
uint8_t* ibox = ctx->ibox;
uint32_t* tds = ctx->tds;
uint32_t* rk = ctx->rk;
s0 = rk[48] ^ GET_U32BE(buf + 0);
s1 = rk[49] ^ GET_U32BE(buf + 4);
s2 = rk[50] ^ GET_U32BE(buf + 8);
s3 = rk[51] ^ GET_U32BE(buf + 12);
t0 = rk[44] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[45] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[46] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[47] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
s0 = rk[40] ^ tds[4 * ibox[GET_B0(t1)] + 3] ^ tds[4 * ibox[GET_B1(t2)] + 2] ^ tds[4 * ibox[GET_B2(t3)] + 1] ^ tds[4 * ibox[GET_B3(t0)] + 0];
s1 = rk[41] ^ tds[4 * ibox[GET_B0(t2)] + 3] ^ tds[4 * ibox[GET_B1(t3)] + 2] ^ tds[4 * ibox[GET_B2(t0)] + 1] ^ tds[4 * ibox[GET_B3(t1)] + 0];
s2 = rk[42] ^ tds[4 * ibox[GET_B0(t3)] + 3] ^ tds[4 * ibox[GET_B1(t0)] + 2] ^ tds[4 * ibox[GET_B2(t1)] + 1] ^ tds[4 * ibox[GET_B3(t2)] + 0];
s3 = rk[43] ^ tds[4 * ibox[GET_B0(t0)] + 3] ^ tds[4 * ibox[GET_B1(t1)] + 2] ^ tds[4 * ibox[GET_B2(t2)] + 1] ^ tds[4 * ibox[GET_B3(t3)] + 0];
t0 = rk[36] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[37] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[38] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[39] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
s0 = rk[32] ^ tds[4 * ibox[GET_B0(t1)] + 3] ^ tds[4 * ibox[GET_B1(t2)] + 2] ^ tds[4 * ibox[GET_B2(t3)] + 1] ^ tds[4 * ibox[GET_B3(t0)] + 0];
s1 = rk[33] ^ tds[4 * ibox[GET_B0(t2)] + 3] ^ tds[4 * ibox[GET_B1(t3)] + 2] ^ tds[4 * ibox[GET_B2(t0)] + 1] ^ tds[4 * ibox[GET_B3(t1)] + 0];
s2 = rk[34] ^ tds[4 * ibox[GET_B0(t3)] + 3] ^ tds[4 * ibox[GET_B1(t0)] + 2] ^ tds[4 * ibox[GET_B2(t1)] + 1] ^ tds[4 * ibox[GET_B3(t2)] + 0];
s3 = rk[35] ^ tds[4 * ibox[GET_B0(t0)] + 3] ^ tds[4 * ibox[GET_B1(t1)] + 2] ^ tds[4 * ibox[GET_B2(t2)] + 1] ^ tds[4 * ibox[GET_B3(t3)] + 0];
t0 = rk[28] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[29] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[30] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[31] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
s0 = rk[24] ^ tds[4 * ibox[GET_B0(t1)] + 3] ^ tds[4 * ibox[GET_B1(t2)] + 2] ^ tds[4 * ibox[GET_B2(t3)] + 1] ^ tds[4 * ibox[GET_B3(t0)] + 0];
s1 = rk[25] ^ tds[4 * ibox[GET_B0(t2)] + 3] ^ tds[4 * ibox[GET_B1(t3)] + 2] ^ tds[4 * ibox[GET_B2(t0)] + 1] ^ tds[4 * ibox[GET_B3(t1)] + 0];
s2 = rk[26] ^ tds[4 * ibox[GET_B0(t3)] + 3] ^ tds[4 * ibox[GET_B1(t0)] + 2] ^ tds[4 * ibox[GET_B2(t1)] + 1] ^ tds[4 * ibox[GET_B3(t2)] + 0];
s3 = rk[27] ^ tds[4 * ibox[GET_B0(t0)] + 3] ^ tds[4 * ibox[GET_B1(t1)] + 2] ^ tds[4 * ibox[GET_B2(t2)] + 1] ^ tds[4 * ibox[GET_B3(t3)] + 0];
t0 = rk[20] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[21] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[22] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[23] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
s0 = rk[16] ^ tds[4 * ibox[GET_B0(t1)] + 3] ^ tds[4 * ibox[GET_B1(t2)] + 2] ^ tds[4 * ibox[GET_B2(t3)] + 1] ^ tds[4 * ibox[GET_B3(t0)] + 0];
s1 = rk[17] ^ tds[4 * ibox[GET_B0(t2)] + 3] ^ tds[4 * ibox[GET_B1(t3)] + 2] ^ tds[4 * ibox[GET_B2(t0)] + 1] ^ tds[4 * ibox[GET_B3(t1)] + 0];
s2 = rk[18] ^ tds[4 * ibox[GET_B0(t3)] + 3] ^ tds[4 * ibox[GET_B1(t0)] + 2] ^ tds[4 * ibox[GET_B2(t1)] + 1] ^ tds[4 * ibox[GET_B3(t2)] + 0];
s3 = rk[19] ^ tds[4 * ibox[GET_B0(t0)] + 3] ^ tds[4 * ibox[GET_B1(t1)] + 2] ^ tds[4 * ibox[GET_B2(t2)] + 1] ^ tds[4 * ibox[GET_B3(t3)] + 0];
t0 = rk[12] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[13] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[14] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[15] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
s0 = rk[8 ] ^ tds[4 * ibox[GET_B0(t1)] + 3] ^ tds[4 * ibox[GET_B1(t2)] + 2] ^ tds[4 * ibox[GET_B2(t3)] + 1] ^ tds[4 * ibox[GET_B3(t0)] + 0];
s1 = rk[9 ] ^ tds[4 * ibox[GET_B0(t2)] + 3] ^ tds[4 * ibox[GET_B1(t3)] + 2] ^ tds[4 * ibox[GET_B2(t0)] + 1] ^ tds[4 * ibox[GET_B3(t1)] + 0];
s2 = rk[10] ^ tds[4 * ibox[GET_B0(t3)] + 3] ^ tds[4 * ibox[GET_B1(t0)] + 2] ^ tds[4 * ibox[GET_B2(t1)] + 1] ^ tds[4 * ibox[GET_B3(t2)] + 0];
s3 = rk[11] ^ tds[4 * ibox[GET_B0(t0)] + 3] ^ tds[4 * ibox[GET_B1(t1)] + 2] ^ tds[4 * ibox[GET_B2(t2)] + 1] ^ tds[4 * ibox[GET_B3(t3)] + 0];
t0 = rk[4 ] ^ tds[4 * ibox[GET_B0(s1)] + 3] ^ tds[4 * ibox[GET_B1(s2)] + 2] ^ tds[4 * ibox[GET_B2(s3)] + 1] ^ tds[4 * ibox[GET_B3(s0)] + 0];
t1 = rk[5 ] ^ tds[4 * ibox[GET_B0(s2)] + 3] ^ tds[4 * ibox[GET_B1(s3)] + 2] ^ tds[4 * ibox[GET_B2(s0)] + 1] ^ tds[4 * ibox[GET_B3(s1)] + 0];
t2 = rk[6 ] ^ tds[4 * ibox[GET_B0(s3)] + 3] ^ tds[4 * ibox[GET_B1(s0)] + 2] ^ tds[4 * ibox[GET_B2(s1)] + 1] ^ tds[4 * ibox[GET_B3(s2)] + 0];
t3 = rk[7 ] ^ tds[4 * ibox[GET_B0(s0)] + 3] ^ tds[4 * ibox[GET_B1(s1)] + 2] ^ tds[4 * ibox[GET_B2(s2)] + 1] ^ tds[4 * ibox[GET_B3(s3)] + 0];
buf[0 ] = GET_B3(rk[0]) ^ ibox[GET_B3(t0)];
buf[1 ] = GET_B2(rk[0]) ^ ibox[GET_B2(t3)];
buf[2 ] = GET_B1(rk[0]) ^ ibox[GET_B1(t2)];
buf[3 ] = GET_B0(rk[0]) ^ ibox[GET_B0(t1)];
buf[4 ] = GET_B3(rk[1]) ^ ibox[GET_B3(t1)];
buf[5 ] = GET_B2(rk[1]) ^ ibox[GET_B2(t0)];
buf[6 ] = GET_B1(rk[1]) ^ ibox[GET_B1(t3)];
buf[7 ] = GET_B0(rk[1]) ^ ibox[GET_B0(t2)];
buf[8 ] = GET_B3(rk[2]) ^ ibox[GET_B3(t2)];
buf[9 ] = GET_B2(rk[2]) ^ ibox[GET_B2(t1)];
buf[10] = GET_B1(rk[2]) ^ ibox[GET_B1(t0)];
buf[11] = GET_B0(rk[2]) ^ ibox[GET_B0(t3)];
buf[12] = GET_B3(rk[3]) ^ ibox[GET_B3(t3)];
buf[13] = GET_B2(rk[3]) ^ ibox[GET_B2(t2)];
buf[14] = GET_B1(rk[3]) ^ ibox[GET_B1(t1)];
buf[15] = GET_B0(rk[3]) ^ ibox[GET_B0(t0)];
}
/* **************************** */
s14aes_handle* s14aes_init() {
s14aes_handle* ctx = malloc(sizeof(s14aes_handle));
if (!ctx) goto fail;
aes_init_state(ctx);
return ctx;
fail:
return NULL;
}
void s14aes_close(s14aes_handle* ctx) {
free(ctx);
}
void s14aes_set_key(s14aes_handle* ctx, const uint8_t* key) {
aes_init_key(ctx, key);
}
void s14aes_decrypt(s14aes_handle* ctx, uint8_t* buf) {
aes_decrypt_block(ctx, buf);
}

View File

@ -0,0 +1,19 @@
#ifndef _G7221_DECODER_AES_H
#define _G7221_DECODER_AES_H
#include <stdint.h>
typedef struct s14aes_handle s14aes_handle;
/* init/close handle (AES-192 in ECB mode) */
s14aes_handle* s14aes_init();
void s14aes_close(s14aes_handle* ctx);
/* set new key (can be called multiple times) */
void s14aes_set_key(s14aes_handle* ctx, const uint8_t* key);
/* decrypt a single 0x10 block */
void s14aes_decrypt(s14aes_handle* ctx, uint8_t* buf);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
/*
Interface to Namco G.722.1 decoder
*/
#ifndef _G7221_DECODER_LIB_H
#define _G7221_DECODER_LIB_H
#include <stdint.h>
/* forward definition for the opaque handle object */
typedef struct g7221_handle g7221_handle;
/* return a handle for decoding on successful init, NULL on failure */
g7221_handle* g7221_init(int bytes_per_frame);
/* decode a frame, at code_words, into 16-bit PCM in sample_buffer */
int g7221_decode_frame(g7221_handle* handle, uint8_t* data, int16_t* out_samples);
#if 0
/* decodes an empty frame after no more data is found (may be used to "drain" window samples */
int g7221_decode_empty(g7221_handle* handle, int16_t* out_samples);
#endif
/* reset the decoder to its initial state */
void g7221_reset(g7221_handle* handle);
/* free resources */
void g7221_free(g7221_handle* handle);
/* set new key (ignores key on failure) */
int g7221_set_key(g7221_handle* handle, const uint8_t* key);
#endif

View File

@ -0,0 +1,576 @@
#ifndef _DATA_H_
#define _DATA_H_
#include <stdint.h>
/*****************************************************************************
* MAIN
*****************************************************************************/
#define MAX_DCT_LENGTH 640
/*****************************************************************************
* IMLT
*****************************************************************************/
/* vs refdec: this window seems based on float refdec with a scale:
* for (i = 0; i < 640; i++)
* window[i] = floor(sin((PI/2.0) * (i + 0.5) / 640) * 32767.0)
* while the original int refdec table uses an altered formula? (smaller values) */
static const int16_t imlt_samples_window[MAX_DCT_LENGTH] = { /* "Out_Window"? */
40, 120, 201, 281, 361, 442, 522, 603, 683, 763,
844, 924, 1005, 1085, 1165, 1246, 1326, 1406, 1487, 1567,
1647, 1728, 1808, 1888, 1969, 2049, 2129, 2209, 2290, 2370,
2450, 2530, 2610, 2691, 2771, 2851, 2931, 3011, 3091, 3171,
3251, 3331, 3411, 3491, 3571, 3651, 3731, 3811, 3891, 3971,
4050, 4130, 4210, 4290, 4369, 4449, 4529, 4608, 4688, 4768,
4847, 4927, 5006, 5086, 5165, 5245, 5324, 5403, 5483, 5562,
5641, 5720, 5799, 5879, 5958, 6037, 6116, 6195, 6274, 6353,
6431, 6510, 6589, 6668, 6747, 6825, 6904, 6982, 7061, 7140,
7218, 7296, 7375, 7453, 7531, 7610, 7688, 7766, 7844, 7922,
8000, 8078, 8156, 8234, 8312, 8390, 8467, 8545, 8623, 8700,
8778, 8855, 8932, 9010, 9087, 9164, 9242, 9319, 9396, 9473,
9550, 9627, 9703, 9780, 9857, 9934, 10010, 10087, 10163, 10240,
10316, 10392, 10469, 10545, 10621, 10697, 10773, 10849, 10925, 11001,
11076, 11152, 11227, 11303, 11378, 11454, 11529, 11604, 11680, 11755,
11830, 11905, 11980, 12054, 12129, 12204, 12278, 12353, 12427, 12502,
12576, 12650, 12724, 12798, 12872, 12946, 13020, 13094, 13168, 13241,
13315, 13388, 13462, 13535, 13608, 13681, 13754, 13827, 13900, 13973,
14046, 14118, 14191, 14263, 14335, 14408, 14480, 14552, 14624, 14696,
14768, 14840, 14911, 14983, 15054, 15126, 15197, 15268, 15339, 15410,
15481, 15552, 15623, 15693, 15764, 15834, 15905, 15975, 16045, 16115,
16185, 16255, 16325, 16395, 16464, 16534, 16603, 16672, 16742, 16811,
16880, 16948, 17017, 17086, 17154, 17223, 17291, 17360, 17428, 17496,
17564, 17632, 17699, 17767, 17834, 17902, 17969, 18036, 18103, 18170,
18237, 18304, 18371, 18437, 18504, 18570, 18636, 18702, 18768, 18834,
18900, 18966, 19031, 19096, 19162, 19227, 19292, 19357, 19422, 19486,
19551, 19616, 19680, 19744, 19808, 19872, 19936, 20000, 20064, 20127,
20190, 20254, 20317, 20380, 20443, 20506, 20568, 20631, 20693, 20756,
20818, 20880, 20942, 21003, 21065, 21127, 21188, 21249, 21311, 21372,
21432, 21493, 21554, 21614, 21675, 21735, 21795, 21855, 21915, 21975,
22034, 22094, 22153, 22212, 22271, 22330, 22389, 22448, 22506, 22565,
22623, 22681, 22739, 22797, 22854, 22912, 22969, 23027, 23084, 23141,
23198, 23254, 23311, 23367, 23424, 23480, 23536, 23592, 23648, 23703,
23759, 23814, 23869, 23924, 23979, 24034, 24088, 24143, 24197, 24251,
24305, 24359, 24413, 24466, 24520, 24573, 24626, 24679, 24732, 24785,
24837, 24890, 24942, 24994, 25046, 25098, 25149, 25201, 25252, 25303,
25354, 25405, 25456, 25506, 25557, 25607, 25657, 25707, 25757, 25806,
25856, 25905, 25954, 26003, 26052, 26101, 26150, 26198, 26246, 26294,
26342, 26390, 26437, 26485, 26532, 26579, 26626, 26673, 26720, 26766,
26812, 26859, 26905, 26950, 26996, 27042, 27087, 27132, 27177, 27222,
27267, 27311, 27355, 27400, 27444, 27488, 27531, 27575, 27618, 27661,
27704, 27747, 27790, 27832, 27875, 27917, 27959, 28001, 28042, 28084,
28125, 28167, 28208, 28248, 28289, 28330, 28370, 28410, 28450, 28490,
28529, 28569, 28608, 28647, 28686, 28725, 28764, 28802, 28840, 28878,
28916, 28954, 28992, 29029, 29066, 29103, 29140, 29177, 29213, 29250,
29286, 29322, 29358, 29393, 29429, 29464, 29499, 29534, 29569, 29603,
29638, 29672, 29706, 29740, 29773, 29807, 29840, 29873, 29906, 29939,
29972, 30004, 30036, 30068, 30100, 30132, 30163, 30195, 30226, 30257,
30288, 30318, 30349, 30379, 30409, 30439, 30468, 30498, 30527, 30556,
30585, 30614, 30643, 30671, 30699, 30727, 30755, 30783, 30810, 30838,
30865, 30892, 30918, 30945, 30971, 30997, 31023, 31049, 31075, 31100,
31125, 31150, 31175, 31200, 31224, 31249, 31273, 31297, 31320, 31344,
31367, 31390, 31413, 31436, 31459, 31481, 31503, 31525, 31547, 31569,
31590, 31612, 31633, 31653, 31674, 31695, 31715, 31735, 31755, 31775,
31794, 31814, 31833, 31852, 31871, 31889, 31907, 31926, 31944, 31961,
31979, 31997, 32014, 32031, 32048, 32064, 32081, 32097, 32113, 32129,
32145, 32160, 32176, 32191, 32206, 32220, 32235, 32249, 32263, 32277,
32291, 32304, 32318, 32331, 32344, 32357, 32369, 32382, 32394, 32406,
32418, 32429, 32441, 32452, 32463, 32474, 32484, 32495, 32505, 32515,
32525, 32535, 32544, 32553, 32562, 32571, 32580, 32588, 32597, 32605,
32613, 32620, 32628, 32635, 32642, 32649, 32656, 32662, 32669, 32675,
32681, 32686, 32692, 32697, 32702, 32707, 32712, 32717, 32721, 32725,
32729, 32733, 32736, 32740, 32743, 32746, 32749, 32751, 32753, 32756,
32758, 32759, 32761, 32762, 32764, 32765, 32765, 32766, 32766, 32766,
};
/* set helper for DCT-IV optimizations (code seem to stop at 174) */
static const uint8_t imlt_set1_table[176] = {
1, 1, 1, 1, 1, 1, 3, 1, 2, 0, 1, 1, 3, 1, 1, 1,
1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1,
3, 1, 3, 1, 1, 1, 1, 1, 3, 1, 2, 0, 1, 1, 3, 1,
1, 1, 1, 1, 3, 1, 3, 1, 3, 1, 1, 1, 1, 1, 3, 1,
1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 3, 1,
1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1,
3, 1, 3, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1,
3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 3, 1, 1, 1, 1, 1,
3, 1, 3, 1, 3, 1, 1, 1, 1, 1, 3, 1, 3, 1, 3, 1,
1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1,
3, 1, 3, 1, 3, 1, 1, 1, 1, 1, 3, 1, 2, 0, 0, 0,
};
static const uint8_t imlt_set2_table[44] = {
1, 3, 1, 1, 3, 3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3,
3, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 3, 3, 1, 1, 3,
2, 1, 3, 1, 1, 3, 1, 1, 3, 2, 1, 1,
};
/* vs refdec: bigger values calculated differently (unsure how), probably:
* for (i = 0; i < size; i++)
* cos/sin( (PI / (4 * size)) * (i + 0.5) * unknown_scale )
* Originally were multiple separate tables, but here they are fused into one
* (could be cleaned up, may be a compiler optimization)
* Note this uses *unsigned* int16s, for temp vars we can use ints */
static const uint16_t imlt_cos_tables[636] = {
/* imlt_cos_table_64[320] (640/2) */
65535, 65535, 65534, 65533, 65532, 65530, 65527, 65524,
65521, 65518, 65514, 65509, 65505, 65500, 65494, 65488,
65482, 65475, 65468, 65460, 65453, 65444, 65436, 65427,
65417, 65407, 65397, 65386, 65375, 65364, 65352, 65340,
65327, 65314, 65301, 65287, 65273, 65258, 65243, 65228,
65212, 65196, 65179, 65162, 65145, 65127, 65109, 65091,
65072, 65052, 65033, 65013, 64992, 64971, 64950, 64928,
64906, 64884, 64861, 64838, 64814, 64790, 64766, 64741,
64716, 64690, 64665, 64638, 64611, 64584, 64557, 64529,
64501, 64472, 64443, 64414, 64384, 64353, 64323, 64292,
64261, 64229, 64197, 64164, 64131, 64098, 64064, 64030,
63996, 63961, 63925, 63890, 63854, 63817, 63781, 63743,
63706, 63668, 63630, 63591, 63552, 63512, 63473, 63432,
63392, 63351, 63309, 63268, 63225, 63183, 63140, 63097,
63053, 63009, 62965, 62920, 62875, 62829, 62783, 62737,
62690, 62643, 62596, 62548, 62500, 62451, 62402, 62353,
62303, 62253, 62203, 62152, 62100, 62049, 61997, 61945,
61892, 61839, 61785, 61732, 61677, 61623, 61568, 61513,
61457, 61401, 61344, 61288, 61231, 61173, 61115, 61057,
60998, 60939, 60880, 60820, 60760, 60700, 60639, 60578,
60516, 60454, 60392, 60329, 60266, 60203, 60139, 60075,
60011, 59946, 59881, 59815, 59749, 59683, 59616, 59549,
59482, 59414, 59346, 59278, 59209, 59140, 59070, 59000,
58930, 58860, 58789, 58718, 58646, 58574, 58502, 58429,
58356, 58283, 58209, 58135, 58060, 57986, 57910, 57835,
57759, 57683, 57606, 57530, 57452, 57375, 57297, 57219,
57140, 57061, 56982, 56902, 56822, 56742, 56661, 56580,
56499, 56417, 56335, 56253, 56170, 56087, 56004, 55920,
55836, 55752, 55667, 55582, 55497, 55411, 55325, 55238,
55152, 55065, 54977, 54889, 54801, 54713, 54624, 54535,
54446, 54356, 54266, 54176, 54085, 53994, 53903, 53811,
53719, 53627, 53534, 53441, 53348, 53255, 53161, 53066,
52972, 52877, 52782, 52686, 52591, 52494, 52398, 52301,
52204, 52107, 52009, 51911, 51813, 51714, 51615, 51516,
51416, 51316, 51216, 51116, 51015, 50914, 50812, 50710,
50608, 50506, 50403, 50301, 50197, 50094, 49990, 49886,
49781, 49676, 49571, 49466, 49360, 49254, 49148, 49042,
48935, 48828, 48720, 48612, 48504, 48396, 48288, 48179,
48069, 47960, 47850, 47740, 47630, 47519, 47408, 47297,
47186, 47074, 46962, 46849, 46737, 46624, 46511, 46397,
/* imlt_cos_table_32[160] (640/4) (seems unused) */
65535, 65534, 65531, 65526, 65520, 65512, 65502, 65491,
65478, 65464, 65448, 65431, 65412, 65392, 65370, 65346,
65321, 65294, 65265, 65235, 65204, 65171, 65136, 65100,
65062, 65023, 64982, 64939, 64895, 64850, 64802, 64754,
64703, 64651, 64598, 64543, 64486, 64428, 64369, 64307,
64245, 64180, 64115, 64047, 63978, 63908, 63836, 63762,
63687, 63610, 63532, 63452, 63371, 63289, 63204, 63118,
63031, 62942, 62852, 62760, 62667, 62572, 62475, 62377,
62278, 62177, 62075, 61971, 61865, 61759, 61650, 61540,
61429, 61316, 61202, 61086, 60969, 60850, 60730, 60608,
60485, 60361, 60235, 60107, 59978, 59848, 59716, 59583,
59448, 59312, 59174, 59035, 58895, 58753, 58610, 58465,
58319, 58172, 58023, 57873, 57721, 57568, 57414, 57258,
57101, 56942, 56782, 56621, 56458, 56294, 56129, 55962,
55794, 55624, 55454, 55282, 55108, 54933, 54757, 54580,
54401, 54221, 54040, 53857, 53673, 53488, 53301, 53114,
52925, 52734, 52543, 52350, 52155, 51960, 51763, 51565,
51366, 51166, 50964, 50761, 50557, 50352, 50146, 49938,
49729, 49519, 49307, 49095, 48881, 48666, 48450, 48233,
48015, 47795, 47575, 47353, 47130, 46906, 46680, 46454,
/* imlt_cos_table_16[80] (640/8) */
65535, 65528, 65516, 65497, 65472, 65440, 65402, 65358,
65307, 65251, 65188, 65118, 65043, 64961, 64873, 64778,
64678, 64571, 64458, 64338, 64213, 64081, 63943, 63799,
63649, 63493, 63330, 63162, 62987, 62806, 62619, 62427,
62228, 62023, 61812, 61595, 61373, 61144, 60910, 60669,
60423, 60171, 59913, 59650, 59380, 59105, 58824, 58538,
58246, 57948, 57645, 57336, 57022, 56702, 56376, 56046,
55709, 55368, 55021, 54669, 54311, 53949, 53581, 53208,
52830, 52446, 52058, 51665, 51266, 50863, 50455, 50042,
49624, 49201, 48774, 48342, 47905, 47464, 47018, 46567,
/* imlt_cos_table_8[40] (640/16) */
65532, 65507, 65457, 65381, 65280, 65154, 65002, 64826,
64625, 64399, 64148, 63872, 63571, 63247, 62897, 62524,
62126, 61705, 61259, 60790, 60298, 59782, 59243, 58682,
58098, 57491, 56862, 56212, 55539, 54846, 54131, 53395,
52639, 51862, 51065, 50249, 49413, 48558, 47685, 46793,
/* imlt_cos_table_4[20] (640/32) */
65523, 65422, 65220, 64917, 64515, 64013, 63412, 62714,
61918, 61028, 60043, 58965, 57797, 56540, 55195, 53765,
52253, 50660, 48988, 47241,
/* imlt_cos_table_2[10] (640/64) */
65485, 65081, 64276, 63075, 61485, 59516, 57179, 54491,
51466, 48124,
/* imlt_cos_table_1[5] (640/128) */
65333, 63725, 60547, 55878, 49833,
/* extra */
0,
};
/* see cos table info */
static const uint16_t imlt_sin_tables[636] = { /* "sin_table" */
/* imlt_sin_table_64[320] (640/2) */
80, 241, 402, 562, 723, 884, 1045, 1206,
1367, 1527, 1688, 1849, 2010, 2171, 2331, 2492,
2653, 2814, 2974, 3135, 3296, 3456, 3617, 3777,
3938, 4098, 4259, 4420, 4580, 4740, 4901, 5061,
5222, 5382, 5542, 5702, 5863, 6023, 6183, 6343,
6503, 6663, 6823, 6983, 7143, 7303, 7463, 7623,
7782, 7942, 8102, 8261, 8421, 8580, 8740, 8899,
9058, 9218, 9377, 9536, 9695, 9854, 10013, 10172,
10331, 10490, 10649, 10807, 10966, 11124, 11283, 11441,
11600, 11758, 11916, 12074, 12232, 12390, 12548, 12706,
12864, 13021, 13179, 13337, 13494, 13651, 13809, 13966,
14123, 14280, 14437, 14594, 14751, 14907, 15064, 15220,
15377, 15533, 15689, 15845, 16001, 16157, 16313, 16469,
16625, 16780, 16936, 17091, 17246, 17401, 17556, 17711,
17866, 18021, 18175, 18330, 18484, 18638, 18793, 18947,
19101, 19254, 19408, 19562, 19715, 19868, 20022, 20175,
20328, 20481, 20633, 20786, 20938, 21091, 21243, 21395,
21547, 21699, 21851, 22002, 22154, 22305, 22456, 22607,
22758, 22909, 23059, 23210, 23360, 23511, 23661, 23811,
23960, 24110, 24259, 24409, 24558, 24707, 24856, 25005,
25153, 25302, 25450, 25598, 25746, 25894, 26042, 26189,
26337, 26484, 26631, 26778, 26925, 27071, 27217, 27364,
27510, 27656, 27801, 27947, 28092, 28238, 28383, 28528,
28672, 28817, 28961, 29105, 29250, 29393, 29537, 29681,
29824, 29967, 30110, 30253, 30395, 30538, 30680, 30822,
30964, 31106, 31247, 31388, 31529, 31670, 31811, 31952,
32092, 32232, 32372, 32512, 32651, 32791, 32930, 33069,
33208, 33346, 33485, 33623, 33761, 33898, 34036, 34173,
34311, 34447, 34584, 34721, 34857, 34993, 35129, 35265,
35400, 35535, 35670, 35805, 35940, 36074, 36208, 36342,
36476, 36610, 36743, 36876, 37009, 37142, 37274, 37406,
37538, 37670, 37801, 37933, 38064, 38195, 38325, 38456,
38586, 38716, 38845, 38975, 39104, 39233, 39362, 39490,
39618, 39746, 39874, 40002, 40129, 40256, 40383, 40509,
40636, 40762, 40887, 41013, 41138, 41263, 41388, 41513,
41637, 41761, 41885, 42009, 42132, 42255, 42378, 42501,
42623, 42745, 42867, 42988, 43110, 43231, 43351, 43472,
43592, 43712, 43832, 43951, 44070, 44189, 44308, 44426,
44544, 44662, 44780, 44897, 45014, 45131, 45247, 45364,
45480, 45595, 45711, 45826, 45941, 46055, 46170, 46284,
/* imlt_sin_table_32[160] (640/4) */
160, 482, 804, 1125, 1447, 1769, 2090, 2412,
2733, 3055, 3376, 3697, 4018, 4339, 4660, 4981,
5302, 5622, 5943, 6263, 6583, 6903, 7223, 7543,
7862, 8181, 8501, 8819, 9138, 9456, 9775, 10093,
10410, 10728, 11045, 11362, 11679, 11995, 12311, 12627,
12943, 13258, 13573, 13887, 14202, 14515, 14829, 15142,
15455, 15767, 16079, 16391, 16702, 17013, 17324, 17634,
17943, 18253, 18561, 18870, 19177, 19485, 19792, 20098,
20404, 20710, 21015, 21319, 21623, 21926, 22229, 22532,
22833, 23135, 23435, 23736, 24035, 24334, 24633, 24930,
25228, 25524, 25820, 26116, 26410, 26704, 26998, 27291,
27583, 27874, 28165, 28455, 28745, 29033, 29321, 29609,
29895, 30181, 30467, 30751, 31035, 31318, 31600, 31881,
32162, 32442, 32721, 32999, 33277, 33554, 33830, 34105,
34379, 34652, 34925, 35197, 35468, 35738, 36007, 36275,
36543, 36810, 37075, 37340, 37604, 37867, 38129, 38390,
38651, 38910, 39168, 39426, 39682, 39938, 40192, 40446,
40699, 40950, 41201, 41451, 41699, 41947, 42194, 42439,
42684, 42928, 43170, 43412, 43652, 43891, 44130, 44367,
44603, 44839, 45073, 45306, 45537, 45768, 45998, 46227,
/* imlt_sin_table_16[80] (640/8) */
321, 965, 1608, 2251, 2894, 3536, 4179, 4821,
5462, 6103, 6743, 7383, 8022, 8660, 9297, 9934,
10569, 11204, 11837, 12469, 13100, 13730, 14359, 14986,
15611, 16235, 16858, 17479, 18098, 18716, 19331, 19945,
20557, 21167, 21775, 22381, 22984, 23586, 24185, 24782,
25376, 25968, 26557, 27144, 27729, 28310, 28889, 29465,
30038, 30609, 31176, 31741, 32302, 32860, 33415, 33967,
34516, 35061, 35603, 36141, 36676, 37208, 37736, 38260,
38780, 39297, 39810, 40319, 40825, 41326, 41823, 42317,
42806, 43291, 43772, 44249, 44721, 45189, 45653, 46112,
/* imlt_sin_table_8[40] (640/16) */
643, 1929, 3215, 4500, 5783, 7063, 8341, 9616,
10887, 12153, 13415, 14672, 15923, 17169, 18407, 19638,
20862, 22078, 23285, 24483, 25672, 26851, 28020, 29178,
30324, 31459, 32582, 33692, 34789, 35873, 36943, 37998,
39039, 40065, 41076, 42070, 43049, 44011, 44956, 45883,
/* imlt_sin_table_4[20] (640/32) */
1286, 3858, 6423, 8979, 11520, 14044, 16547, 19024,
21471, 23885, 26263, 28600, 30893, 33138, 35332, 37472,
39554, 41575, 43532, 45422,
/* imlt_sin_table_2[10] (640/64) */
2572, 7702, 12785, 17789, 22683, 27437, 32022, 36409,
40572, 44485,
/* imlt_sin_table_1[5] (640/128) */
5141, 15299, 25079, 34242, 42562,
/* extra */
0,
};
/*****************************************************************************
* UNPACK
*****************************************************************************/
#define REGION_POWER_TABLE_SIZE 64
#define REGION_POWER_TABLE_NUM_NEGATIVES 24
#define NUM_CATEGORIZATION_CONTROL_BITS 5
#define NUM_CATEGORIZATION_CONTROL_POSSIBILITIES 32
#define NUM_CATEGORIES 8
#define DRP_DIFF_MIN 12 /* used as negative */
//#define DRP_DIFF_MAX 11
#define NUM_BINS 16
//#define MAX_VECTOR_INDICES 625
#define MAX_VECTOR_DIMENSION 5
//#define ABS_REGION_POWER_LEVELS 32
#define NUMBER_OF_REGIONS 28
#define REGION_SIZE 20
#define DIFF_REGION_POWER_LEVELS 24
/* Default scale factor is a bit high due to something something and this compensates
* (using 9-1 may sound better since most Siren14 BNSF get a bit clippy) */
#define ESF_ADJUSTMENT_TO_RMS_INDEX (9-2)
/* vs refdec: has region 0 (unused, all 0s) and regions>13 (repeats of region 13) so they were removed.
* 2nd index only went to DIFF_REGION_POWER_LEVELS-1 and last was added (all 0s though so probably unused). */
static const int16_t differential_region_power_decoder_tree[NUMBER_OF_REGIONS][DIFF_REGION_POWER_LEVELS][2] = { /* "rms_table"? */
{{ 1, 2},{ 3, 4},{ 5, 6},{ 7, 8},{ 9, 10},{ 11,-12},{-11,-10},{ -8, -9},{ -7, -6},{-13, 12},{ -5, -4},{ 0, 13},{ -3,-14},{ -2, 14},{ -1, 15},{-15, 16},{-16, 17},{-17, 18},{ 19, 20},{ 21, 22},{-18,-19},{-20,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{ 7, 8},{-10, -9},{ -8,-11},{ -7, -6},{ 9, -5},{ 10,-12},{ -4, 11},{-13, -3},{ 12, -2},{ 13,-14},{ -1, 14},{ 15,-15},{ 0, 16},{-16, 17},{-17, 18},{-18, 19},{ 20, 21},{ 22,-19},{-20,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{ 7, 8},{ 9, 10},{-12, 11},{-11,-13},{-10, -9},{ 12,-14},{ -8, -7},{-15, -6},{ 13, -5},{-16, -4},{ 14,-17},{ 15, -3},{ 16,-18},{ -2, 17},{ 18,-19},{ -1, 19},{-20, 20},{ 0, 21},{ 22,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{-11,-10},{ 7,-12},{ 8, -9},{ 9,-13},{-14, 10},{ -8,-15},{-16, 11},{ -7, 12},{-17, -6},{ 13, 14},{-18, 15},{ -5, -4},{ 16, 17},{ -3, -2},{-19, 18},{ -1, 19},{-20, 20},{ 21, 22},{ 0,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{-12,-11},{-13, 7},{ 8,-14},{-10, 9},{ 10,-15},{ -9, 11},{ -8, 12},{-16, 13},{ -7, -6},{-17, 14},{ -5,-18},{ 15, -4},{ 16,-19},{ 17, -3},{-20, 18},{ -2, 19},{-21, 20},{ 0, 21},{ 22, -1},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{-11, 7},{-12,-10},{-13, -9},{ 8, 9},{-14, -8},{ 10,-15},{ -7, 11},{-16, 12},{ -6,-17},{ 13, 14},{ -5, 15},{-18, 16},{ -4, 17},{ -3,-19},{ 18, -2},{-20, 19},{ -1, 20},{ 0, 21},{ 22,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5,-12},{ 6,-11},{-10,-13},{ -9, 7},{ 8,-14},{ 9, -8},{-15, 10},{ -7,-16},{ 11, -6},{ 12,-17},{ 13, -5},{-18, 14},{ 15, -4},{-19, 16},{ 17, -3},{-20, 18},{ 19, 20},{ 21, 22},{ 0, -2},{ -1,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5,-12},{ 6,-13},{-11,-10},{ 7,-14},{ 8, -9},{ 9,-15},{ -8, 10},{ -7,-16},{ 11, 12},{ -6,-17},{ -5, 13},{ 14, 15},{-18, -4},{-19, 16},{ -3, 17},{ 18, -2},{-20, 19},{ 20, 21},{ 22, 0},{ -1,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{-11,-10},{-12, -9},{ 7, 8},{-13, -8},{ 9,-14},{ -7, 10},{ -6,-15},{ 11, 12},{ -5,-16},{ 13, 14},{-17, 15},{ -4, 16},{ 17,-18},{ 18, -3},{ -2, 19},{ -1, 0},{-19, 20},{-20, 21},{ 22,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5, 6},{-11, 7},{-10,-12},{ -9, 8},{ -8,-13},{ 9, -7},{ 10,-14},{ -6, 11},{-15, 12},{ -5, 13},{-16, -4},{ 14, 15},{-17, -3},{-18, 16},{ 17,-19},{ -2, 18},{-20, 19},{ -1, 20},{ 21, 22},{ 0,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5,-12},{ 6,-11},{ 7, 8},{-10,-13},{ -9, 9},{ -8,-14},{ 10, -7},{ 11,-15},{ -6, 12},{ -5, 13},{ -4,-16},{ 14, 15},{ -3,-17},{ 16, 17},{-18, -2},{ 18,-19},{ -1, 19},{-20, 20},{-21, 21},{ 22, 0},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{ 5,-12},{-13, 6},{-11, 7},{-14, 8},{-10, 9},{-15, -9},{ -8, 10},{ -7,-16},{ 11, -6},{ 12, -5},{-17, 13},{ 14,-18},{ 15, -4},{ 16,-19},{ 17, -3},{ 18, -2},{ 19, -1},{-20, 20},{ 21, 22},{ 0,-21},{-22,-23},{ 0, 0}},
{{ 1, 2},{ 3, 4},{-12, 5},{-11,-13},{ 6,-14},{-10, 7},{ 8,-15},{ -9, 9},{-16, 10},{ -8,-17},{ 11, 12},{ -7,-18},{ -6, 13},{ 14, -5},{ 15,-19},{ -4, 16},{-20, 17},{ 18, 19},{ 20, 21},{ 22, 0},{ -1, -3},{ -2,-21},{-22,-23},{ 0, 0}},
};
/* vs refdec: same table */
static const int16_t mlt_quant_centroid[NUM_CATEGORIES][NUM_BINS] = { /* "mlt_q" */
{ 0, 1606, 3119, 4586, 6049, 7502, 8941,10406,11851,13292,14736,16146,17566,19351, 0, 0},
{ 0, 2229, 4341, 6401, 8471,10531,12583,14588,16673,18924, 0, 0, 0, 0, 0, 0},
{ 0, 3055, 5998, 8929,11806,14680,17680, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 4121, 8192,12259,16322, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 5413,11071,16315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 6785,14300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 8044, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 8019, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
/* vs refdec: Namco uses a stack array with these values */
static const int16_t expected_bits_table[NUM_CATEGORIES] = {
52, 47, 43, 37, 29, 22, 16, 0
};
/* vs refdec: Namco uses positive values *2 but I'm not sure what they are for (some index access)
* so these are the refdec values */
static const int16_t mlt_decoder_tree_category_0[180][2] = { /* "reasion_huffman_table"? */
{ 1, 0},{ 2, 3},{ 4, 5},{ 6, 7},{ 8, 9},{ -1, -14},{ 10, 11},{ 12, 13},
{ 14, 15},{ 16, 17},{ 18, 19},{ -15, 20},{ 21, 22},{ 23, -28},{ 24, -2},{ 25, 26},
{ 27, 28},{ 29, 30},{ 31, 32},{ -29, 33},{ -16, 34},{ -3, 35},{ 36, 37},{ -42, 38},
{ 39, 40},{ 41, 42},{ 43, 44},{ -17, 45},{ -43, 46},{ 47, 48},{ -4, 49},{ -56, 50},
{ 51, 52},{ 53, 54},{ 55, 56},{ -57, -5},{ -30, 57},{ 58, 59},{ -18, 60},{ 61, -70},
{ 62, 63},{ 64, -6},{ 65, 66},{ -44, 67},{ -71, 68},{ 69, 70},{ -19, -31},{ -84, 71},
{ 72, 73},{ 74, 75},{ 76, 77},{ -7, 78},{ 79, -20},{ 80, 81},{ -85, 82},{ -98, 83},
{ -58, 84},{ 85, -32},{ -99, 86},{ -8, 87},{ 88, 89},{ -72, -45},{ 90, -33},{ 91,-112},
{ -21, 92},{ -59,-113},{ -46, 93},{ -9, 94},{ -22, 95},{ 96, 97},{ 98, 99},{ -23, -86},
{ 100, 101},{ -34, -73},{ 102,-126},{-127, -35},{ 103, -47},{ 104, 105},{ 106, 107},{-140,-100},
{-114, -87},{ 108, 109},{ 110, 111},{-141, -60},{ 112, -48},{ 113, -24},{ -10, -61},{ 114,-101},
{ 115, 116},{ -74, -36},{ 117,-128},{ 118, -62},{ 119, 120},{ -37, 121},{ -11, -49},{ -88, 122},
{ 123,-115},{-154, -25},{-142, 124},{-155,-129},{ 125, -50},{ 126, 127},{ -76, -75},{ 128, 129},
{ -63, -77},{-102, -39},{ -38, 130},{ -51, 131},{ -89,-116},{-117,-156},{ 132, -52},{ -78, 133},
{ 134,-103},{ 135, 136},{-143, -65},{ 137, -64},{-130,-131},{ -90, 138},{-104, -91},{ -92, 139},
{-169,-183},{ -26,-118},{ 140, 141},{-144, -66},{ -12, 142},{-168, 143},{-105,-157},{ 144,-182},
{ 145, 146},{ -79, 147},{ -53,-170},{ 148, 149},{ -27,-145},{ 150, -80},{-106, -13},{-132, -67},
{-158, -40},{-119, 151},{ 152,-107},{ 153, 154},{ -41,-184},{ 155, 156},{ -54, 157},{-171, 158},
{ -94, 159},{-134,-146},{ -93,-133},{-159,-108},{ 160, -81},{ 161,-160},{ 162, -68},{-120,-122},
{-172, 163},{ -55, -95},{ 164,-109},{-161, -82},{-173,-185},{ 165, -69},{-147,-186},{ 166, 167},
{-121, -96},{ 168,-148},{-174, 169},{ 170,-136},{ -83, 171},{ 172, 173},{-135,-110},{-187, 174},
{-149,-150},{ 175,-123},{-162,-163},{ -97,-175},{-188, 176},{ 177, 178},{ 179,-111},{-151,-124},
{-137,-177},{-176,-125},{-164,-138},{-189,-190},};
static const int16_t mlt_decoder_tree_category_1[93][2] = {
{ 1, 0},{ 2, 3},{ 4, 5},{ 6, 7},{ 8, -10},{ -1, 9},{ 10, 11},{ 12, 13},
{ -11, 14},{ 15, 16},{ 17, 18},{ -20, -2},{ 19, 20},{ -21, 21},{ 22, 23},{ -12, 24},
{ 25, 26},{ 27, 28},{ 29, 30},{ -30, 31},{ -31, -3},{ 32, -22},{ 33, -13},{ 34, 35},
{ 36, 37},{ 38, 39},{ 40, -4},{ -41, -14},{ 41, -40},{ -32, 42},{ 43, -23},{ 44, 45},
{ 46, 47},{ 48, -5},{ -51, -50},{ -42, 49},{ -33, 50},{ -15, 51},{ 52, 53},{ 54, -24},
{ 55, -43},{ 56, -52},{ 57, -61},{ -60, 58},{ -25, 59},{ -16, -34},{ -6, 60},{ -62, 61},
{ -71, 62},{ -35, -7},{ 63, -72},{ -53, -17},{ 64, -44},{ -26, -70},{ 65, -45},{ -36, 66},
{ -63, 67},{ -80, -54},{ -81, 68},{ -27, 69},{ 70, -82},{ -18, 71},{ 72, -55},{ 73, -64},
{ 74, -73},{ 75, -46},{ -37, 76},{ -91, -8},{ -9, 77},{ -90, -83},{ 78, -28},{ 79, -56},
{ -65, -38},{ -74, 80},{ -19, -57},{ -92, 81},{ -47, -48},{ 82, -66},{ 83, -29},{ -84, 84},
{ -75, -85},{ -67, -93},{ -39, 85},{ -76, 86},{ -58, 87},{ 88, -49},{ -94, 89},{ 90, -68},
{ 91, -78},{ -86, -59},{ -77, -95},{ 92, -69},{ -87, -96},};
static const int16_t mlt_decoder_tree_category_2[47][2] = {
{ 1, 0},{ 2, 3},{ 4, 5},{ 6, -7},{ -1, 7},{ -8, 8},{ 9, 10},{ 11, 12},
{ 13, -14},{ -15, -9},{ -2, 14},{ 15, 16},{ 17, 18},{ 19, -16},{ 20, -22},{ -10, 21},
{ -21, -3},{ 22, 23},{ 24, 25},{ -23, -17},{ 26, 27},{ 28, -29},{ -11, -28},{ 29, 30},
{ -4, -24},{ -30, 31},{ 32, -18},{ 33, -35},{ -36, 34},{ -31, -12},{ 35, -25},{ -5, -37},
{ 36, 37},{ -42, 38},{ -19, -43},{ -32, 39},{ -13, -38},{ -26, -20},{ 40, -6},{ -44, 41},
{ 42, -39},{ -33, -45},{ 43, -27},{ 44, -46},{ 45, -34},{ -40, 46},{ -41, -47},};
static const int16_t mlt_decoder_tree_category_3[519][2] = {
{ 1, 2},{ 3, 4},{ 5, 0},{ 6, 7},{ 8, 9},{ 10, 11},{ 12, 13},{ 14, 15},
{ 16, 17},{-125, 18},{ -1, 19},{ 20, 21},{ 22, 23},{ 24, 25},{ -5, -25},{ 26, 27},
{ -6,-150},{ 28, 29},{ 30, 31},{ 32, 33},{ 34, -30},{ 35, 36},{ 37, 38},{ 39, -31},
{-126,-155},{ 40, 41},{-156, 42},{ 43,-130},{ 44,-131},{-151, -26},{ 45, 46},{-250, 47},
{ 48, 49},{ 50, 51},{ 52,-275},{ 53, 54},{ -2, -7},{ 55, 56},{ 57, 58},{ 59, 60},
{ 61, 62},{ 63, 64},{ 65, 66},{ 67, 68},{ 69, 70},{ 71, -50},{ 72,-180},{ 73, 74},
{ 75, 76},{ 77, -55},{ 78,-175},{ 79, -36},{ 80, 81},{ -35, -10},{ 82, 83},{-280, 84},
{ -11, 85},{ 86, -32},{ 87, 88},{ 89,-161},{ 90,-276},{ 91, 92},{-281, 93},{ -8, 94},
{ 95, 96},{ 97,-157},{-181,-400},{-132, 98},{-375, 99},{-160, 100},{-127, 101},{ -27, 102},
{ 103,-251},{ -56, 104},{ 105,-256},{-300, -3},{-152,-255},{ 106, 107},{ -37, 108},{-305, 109},
{-176, 110},{-136, 111},{ -12, 112},{ 113, 114},{ 115,-135},{ 116, 117},{-162, 118},{ -16, -51},
{-186, 119},{ 120, 121},{ 122, 123},{ -41, 124},{ -61, 125},{ 126, 127},{ 128, 129},{ 130, -60},
{ 131, 132},{-306, 133},{ 134,-205},{-405, 135},{ 136, 137},{ 138, 139},{-185, 140},{ 141,-500},
{ -15, 142},{ 143, -80},{ -75, -40},{-301, 144},{ 145, 146},{-200, 147},{ 148, 149},{ 150, 151},
{ 152,-525},{ 153,-177},{-425, 154},{ 155, -13},{-430, 156},{ 157,-406},{ 158, 159},{-206,-380},
{ 160, 161},{ 162, 163},{ 164,-182},{-137, 165},{-286, 166},{ 167,-401},{ 168, 169},{ -42, -33},
{ 170,-166},{ -57,-325},{ 171,-187},{ -38, 172},{ 173, 174},{-165,-330},{ -4,-282},{ 175,-257},
{-261,-311},{-376, 176},{ 177, 178},{ -28, 179},{ 180, -9},{-285, 181},{ 182, 183},{ 184,-277},
{ 185,-133},{-310, -81},{ -85, 186},{-158,-210},{ -17, 187},{ 188, 189},{ 190, -52},{-141, 191},
{ 192,-128},{-191, -20},{ 193,-140},{ 194, 195},{-211,-260},{ 196, 197},{ 198, 199},{ 200, -66},
{-201,-225},{-381, 201},{ 202, 203},{ 204, 205},{ 206, 207},{-163,-287},{ 208,-100},{ 209, 210},
{ 211, 212},{ 213,-252},{-105, -76},{ 214, 215},{ 216, -21},{ -86, -62},{-307, 217},{ -65,-455},
{-550, 218},{ 219, 220},{ 221, 222},{ 223, 224},{ 225,-230},{-142, 226},{-302,-426},{-431, 227},
{ 228, 229},{ 230,-190},{-402, -46},{-153,-450},{-505, 231},{ 232, 233},{ 234, 235},{ 236, 237},
{ 238, 239},{-262, -29},{ 240, 241},{ 242, 243},{-167, -67},{-331,-530},{ 244, 245},{ 246, 247},
{ 248, 249},{ 250, 251},{ 252, 253},{ 254, 255},{ 256, 257},{ 258, 259},{ 260, 261},{ 262,-336},
{ 263,-171},{-192,-207},{-258,-138},{ 264, 265},{ 266, 267},{ 268, 269},{ 270, 271},{ 272, 273},
{ 274, -45},{-335,-411},{ -43, -18},{-265, -71},{-316,-326},{-350,-407},{-146, -14},{ 275, 276},
{ 277, 278},{ 279, 280},{ 281,-216},{ -34,-283},{-291,-312},{-410,-168},{-555, 282},{ -70, -53},
{-235, -87},{ -77,-183},{-315,-332},{-178, -58},{ 283, 284},{ 285, 286},{ 287, 288},{ 289, 290},
{ 291, 292},{ 293, 294},{ 295, 296},{ 297, 298},{-202,-226},{-170,-267},{-134,-290},{-355,-385},
{-386, -47},{-526,-196},{ 299, 300},{ 301, 302},{ 303, 304},{ 305, 306},{ 307, 308},{ 309, 310},
{ 311, 312},{ 313, 314},{ 315, 316},{ 317, 318},{ 319, 320},{ 321, 322},{ 323, 324},{ 325,-111},
{-231,-253},{ -91, -82},{-172,-145},{ -22,-317},{ -90,-356},{-382,-159},{ 326, 327},{ 328, 329},
{ 330, 331},{ 332, 333},{ 334, 335},{-106,-263},{-278,-215},{-110, -39},{-101,-377},{-129, -63},
{-436,-195},{-506,-531},{ 336,-212},{-154,-266},{ -59,-288},{-292,-303},{-337,-432},{-188,-451},
{-456,-460},{-501,-236},{-551, 337},{ 338, 339},{ 340, 341},{ 342, 343},{ 344, 345},{ 346, 347},
{ 348, 349},{ 350, 351},{ 352, 353},{ 354, 355},{ 356, 357},{ 358, 359},{ 360, 361},{ 362, 363},
{ 364, 365},{ 366, 367},{ 368, 369},{ 370, 371},{ 372, 373},{ 374, 375},{ 376, 377},{ 378, 379},
{ 380, 381},{ 382, 383},{ 384, 385},{ 386, 387},{ 388, 389},{ 390, 391},{ 392, 393},{ 394, 395},
{ 396, 397},{ 398, 399},{ 400, 401},{ 402, 403},{ 404, 405},{ 406, 407},{ -72,-272},{-309,-333},
{-340,-360},{ -68,-387},{-184,-416},{-427,-147},{-435,-437},{-115,-480},{-510,-532},{-164,-556},
{ 408,-295},{-296,-297},{-107,-313},{-193,-173},{-320,-327},{-341,-351},{-352,-143},{-378, -19},
{-403,-412},{-268, -54},{ -83,-441},{-442,-457},{-475, -44},{ -97,-511},{-515,-208},{-527,-528},
{-237,-536},{-552, 409},{ 410, 411},{ 412, 413},{ 414, 415},{ 416, 417},{ 418, 419},{ 420, 421},
{ 422, 423},{ 424, 425},{ 426, 427},{ 428, 429},{ 430, 431},{ 432, 433},{ 434, 435},{ 436, 437},
{ 438, 439},{ 440, 441},{ 442, 443},{ 444, 445},{ 446, 447},{ 448, 449},{ 450, 451},{ 452, 453},
{ 454, 455},{ 456, 457},{ 458, 459},{ 460, 461},{ 462, 463},{ 464, 465},{ 466, 467},{ 468, 469},
{ 470, 471},{ 472, 473},{ 474, 475},{ 476, 477},{ 478, 479},{ 480, 481},{ 482, 483},{ 484, 485},
{ 486, 487},{ 488, 489},{ 490, 491},{ 492, 493},{ 494, 495},{ 496, 497},{ 498, 499},{ 500, 501},
{ 502, 503},{ 504, 505},{ 506, 507},{ 508, 509},{ 510, 511},{ 512, 513},{ 514, 515},{ 516, 517},
{ 518,-104},{ -84,-218},{-318,-319},{-117,-321},{-322,-323},{-219,-174},{-243,-328},{-329, -94},
{-228,-194},{-240,-334},{-102,-229},{-169,-338},{-339,-116},{-289,-342},{-343,-345},{-346,-347},
{ -23,-203},{-214,-353},{-204,-220},{-357,-358},{-264,-361},{-362,-363},{-365,-366},{-367, -92},
{-245,-121},{-293,-379},{-108,-232},{-221,-383},{-384,-233},{-294,-241},{-388,-389},{-390,-391},
{-392,-393},{-394,-395},{-396,-397},{-398, -24},{-109,-149},{-242,-404},{ -64, -79},{ -89,-408},
{-409,-213},{-120,-113},{-413,-414},{-415, -96},{-417,-418},{-419,-420},{-421,-422},{-423,-298},
{ -69,-269},{-428,-429},{ -78,-270},{ -88,-433},{-434,-271},{-234,-259},{-438,-439},{-440,-227},
{-179,-443},{-445,-446},{-447,-223},{-238,-452},{-453,-454},{-273,-254},{-246,-458},{-459, -48},
{-461,-462},{-463,-465},{-466,-467},{-468,-470},{-471,-304},{-476,-477},{-478,-112},{-481,-482},
{-483,-485},{-486,-487},{-490,-491},{-103,-118},{-502,-503},{-504,-189},{ -93,-507},{-508,-509},
{-148,-139},{-512,-513},{-308,-516},{-517,-518},{-520,-521},{ -73, -98},{ -95, -49},{-529,-222},
{-217,-197},{-533,-534},{-535,-284},{-537,-538},{-540,-541},{-542,-543},{-545,-546},{-144,-198},
{-314,-553},{-209,-279},{-557,-558},{-560,-561},{-562,-563},{-565,-566},{-567,-575},{-576,-577},
{-578,-580},{-581,-582},{-583,-585},{-586,-587},{-590,-591},{-600,-601},{-605,-606},};
static const int16_t mlt_decoder_tree_category_4[208][2] = {
{ 1, 2},{ 3, 0},{ 4, 5},{ 6, 7},{ 8, 9},{ 10, 11},{ 12, -64},{ -1, 13},
{ 14, -16},{ -4, 15},{ 16, 17},{ 18, -80},{ -5, 19},{ 20, 21},{ -20, 22},{ 23, -65},
{ -84, -21},{ -68, 24},{ -17, 25},{ 26, 27},{ 28, -81},{ -69, -85},{ 29, 30},{ 31, 32},
{-128, 33},{ 34, 35},{ -2, 36},{ 37, 38},{-144, 39},{ 40, -6},{ 41, 42},{ -32, 43},
{ 44, -8},{ 45, -25},{ -96, 46},{ 47,-100},{ -9, 48},{ 49, -36},{ 50, -24},{ 51, 52},
{ 53,-148},{ 54, 55},{ -22, 56},{ 57, 58},{-132, -89},{ 59, 60},{-101, 61},{ -37, 62},
{ -18, 63},{ -88,-129},{ -66, -70},{ -97, 64},{ -72, -73},{ 65,-145},{-149, -86},{ 66, -33},
{ 67,-133},{ 68, 69},{ 70, 71},{-192, 72},{ 73,-160},{ -82, 74},{-164, 75},{ -10, 76},
{ 77,-208},{ 78, -40},{ 79, 80},{ -3, 81},{ -7, 82},{ 83, 84},{-104, 85},{ 86, -26},
{ 87,-105},{ 88,-112},{ 89, 90},{ 91, -41},{ 92, 93},{ 94, 95},{ -48, 96},{ -90, 97},
{ 98, -28},{ -52, 99},{ -12, 100},{ 101, -74},{ -13,-116},{-161, 102},{ 103, -29},{-102, 104},
{-152,-165},{ 105, 106},{ 107, 108},{ 109, 110},{ 111,-212},{ 112, 113},{-136, 114},{ 115,-137},
{ 116, -23},{ -19,-153},{ -98,-134},{-196, 117},{ 118, 119},{ -38,-193},{-113,-150},{-209, 120},
{ 121, -93},{ -83, 122},{ 123, 124},{ 125, 126},{ 127, 128},{ 129, 130},{ 131, -34},{-146, -53},
{ 132, 133},{ 134, 135},{ 136, 137},{ 138,-130},{ -49, 139},{ 140, 141},{-117, -42},{ -67, -92},
{ 142, -87},{ -77,-197},{ -71, 143},{ 144, 145},{ 146, 147},{ 148, 149},{ 150, 151},{ 152, 153},
{ 154, 155},{ 156, 157},{ 158, 159},{ 160, 161},{ 162, 163},{ 164, 165},{ 166, 167},{ 168, 169},
{-108, -76},{-168,-169},{-176, -44},{-224, -56},{ -45,-180},{ -11,-106},{-213, 170},{ 171, 172},
{ 173, 174},{ 175, 176},{ 177, 178},{ 179, 180},{ 181, 182},{ 183, 184},{ 185, 186},{ 187, 188},
{ 189, 190},{ 191, 192},{ 193, 194},{ 195, 196},{ 197, 198},{ 199, 200},{ 201, 202},{ 203, 204},
{ 205, 206},{ 207,-131},{ -30, -27},{ -43,-151},{ -75,-154},{-156,-162},{-109,-194},{-198,-201},
{-114,-225},{-228,-229},{-141,-142},{ -94,-124},{ -95,-147},{-115,-125},{ -54, -55},{-107, -58},
{ -39,-155},{-121,-157},{-158,-103},{ -14,-122},{-163, -51},{ -57,-166},{-167, -46},{-110,-170},
{-172,-173},{ -61,-177},{-178, -99},{-181,-182},{-184,-185},{-118, -35},{ -15,-195},{ -31, -60},
{-135,-199},{-200, -79},{-202,-204},{-205,-119},{ -91,-210},{-211, -78},{-120,-214},{-215,-216},
{-217,-218},{-220,-221},{ -50,-138},{-226,-139},{-140,-230},{-232,-233},{-240,-241},{-244,-245},};
static const int16_t mlt_decoder_tree_category_5[191][2] = {
{ 1, 2},{ 0, 3},{ 4, 5},{ 6, 7},{ 8, 9},{ 10, 11},{ -81, -1},{ 12, 13},
{ 14, -27},{ -3, -9},{ 15, 16},{ 17, 18},{ 19, 20},{-108, 21},{ -4, 22},{ 23, -36},
{ -12, 24},{ -82, 25},{ 26, -84},{ 27, -90},{ -10, -30},{ 28, 29},{ 30, -28},{ 31,-117},
{ -13, 32},{ -39, 33},{ 34,-109},{ 35, -93},{ -85,-111},{ -37, 36},{ -31, 37},{ -91, 38},
{ 39, 40},{ -40,-120},{ 41, 42},{-118, 43},{ -94, 44},{-112,-162},{ 45, 46},{ -2, 47},
{ 48, 49},{-121,-189},{ 50, -54},{ 51, 52},{ 53, -18},{ 54, 55},{ -6, 56},{ 57, -5},
{-135, 58},{ 59, 60},{ 61, 62},{ -63, 63},{ 64, -7},{ -15, 65},{ 66, 67},{ -45, 68},
{ 69, 70},{ 71, -21},{ 72, 73},{ 74, 75},{ 76, 77},{-163, 78},{ 79,-171},{-144, 80},
{ -48, 81},{ -57, 82},{ 83, 84},{-165, 85},{ -16,-198},{ 86, 87},{ -11, 88},{ 89, -99},
{ 90, -83},{ -19, 91},{ 92, 93},{ 94, 95},{ 96, 97},{ 98, 99},{ -87, 100},{ 101, 102},
{-190, -66},{ -33,-192},{ 103, 104},{ 105, 106},{-102, -42},{ 107,-126},{ 108, -29},{-129, -46},
{ -86, -14},{-114, -32},{-172, 109},{ 110, -58},{ -34,-138},{ 111, 112},{ 113, 114},{ 115, 116},
{ 117, 118},{ 119, 120},{-127,-166},{-174, 121},{ 122, 123},{ 124, 125},{ -88, -96},{ 126,-100},
{ -38,-110},{ -22,-136},{ -55,-139},{-201, 127},{ -64,-193},{ 128, -49},{-175,-199},{ 129, 130},
{ 131, 132},{ 133, 134},{ 135, 136},{ 137, 138},{ 139, 140},{ 141, 142},{ 143, 144},{ 145, 146},
{ 147, 148},{ 149, 150},{-103, -92},{ -43,-130},{-145,-147},{-148, -41},{-216,-115},{-119,-123},
{ -95, 151},{ 152, 153},{ 154, 155},{ 156, 157},{ 158, 159},{ 160, 161},{ 162, 163},{ 164, 165},
{ 166, 167},{ 168, 169},{ 170, 171},{ 172, 173},{ 174, 175},{ 176, 177},{ 178, 179},{ 180, 181},
{ 182, 183},{ 184, 185},{ 186, 187},{ 188, 189},{ 190,-153},{-180, -8},{ -97, -24},{-122,-113},
{-124,-125},{ -67, -44},{-128, -69},{-106,-131},{-132,-133},{ -61, -73},{-137,-116},{ -89,-140},
{-141,-142},{ -23, -25},{-146, -17},{-104,-149},{-150,-151},{ -52,-154},{-156,-157},{ -76, -70},
{-164, -51},{ -72,-167},{-168,-169},{ -47, -20},{-173, -59},{-101,-176},{-177,-178},{ -68,-181},
{-183,-184},{ -35, -60},{-191, -98},{ -56,-194},{-195,-196},{ -75, -65},{-200,-105},{-202,-203},
{-204,-205},{-207,-208},{-210,-211},{ -50,-217},{-219,-220},{-225,-226},{-228,-229},};
static const int16_t mlt_decoder_tree_category_6[31][2] = {
{ 1, 0},{ 2, 3},{ 4, 5},{ 6, 7},{ 8, -16},{ -1, -8},{ -2, -4},{ 9, 10},
{ 11, 12},{ 13, 14},{ 15, 16},{ 17, -24},{ -3, -12},{ -6, 18},{ 19, -20},{ -10, -5},
{ -17, -9},{ -18, 20},{ 21, 22},{ 23, 24},{ 25, -28},{ 26, -7},{ -14, -22},{ -26, -11},
{ 27, -19},{ -25, -13},{ -21, 28},{ 29, -30},{ -27, 30},{ -15, -29},{ -23, -31},};
static const int16_t *table_of_decoder_tables[NUM_CATEGORIES-1] = {
(const int16_t *)mlt_decoder_tree_category_0,
(const int16_t *)mlt_decoder_tree_category_1,
(const int16_t *)mlt_decoder_tree_category_2,
(const int16_t *)mlt_decoder_tree_category_3,
(const int16_t *)mlt_decoder_tree_category_4,
(const int16_t *)mlt_decoder_tree_category_5,
(const int16_t *)mlt_decoder_tree_category_6,
};
/* vs refdec: same table */
static const int16_t region_standard_deviation_table[REGION_POWER_TABLE_SIZE] = { /* "rnd_reg"? */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 2, 3, 4, 6, 8, 11,
16, 23, 32, 45, 64, 91, 128, 181,
256, 362, 512, 724, 1024, 1448, 2048, 2896,
4096,5793,8192,11585,16384,23170, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
};
/* the following tables don't use last index since category 7 isn't quantized */
/* vs refdec: same table but last index is 20 */
static const int16_t number_of_vectors[NUM_CATEGORIES] = {
10, 10, 10, 5, 5, 4, 4, 0,
};
/* vs refdec: same table but last index is 1 */
static const int16_t vector_dimension[NUM_CATEGORIES] = { /* "vd_inv"? */
2, 2, 2, 4, 4, 5, 5, 0,
};
/* vs refdec: pre-adds one instead of in runtime and last index is 1 */
static const int16_t max_bin_plus1[NUM_CATEGORIES] = { /* "kmax_p1" */
14, 10, 7, 5, 4, 3, 2, 0,
};
/* vs refdec: pre-scaled x2 (cat3 subs -1 and cat5/7 -2 too) */
static const uint16_t max_bin_plus_one_inverse_scaled[8] = { /* "kmax_p1_inv" */
4682, 6554, 9363, 13108, 16384, 21846, 32768, 0,
};
#endif

View File

@ -263,6 +263,26 @@ static void blitz_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset
if (*step_index > 88) *step_index=88;
}
static const int CIMAADPCM_INDEX_TABLE[16] = {8, 6, 4, 2, -1, -1, -1, -1,
-1, -1, -1, -1, 2, 4, 6, 8};
/* Capcom's MT Framework modified IMA, reverse engineered from the exe */
static void mtf_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
int sample_nibble, sample_decoded, step, delta;
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf;
sample_decoded = *hist1;
step = ADPCMTable[*step_index];
delta = step * (2 * sample_nibble - 15);
sample_decoded += delta;
*hist1 = sample_decoded;
*step_index += CIMAADPCM_INDEX_TABLE[sample_nibble];
if (*step_index < 0) *step_index=0;
if (*step_index > 88) *step_index=88;
}
/* ************************************ */
/* DVI/IMA */
/* ************************************ */
@ -298,6 +318,34 @@ void decode_standard_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int chann
stream->adpcm_step_index = step_index;
}
void decode_mtf_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo) {
int i, sample_count = 0;
int32_t hist1 = stream->adpcm_history1_32;
int step_index = stream->adpcm_step_index;
/* external interleave */
/* no header (external setup), pre-clamp for wrong values */
if (step_index < 0) step_index=0;
if (step_index > 88) step_index=88;
/* decode nibbles (layout: varies) */
for (i = first_sample; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
off_t byte_offset = is_stereo ?
stream->offset + i : /* stereo: one nibble per channel */
stream->offset + i/2; /* mono: consecutive nibbles */
int nibble_shift = is_stereo ?
((channel&1) ? 0:4) :
((i&1) ? 0:4);
mtf_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
outbuf[sample_count] = clamp16(hist1 >> 4);
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_index;
}
void decode_3ds_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i, sample_count;
int32_t hist1 = stream->adpcm_history1_32;

View File

@ -188,6 +188,7 @@ void decode_hevag(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspaci
hist3 * hevag_coefs[coef_index][2] +
hist4 * hevag_coefs[coef_index][3] ) / 32;
sample = (sample + (scale << (20 - shift_factor)) + 128) >> 8;
sample = clamp16(sample);
}
outbuf[sample_count] = sample;

View File

@ -0,0 +1,500 @@
#include "coding.h"
/* Relic Codec decoder, a fairly simple mono-interleave DCT-based codec.
*
* Decompiled from Relic's dec.exe with some info from Homeworld source code .h/lib
* files (released around 2003 through Relic Dev Network), accurate with minor +-1
* samples due to double<>float ops or maybe original compiler (Intel's) diffs.
*
* TODO: clean API, improve validations (can segfault on bad data) and naming
*/
/* mixfft.c */
extern void fft(int n, float *xRe, float *xIm, float *yRe, float *yIm);
static relic_codec_data* init_codec(int channels, int bitrate, int codec_rate);
static int decode_frame_next(VGMSTREAMCHANNEL* stream, relic_codec_data* data);
static void copy_samples(relic_codec_data* data, sample_t* outbuf, int32_t samples_to_get);
static void reset_codec(relic_codec_data* data);
#define RELIC_MAX_CHANNELS 2
#define RELIC_MAX_SCALES 6
#define RELIC_BASE_SCALE 10.0f
#define RELIC_FREQUENCY_MASKING_FACTOR 1.0f
#define RELIC_CRITICAL_BAND_COUNT 27
#define RELIC_PI 3.14159265358979323846f
#define RELIC_SIZE_LOW 128
#define RELIC_SIZE_MID 256
#define RELIC_SIZE_HIGH 512
#define RELIC_MAX_SIZE RELIC_SIZE_HIGH
#define RELIC_MAX_FREQ (RELIC_MAX_SIZE / 2)
#define RELIC_MAX_FFT (RELIC_MAX_SIZE / 4)
#define RELIC_BITRATE_22 256
#define RELIC_BITRATE_44 512
#define RELIC_BITRATE_88 1024
#define RELIC_BITRATE_176 2048
#define RELIC_MAX_FRAME_SIZE ((RELIC_BITRATE_176 / 8) + 0x04) /* extra 0x04 for the bitreader */
struct relic_codec_data {
/* decoder info */
int channels;
int frame_size;
int wave_size;
int freq_size;
int dct_mode;
int samples_mode;
/* decoder init state */
float scales[RELIC_MAX_SCALES]; /* quantization scales */
float dct[RELIC_MAX_SIZE];
float window[RELIC_MAX_SIZE];
/* decoder frame state */
uint8_t exponents[RELIC_MAX_CHANNELS][RELIC_MAX_FREQ]; /* quantization/scale indexes */
float freq1[RELIC_MAX_FREQ]; /* dequantized spectrum */
float freq2[RELIC_MAX_FREQ];
float wave_cur[RELIC_MAX_CHANNELS][RELIC_MAX_SIZE]; /* current frame samples */
float wave_prv[RELIC_MAX_CHANNELS][RELIC_MAX_SIZE]; /* previous frame samples */
/* sample state */
int32_t samples_discard;
int32_t samples_consumed;
int32_t samples_filled;
};
/* ************************************* */
relic_codec_data* init_relic(int channels, int bitrate, int codec_rate) {
return init_codec(channels, bitrate, codec_rate);
}
void decode_relic(VGMSTREAMCHANNEL* stream, relic_codec_data* data, sample_t* outbuf, int32_t samples_to_do) {
while (samples_to_do > 0) {
if (data->samples_consumed < data->samples_filled) {
/* consume samples */
int samples_to_get = (data->samples_filled - data->samples_consumed);
if (data->samples_discard) {
/* discard samples for looping */
if (samples_to_get > data->samples_discard)
samples_to_get = data->samples_discard;
data->samples_discard -= samples_to_get;
}
else {
/* get max samples and copy */
if (samples_to_get > samples_to_do)
samples_to_get = samples_to_do;
copy_samples(data, outbuf, samples_to_get);
samples_to_do -= samples_to_get;
outbuf += samples_to_get * data->channels;
}
/* mark consumed samples */
data->samples_consumed += samples_to_get;
}
else {
int ok = decode_frame_next(stream, data);
if (!ok) goto decode_fail;
}
}
return;
decode_fail:
/* on error just put some 0 samples */
VGM_LOG("RELIC: decode fail, missing %i samples\n", samples_to_do);
memset(outbuf, 0, samples_to_do * data->channels * sizeof(sample));
}
void reset_relic(relic_codec_data* data) {
if (!data) return;
reset_codec(data);
data->samples_filled = 0;
data->samples_consumed = 0;
data->samples_discard = 0;
}
void seek_relic(relic_codec_data* data, int32_t num_sample) {
if (!data) return;
reset_relic(data);
data->samples_discard = num_sample;
}
void free_relic(relic_codec_data* data) {
if (!data) return;
free(data);
}
/* ***************************************** */
static const int16_t critical_band_data[RELIC_CRITICAL_BAND_COUNT] = {
0, 1, 2, 3, 4, 5, 6, 7,
9, 11, 13, 15, 17, 20, 23, 27,
31, 37, 43, 51, 62, 74, 89, 110,
139, 180, 256
};
static void init_dct(float *dct, int dct_size) {
int i;
int dct_quarter = dct_size >> 2;
for (i = 0; i < dct_quarter; i++) {
double temp = ((float)i + 0.125f) * (RELIC_PI * 2.0f) * (1.0f / (float)dct_size);
dct[i] = sin(temp);
dct[dct_quarter + i] = cos(temp);
}
}
static int apply_idct(const float *freq, float *wave, const float *dct, int dct_size) {
int i;
float factor;
float out_re[RELIC_MAX_FFT];
float out_im[RELIC_MAX_FFT];
float in_re[RELIC_MAX_FFT];
float in_im[RELIC_MAX_FFT];
float wave_tmp[RELIC_MAX_SIZE];
int dct_half = dct_size >> 1;
int dct_quarter = dct_size >> 2;
int dct_3quarter = 3 * (dct_size >> 2);
/* prerotation? */
for (i = 0; i < dct_quarter; i++) {
float coef1 = freq[2 * i] * 0.5f;
float coef2 = freq[dct_half - 1 - 2 * i] * 0.5f;
in_re[i] = coef1 * dct[dct_quarter + i] + coef2 * dct[i];
in_im[i] = -coef1 * dct[i] + coef2 * dct[dct_quarter + i];
}
/* main FFT */
fft(dct_quarter, in_re, in_im, out_re, out_im);
/* postrotation, window and reorder? */
factor = 8.0 / sqrt(dct_size);
for (i = 0; i < dct_quarter; i++) {
float out_re_i = out_re[i];
out_re[i] = (out_re[i] * dct[dct_quarter + i] + out_im[i] * dct[i]) * factor;
out_im[i] = (-out_re_i * dct[i] + out_im[i] * dct[dct_quarter + i]) * factor;
wave_tmp[i * 2] = out_re[i];
wave_tmp[i * 2 + dct_half] = out_im[i];
}
for (i = 1; i < dct_size; i += 2) {
wave_tmp[i] = -wave_tmp[dct_size - 1 - i];
}
/* wave mix thing? */
for (i = 0; i < dct_3quarter; i++) {
wave[i] = wave_tmp[dct_quarter + i];
}
for (i = dct_3quarter; i < dct_size; i++) {
wave[i] = -wave_tmp[i - dct_3quarter];
}
return 0;
}
static void decode_frame(const float *freq1, const float *freq2, float *wave_cur, float *wave_prv, const float *dct, const float *window, int dct_size) {
int i;
float wave_tmp[RELIC_MAX_SIZE];
int dct_half = dct_size >> 1;
/* copy for first half(?) */
memcpy(wave_cur, wave_prv, RELIC_MAX_SIZE * sizeof(float));
/* transform frequency domain to time domain with DCT/FFT */
apply_idct(freq1, wave_tmp, dct, dct_size);
apply_idct(freq2, wave_prv, dct, dct_size);
/* overlap and apply window function to filter this block's beginning */
for (i = 0; i < dct_half; i++) {
wave_cur[dct_half + i] = wave_tmp[i] * window[i] + wave_cur[dct_half + i] * window[dct_half + i];
wave_prv[i] = wave_prv[i] * window[i] + wave_tmp[dct_half + i] * window[dct_half + i];
}
}
static void init_window(float *window, int dct_size) {
int i;
for (i = 0; i < dct_size; i++) {
window[i] = sin((float)i * (RELIC_PI / dct_size));
}
}
static void decode_frame_base(const float *freq1, const float *freq2, float *wave_cur, float *wave_prv, const float *dct, const float *window, int dct_mode, int samples_mode) {
int i;
float wave_tmp[RELIC_MAX_SIZE];
/* dec_relic only uses 512/512 mode, source references 256/256 (effects only?) too */
if (samples_mode == RELIC_SIZE_LOW) {
{
/* 128 DCT to 128 samples */
decode_frame(freq1, freq2, wave_cur, wave_prv, dct, window, RELIC_SIZE_LOW);
}
}
else if (samples_mode == RELIC_SIZE_MID) {
if (dct_mode == RELIC_SIZE_LOW) {
/* 128 DCT to 256 samples (repeat sample x2) */
decode_frame(freq1, freq2, wave_tmp, wave_prv, dct, window, RELIC_SIZE_LOW);
for (i = 0; i < 256 - 1; i += 2) {
wave_cur[i + 0] = wave_tmp[i >> 1];
wave_cur[i + 1] = wave_tmp[i >> 1];
}
}
else {
/* 256 DCT to 256 samples */
decode_frame(freq1, freq2, wave_cur, wave_prv, dct, window, RELIC_SIZE_MID);
}
}
else if (samples_mode == RELIC_SIZE_HIGH) {
if (dct_mode == RELIC_SIZE_LOW) {
/* 128 DCT to 512 samples (repeat sample x4) */
decode_frame(freq1, freq2, wave_tmp, wave_prv, dct, window, RELIC_SIZE_LOW);
for (i = 0; i < 512 - 1; i += 4) {
wave_cur[i + 0] = wave_tmp[i >> 2];
wave_cur[i + 1] = wave_tmp[i >> 2];
wave_cur[i + 2] = wave_tmp[i >> 2];
wave_cur[i + 3] = wave_tmp[i >> 2];
}
}
else if (dct_mode == RELIC_SIZE_MID) {
/* 256 DCT to 512 samples (repeat sample x2) */
decode_frame(freq1, freq2, wave_tmp, wave_prv, dct, window, RELIC_SIZE_MID);
for (i = 0; i < 512 - 1; i += 2) {
wave_cur[i + 0] = wave_tmp[i >> 1];
wave_cur[i + 1] = wave_tmp[i >> 1];
}
}
else {
/* 512 DCT to 512 samples */
decode_frame(freq1, freq2, wave_cur, wave_prv, dct, window, RELIC_SIZE_HIGH);
}
}
}
/* reads 32b max, packed in LSB order per byte (like Vorbis), ex.
* with 0x45 6A=01000101 01101010 could read 4b=0101, 6b=100100, 3b=010 ...
* assumes buf has enough extra bits to read 32b (size +0x04) */
static uint32_t read_ubits(uint8_t bits, uint32_t offset, uint8_t *buf) {
uint32_t shift, mask, pos, val;
shift = offset - 8 * (offset / 8);
mask = (1 << bits) - 1;
pos = offset / 8;
val = (buf[pos+0]) | (buf[pos+1]<<8) | (buf[pos+2]<<16) | (buf[pos+3]<<24);
return (val >> shift) & mask;
}
static int read_sbits(uint8_t bits, uint32_t offset, uint8_t *buf) {
uint32_t val = read_ubits(bits, offset, buf);
if (val >> (bits - 1) == 1) { /* upper bit = sign */
uint32_t mask = (1 << (bits - 1)) - 1;
return -(val & mask);
}
return val;
}
static void init_dequantization(float* scales) {
int i;
scales[0] = RELIC_BASE_SCALE;
for (i = 1; i < RELIC_MAX_SCALES; i++) {
scales[i] = scales[i - 1] * scales[0];
}
for (i = 0; i < RELIC_MAX_SCALES; i++) {
scales[i] = RELIC_FREQUENCY_MASKING_FACTOR / (double) ((1 << (i + 1)) - 1) * scales[i];
}
}
static void unpack_frame(uint8_t *buf, int buf_size, float *freq1, float *freq2, const float* scales, uint8_t *exponents, int freq_size) {
uint8_t flags, cb_bits, ev_bits, ei_bits, qv_bits;
int qv;
uint8_t ev;
uint8_t move, pos;
uint32_t bit_offset;
int i, j;
int freq_half = freq_size >> 1;
memset(freq1, 0, RELIC_MAX_FREQ * sizeof(float));
memset(freq2, 0, RELIC_MAX_FREQ * sizeof(float));
flags = read_ubits(2u, 0u, buf);
cb_bits = read_ubits(3u, 2u, buf);
ev_bits = read_ubits(2u, 5u, buf);
ei_bits = read_ubits(4u, 7u, buf);
bit_offset = 11;
/* reset exponents indexes */
if ((flags & 1) == 1) {
memset(exponents, 0, RELIC_MAX_FREQ);
}
/* read packed exponents indexes for all bands */
if (cb_bits > 0 && ev_bits > 0) {
pos = 0;
for (i = 0; i < RELIC_CRITICAL_BAND_COUNT - 1; i++) {
if (bit_offset >= 8*buf_size)
break;
move = read_ubits(cb_bits, bit_offset, buf);
bit_offset += cb_bits;
if (i > 0 && move == 0)
break;
pos += move;
ev = read_ubits(ev_bits, bit_offset, buf);
bit_offset += ev_bits;
for (j = critical_band_data[pos]; j < critical_band_data[pos + 1]; j++)
exponents[j] = ev;
}
}
/* read quantized values */
if (freq_half > 0 && ei_bits > 0) {
/* read first part */
pos = 0;
for (i = 0; i < RELIC_MAX_FREQ; i++) {
if (bit_offset >= 8*buf_size)
break;
move = read_ubits(ei_bits, bit_offset, buf);
bit_offset += ei_bits;
if (i > 0 && move == 0)
break;
pos += move;
qv_bits = exponents[pos];
qv = read_sbits(qv_bits + 2u, bit_offset, buf);
bit_offset += qv_bits + 2u;
if (qv != 0 && pos < freq_half && qv_bits < 6)
freq1[pos] = (float)qv * scales[qv_bits];
}
/* read second part, or clone it */
if ((flags & 2) == 2) {
memcpy(freq2, freq1, RELIC_MAX_FREQ * sizeof(float));
}
else {
pos = 0;
for (i = 0; i < RELIC_MAX_FREQ; i++) {
if (bit_offset >= 8*buf_size)
break;
move = read_ubits(ei_bits, bit_offset, buf);
bit_offset += ei_bits;
if (i > 0 && move == 0)
break;
pos += move;
qv_bits = exponents[pos];
qv = read_sbits(qv_bits + 2u, bit_offset, buf);
bit_offset += qv_bits + 2u;
if (qv != 0 && pos < freq_half && qv_bits < 6)
freq2[pos] = (float)qv * scales[qv_bits];
}
}
}
}
static int decode_frame_next(VGMSTREAMCHANNEL* stream, relic_codec_data* data) {
int ch;
int bytes;
uint8_t buf[RELIC_MAX_FRAME_SIZE];
for (ch = 0; ch < data->channels; ch++) {
/* clean extra bytes for bitreader */
memset(buf + data->frame_size, 0, RELIC_MAX_FRAME_SIZE - data->frame_size);
bytes = read_streamfile(buf, stream->offset, data->frame_size, stream->streamfile);
if (bytes != data->frame_size) goto fail;
stream->offset += data->frame_size;
unpack_frame(buf, sizeof(buf), data->freq1, data->freq2, data->scales, data->exponents[ch], data->freq_size);
decode_frame_base(data->freq1, data->freq2, data->wave_cur[ch], data->wave_prv[ch], data->dct, data->window, data->dct_mode, data->samples_mode);
}
data->samples_consumed = 0;
data->samples_filled = data->wave_size;
return 1;
fail:
return 0;
}
static void copy_samples(relic_codec_data* data, sample_t* outbuf, int32_t samples) {
int s, ch;
int ichs = data->channels;
int skip = data->samples_consumed;
for (ch = 0; ch < ichs; ch++) {
for (s = 0; s < samples; s++) {
double d64_sample = data->wave_cur[ch][skip + s];
int pcm_sample = clamp16(d64_sample);
/* f32 in PCM 32767.0 .. -32768.0 format, original code
* does some custom double-to-int rint() though */
//FQ_BNUM ((float)(1<<26)*(1<<26)*1.5)
//rint(x) ((d64 = (double)(x)+FQ_BNUM), *(int*)(&d64))
outbuf[s*ichs + ch] = pcm_sample;
}
}
}
static relic_codec_data* init_codec(int channels, int bitrate, int codec_rate) {
relic_codec_data *data = NULL;
if (channels > RELIC_MAX_CHANNELS)
goto fail;
data = calloc(1, sizeof(relic_codec_data));
if (!data) goto fail;
data->channels = channels;
/* dequantized freq1+2 size (separate from DCT) */
if (codec_rate < 22050) /* probably 11025 only */
data->freq_size = RELIC_SIZE_LOW;
if (codec_rate == 22050)
data->freq_size = RELIC_SIZE_MID;
if (codec_rate > 22050) /* probably 44100 only */
data->freq_size = RELIC_SIZE_HIGH;
/* default for streams (only a few mode combos are valid, see decode) */
data->wave_size = RELIC_SIZE_HIGH;
data->dct_mode = RELIC_SIZE_HIGH;
data->samples_mode = RELIC_SIZE_HIGH;
init_dct(data->dct, RELIC_SIZE_HIGH);
init_window(data->window, RELIC_SIZE_HIGH);
init_dequantization(data->scales);
memset(data->wave_prv, 0, RELIC_MAX_CHANNELS * RELIC_MAX_SIZE * sizeof(float));
switch(bitrate) {
case RELIC_BITRATE_22:
case RELIC_BITRATE_44:
case RELIC_BITRATE_88:
case RELIC_BITRATE_176:
data->frame_size = (bitrate / 8); /* 0x100 and 0x80 are common */
break;
default:
goto fail;
}
return data;
fail:
free_relic(data);
return NULL;
}
static void reset_codec(relic_codec_data* data) {
memset(data->wave_prv, 0, RELIC_MAX_CHANNELS * RELIC_MAX_SIZE * sizeof(float));
}

View File

@ -0,0 +1,618 @@
/* Original Relic code uses mixfft.c v1 by Jens Jorgen Nielsen, though was
* modified to use floats instead of doubles. This is a 100% decompilation
* that somehow resulted in the exact same code (no compiler optims set?),
* so restores comments back but removes/cleans globals (could be simplified). */
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/* ------------------------------------------------------------------------- */
/************************************************************************
fft(int n, double xRe[], double xIm[], double yRe[], double yIm[])
------------------------------------------------------------------------
NOTE : This is copyrighted material, Not public domain. See below.
------------------------------------------------------------------------
Input/output:
int n transformation length.
double xRe[] real part of input sequence.
double xIm[] imaginary part of input sequence.
double yRe[] real part of output sequence.
double yIm[] imaginary part of output sequence.
------------------------------------------------------------------------
Function:
The procedure performs a fast discrete Fourier transform (FFT) of
a complex sequence, x, of an arbitrary length, n. The output, y,
is also a complex sequence of length n.
y[k] = sum(x[m]*exp(-i*2*pi*k*m/n), m=0..(n-1)), k=0,...,(n-1)
The largest prime factor of n must be less than or equal to the
constant maxPrimeFactor defined below.
------------------------------------------------------------------------
Author:
Jens Joergen Nielsen For non-commercial use only.
Bakkehusene 54 A $100 fee must be paid if used
DK-2970 Hoersholm commercially. Please contact.
DENMARK
E-mail : jjn@get2net.dk All rights reserved. October 2000.
Homepage : http://home.get2net.dk/jjn
------------------------------------------------------------------------
Implementation notes:
The general idea is to factor the length of the DFT, n, into
factors that are efficiently handled by the routines.
A number of short DFT's are implemented with a minimum of
arithmetical operations and using (almost) straight line code
resulting in very fast execution when the factors of n belong
to this set. Especially radix-10 is optimized.
Prime factors, that are not in the set of short DFT's are handled
with direct evaluation of the DFP expression.
Please report any problems to the author.
Suggestions and improvements are welcomed.
------------------------------------------------------------------------
Benchmarks:
The Microsoft Visual C++ compiler was used with the following
compile options:
/nologo /Gs /G2 /W4 /AH /Ox /D "NDEBUG" /D "_DOS" /FR
and the FFTBENCH test executed on a 50MHz 486DX :
Length Time [s] Accuracy [dB]
128 0.0054 -314.8
256 0.0116 -309.8
512 0.0251 -290.8
1024 0.0567 -313.6
2048 0.1203 -306.4
4096 0.2600 -291.8
8192 0.5800 -305.1
100 0.0040 -278.5
200 0.0099 -280.3
500 0.0256 -278.5
1000 0.0540 -278.5
2000 0.1294 -280.6
5000 0.3300 -278.4
10000 0.7133 -278.5
------------------------------------------------------------------------
The following procedures are used :
factorize : factor the transformation length.
transTableSetup : setup table with sofar-, actual-, and remainRadix.
permute : permutation allows in-place calculations.
twiddleTransf : twiddle multiplications and DFT's for one stage.
initTrig : initialise sine/cosine table.
fft_4 : length 4 DFT, a la Nussbaumer.
fft_5 : length 5 DFT, a la Nussbaumer.
fft_10 : length 10 DFT using prime factor FFT.
fft_odd : length n DFT, n odd.
*************************************************************************/
#define maxPrimeFactor 37
#define maxPrimeFactorDiv2 ((maxPrimeFactor+1)/2)
#define maxFactorCount 20
static const float c3_1 = -1.5f; /* c3_1 = cos(2*pi/3)-1; */
static const float c3_2 = 0.866025388240814208984375f; /* c3_2 = sin(2*pi/3); */
// static const float u5 = 1.256637096405029296875f; /* u5 = 2*pi/5; */
static const float c5_1 = -1.25f; /* c5_1 = (cos(u5)+cos(2*u5))/2-1;*/
static const float c5_2 = 0.559017002582550048828125f; /* c5_2 = (cos(u5)-cos(2*u5))/2; */
static const float c5_3 = -0.951056540012359619140625f; /* c5_3 = -sin(u5); */
static const float c5_4 = -1.538841724395751953125f; /* c5_4 = -(sin(u5)+sin(2*u5)); */
static const float c5_5 = 0.3632712662220001220703125f; /* c5_5 = (sin(u5)-sin(2*u5)); */
static const float c8 = 0.707106769084930419921875f; /* c8 = 1/sqrt(2); */
static const float pi = 3.1415927410125732421875f;
#if 0 /* extra */
static int groupOffset,dataOffset,adr; //,blockOffset
static int groupNo,dataNo,blockNo,twNo;
static float omega, tw_re,tw_im;
static float twiddleRe[maxPrimeFactor], twiddleIm[maxPrimeFactor],
trigRe[maxPrimeFactor], trigIm[maxPrimeFactor],
zRe[maxPrimeFactor], zIm[maxPrimeFactor];
static float vRe[maxPrimeFactorDiv2], vIm[maxPrimeFactorDiv2];
static float wRe[maxPrimeFactorDiv2], wIm[maxPrimeFactorDiv2];
#endif
static void factorize(int n, int *nFact, int *fact)
{
int i,j,k;
int nRadix;
int radices[7];
int factors[maxFactorCount];
nRadix = 6;
radices[1]= 2;
radices[2]= 3;
radices[3]= 4;
radices[4]= 5;
radices[5]= 8;
radices[6]= 10;
radices[0]= 1; /* extra (assumed) */
factors[0]= 0; /* extra (assumed) */
fact[0]= 0; /* extra (assumed) */
fact[1]= 0; /* extra (assumed) */
if (n==1)
{
j=1;
factors[1]=1;
}
else j=0;
i=nRadix;
while ((n>1) && (i>0))
{
if ((n % radices[i]) == 0)
{
n=n / radices[i];
j=j+1;
factors[j]=radices[i];
}
else i=i-1;
}
if (factors[j] == 2) /*substitute factors 2*8 with 4*4 */
{
i = j-1;
while ((i>0) && (factors[i] != 8)) i--;
if (i>0)
{
factors[j] = 4;
factors[i] = 4;
}
}
if (n>1)
{
for (k=2; k<sqrt(n)+1; k++)
while ((n % k) == 0)
{
n=n / k;
j=j+1;
factors[j]=k;
}
if (n>1)
{
j=j+1;
factors[j]=n;
}
}
for (i=1; i<=j; i++)
{
fact[i] = factors[j-i+1];
}
*nFact=j;
} /* factorize */
/****************************************************************************
After N is factored the parameters that control the stages are generated.
For each stage we have:
sofar : the product of the radices so far.
actual : the radix handled in this stage.
remain : the product of the remaining radices.
****************************************************************************/
static void transTableSetup(int *sofar, int *actual, int *remain,
int *nFact,
int *nPoints)
{
int i;
factorize(*nPoints, nFact, actual);
if (actual[*nFact] > maxPrimeFactor)
{
#if 0 /* extra */
printf("\nPrime factor of FFT length too large : %6d", actual[*nFact]);
exit(1);
#endif
actual[*nFact] = maxPrimeFactor - 1; /* extra */
}
remain[0]=*nPoints;
sofar[1]=1;
remain[1]=*nPoints / actual[1];
for (i=2; i<=*nFact; i++)
{
sofar[i]=sofar[i-1]*actual[i-1];
remain[i]=remain[i-1] / actual[i];
}
} /* transTableSetup */
/****************************************************************************
The sequence y is the permuted input sequence x so that the following
transformations can be performed in-place, and the final result is the
normal order.
****************************************************************************/
static void permute(int nPoint, int nFact,
int *fact, int *remain,
float *xRe, float *xIm,
float *yRe, float *yIm)
{
int i,j,k;
int count[maxFactorCount];
for (i=1; i<=nFact; i++) count[i]=0;
k=0;
for (i=0; i<=nPoint-2; i++)
{
yRe[i] = xRe[k];
yIm[i] = xIm[k];
j=1;
k=k+remain[j];
count[1] = count[1]+1;
while (count[j] >= fact[j])
{
count[j]=0;
k=k-remain[j-1]+remain[j+1];
j=j+1;
count[j]=count[j]+1;
}
}
yRe[nPoint-1]=xRe[nPoint-1];
yIm[nPoint-1]=xIm[nPoint-1];
} /* permute */
/****************************************************************************
Twiddle factor multiplications and transformations are performed on a
group of data. The number of multiplications with 1 are reduced by skipping
the twiddle multiplication of the first stage and of the first group of the
following stages.
***************************************************************************/
static void initTrig(int radix, float *trigRe, float*trigIm)
{
int i;
float w,xre,xim;
w=2*pi/radix;
trigRe[0]=1; trigIm[0]=0;
xre=cos(w);
xim=-sin(w);
trigRe[1]=xre; trigIm[1]=xim;
for (i=2; i<radix; i++)
{
trigRe[i]=xre*trigRe[i-1] - xim*trigIm[i-1];
trigIm[i]=xim*trigRe[i-1] + xre*trigIm[i-1];
}
} /* initTrig */
static void fft_4(float *aRe, float *aIm)
{
float t1_re,t1_im, t2_re,t2_im;
float m2_re,m2_im, m3_re,m3_im;
t1_re=aRe[0] + aRe[2]; t1_im=aIm[0] + aIm[2];
t2_re=aRe[1] + aRe[3]; t2_im=aIm[1] + aIm[3];
m2_re=aRe[0] - aRe[2]; m2_im=aIm[0] - aIm[2];
m3_re=aIm[1] - aIm[3]; m3_im=aRe[3] - aRe[1];
aRe[0]=t1_re + t2_re; aIm[0]=t1_im + t2_im;
aRe[2]=t1_re - t2_re; aIm[2]=t1_im - t2_im;
aRe[1]=m2_re + m3_re; aIm[1]=m2_im + m3_im;
aRe[3]=m2_re - m3_re; aIm[3]=m2_im - m3_im;
} /* fft_4 */
static void fft_5(float *aRe, float *aIm)
{
float t1_re,t1_im, t2_re,t2_im, t3_re,t3_im;
float t4_re,t4_im, t5_re,t5_im;
float m2_re,m2_im, m3_re,m3_im, m4_re,m4_im;
float m1_re,m1_im, m5_re,m5_im;
float s1_re,s1_im, s2_re,s2_im, s3_re,s3_im;
float s4_re,s4_im, s5_re,s5_im;
t1_re=aRe[1] + aRe[4]; t1_im=aIm[1] + aIm[4];
t2_re=aRe[2] + aRe[3]; t2_im=aIm[2] + aIm[3];
t3_re=aRe[1] - aRe[4]; t3_im=aIm[1] - aIm[4];
t4_re=aRe[3] - aRe[2]; t4_im=aIm[3] - aIm[2];
t5_re=t1_re + t2_re; t5_im=t1_im + t2_im;
aRe[0]=aRe[0] + t5_re; aIm[0]=aIm[0] + t5_im;
m1_re=c5_1*t5_re; m1_im=c5_1*t5_im;
m2_re=c5_2*(t1_re - t2_re); m2_im=c5_2*(t1_im - t2_im);
m3_re=-c5_3*(t3_im + t4_im); m3_im=c5_3*(t3_re + t4_re);
m4_re=-c5_4*t4_im; m4_im=c5_4*t4_re;
m5_re=-c5_5*t3_im; m5_im=c5_5*t3_re;
s3_re=m3_re - m4_re; s3_im=m3_im - m4_im;
s5_re=m3_re + m5_re; s5_im=m3_im + m5_im;
s1_re=aRe[0] + m1_re; s1_im=aIm[0] + m1_im;
s2_re=s1_re + m2_re; s2_im=s1_im + m2_im;
s4_re=s1_re - m2_re; s4_im=s1_im - m2_im;
aRe[1]=s2_re + s3_re; aIm[1]=s2_im + s3_im;
aRe[2]=s4_re + s5_re; aIm[2]=s4_im + s5_im;
aRe[3]=s4_re - s5_re; aIm[3]=s4_im - s5_im;
aRe[4]=s2_re - s3_re; aIm[4]=s2_im - s3_im;
} /* fft_5 */
static void fft_8(float *zRe, float *zIm)
{
float aRe[4], aIm[4], bRe[4], bIm[4], gem;
aRe[0] = zRe[0]; bRe[0] = zRe[1];
aRe[1] = zRe[2]; bRe[1] = zRe[3];
aRe[2] = zRe[4]; bRe[2] = zRe[5];
aRe[3] = zRe[6]; bRe[3] = zRe[7];
aIm[0] = zIm[0]; bIm[0] = zIm[1];
aIm[1] = zIm[2]; bIm[1] = zIm[3];
aIm[2] = zIm[4]; bIm[2] = zIm[5];
aIm[3] = zIm[6]; bIm[3] = zIm[7];
fft_4(aRe, aIm); fft_4(bRe, bIm);
gem = c8*(bRe[1] + bIm[1]);
bIm[1] = c8*(bIm[1] - bRe[1]);
bRe[1] = gem;
gem = bIm[2];
bIm[2] =-bRe[2];
bRe[2] = gem;
gem = c8*(bIm[3] - bRe[3]);
bIm[3] =-c8*(bRe[3] + bIm[3]);
bRe[3] = gem;
zRe[0] = aRe[0] + bRe[0]; zRe[4] = aRe[0] - bRe[0];
zRe[1] = aRe[1] + bRe[1]; zRe[5] = aRe[1] - bRe[1];
zRe[2] = aRe[2] + bRe[2]; zRe[6] = aRe[2] - bRe[2];
zRe[3] = aRe[3] + bRe[3]; zRe[7] = aRe[3] - bRe[3];
zIm[0] = aIm[0] + bIm[0]; zIm[4] = aIm[0] - bIm[0];
zIm[1] = aIm[1] + bIm[1]; zIm[5] = aIm[1] - bIm[1];
zIm[2] = aIm[2] + bIm[2]; zIm[6] = aIm[2] - bIm[2];
zIm[3] = aIm[3] + bIm[3]; zIm[7] = aIm[3] - bIm[3];
} /* fft_8 */
static void fft_10(float *zRe, float *zIm)
{
float aRe[5], aIm[5], bRe[5], bIm[5];
aRe[0] = zRe[0]; bRe[0] = zRe[5];
aRe[1] = zRe[2]; bRe[1] = zRe[7];
aRe[2] = zRe[4]; bRe[2] = zRe[9];
aRe[3] = zRe[6]; bRe[3] = zRe[1];
aRe[4] = zRe[8]; bRe[4] = zRe[3];
aIm[0] = zIm[0]; bIm[0] = zIm[5];
aIm[1] = zIm[2]; bIm[1] = zIm[7];
aIm[2] = zIm[4]; bIm[2] = zIm[9];
aIm[3] = zIm[6]; bIm[3] = zIm[1];
aIm[4] = zIm[8]; bIm[4] = zIm[3];
fft_5(aRe, aIm); fft_5(bRe, bIm);
zRe[0] = aRe[0] + bRe[0]; zRe[5] = aRe[0] - bRe[0];
zRe[6] = aRe[1] + bRe[1]; zRe[1] = aRe[1] - bRe[1];
zRe[2] = aRe[2] + bRe[2]; zRe[7] = aRe[2] - bRe[2];
zRe[8] = aRe[3] + bRe[3]; zRe[3] = aRe[3] - bRe[3];
zRe[4] = aRe[4] + bRe[4]; zRe[9] = aRe[4] - bRe[4];
zIm[0] = aIm[0] + bIm[0]; zIm[5] = aIm[0] - bIm[0];
zIm[6] = aIm[1] + bIm[1]; zIm[1] = aIm[1] - bIm[1];
zIm[2] = aIm[2] + bIm[2]; zIm[7] = aIm[2] - bIm[2];
zIm[8] = aIm[3] + bIm[3]; zIm[3] = aIm[3] - bIm[3];
zIm[4] = aIm[4] + bIm[4]; zIm[9] = aIm[4] - bIm[4];
} /* fft_10 */
static void fft_odd(int radix, float *trigRe, float *trigIm, float *zRe, float* zIm)
{
float rere, reim, imre, imim;
int i,j,k,n,max;
float vRe[maxPrimeFactorDiv2] = {0}, vIm[maxPrimeFactorDiv2] = {0}; /* extra */
float wRe[maxPrimeFactorDiv2] = {0}, wIm[maxPrimeFactorDiv2] = {0}; /* extra */
n = radix;
max = (n + 1)/2;
for (j=1; j < max; j++)
{
vRe[j] = zRe[j] + zRe[n-j];
vIm[j] = zIm[j] - zIm[n-j];
wRe[j] = zRe[j] - zRe[n-j];
wIm[j] = zIm[j] + zIm[n-j];
}
for (j=1; j < max; j++)
{
zRe[j]=zRe[0];
zIm[j]=zIm[0];
zRe[n-j]=zRe[0];
zIm[n-j]=zIm[0];
k=j;
for (i=1; i < max; i++)
{
rere = trigRe[k] * vRe[i];
imim = trigIm[k] * vIm[i];
reim = trigRe[k] * wIm[i];
imre = trigIm[k] * wRe[i];
zRe[n-j] += rere + imim;
zIm[n-j] += reim - imre;
zRe[j] += rere - imim;
zIm[j] += reim + imre;
k = k + j;
if (k >= n) k = k - n;
}
}
for (j=1; j < max; j++)
{
zRe[0]=zRe[0] + vRe[j];
zIm[0]=zIm[0] + wIm[j];
}
} /* fft_odd */
static void twiddleTransf(int sofarRadix, int radix, int remainRadix,
float *yRe, float *yIm)
{ /* twiddleTransf */
float cosw, sinw, gem;
float t1_re,t1_im, t2_re,t2_im, t3_re,t3_im;
float t4_re,t4_im, t5_re,t5_im;
float m1_re,m1_im, m2_re,m2_im, m3_re,m3_im;
float m4_re,m4_im, m5_re,m5_im;
float s1_re,s1_im, s2_re,s2_im, s3_re,s3_im;
float s4_re,s4_im, s5_re,s5_im;
int groupOffset,dataOffset,adr; //,blockOffset /* extra */
int groupNo,dataNo,blockNo,twNo; /* extra */
float omega, tw_re,tw_im; /* extra */
float twiddleRe[maxPrimeFactor] = {0}, twiddleIm[maxPrimeFactor] = {0}, /* extra */
trigRe[maxPrimeFactor] = {0}, trigIm[maxPrimeFactor] = {0}, /* extra */
zRe[maxPrimeFactor] = {0}, zIm[maxPrimeFactor] = {0}; /* extra */
initTrig(radix, trigRe, trigIm);
omega = 2*pi/(double)(sofarRadix*radix);
cosw = cos(omega);
sinw = -sin(omega);
tw_re = 1.0;
tw_im = 0;
dataOffset=0;
groupOffset=dataOffset;
adr=groupOffset;
for (dataNo=0; dataNo<sofarRadix; dataNo++)
{
if (sofarRadix>1)
{
twiddleRe[0] = 1.0;
twiddleIm[0] = 0.0;
twiddleRe[1] = tw_re;
twiddleIm[1] = tw_im;
for (twNo=2; twNo<radix; twNo++)
{
twiddleRe[twNo]=tw_re*twiddleRe[twNo-1]
- tw_im*twiddleIm[twNo-1];
twiddleIm[twNo]=tw_im*twiddleRe[twNo-1]
+ tw_re*twiddleIm[twNo-1];
}
gem = cosw*tw_re - sinw*tw_im;
tw_im = sinw*tw_re + cosw*tw_im;
tw_re = gem;
}
for (groupNo=0; groupNo<remainRadix; groupNo++)
{
if ((sofarRadix>1) && (dataNo > 0))
{
zRe[0]=yRe[adr];
zIm[0]=yIm[adr];
blockNo=1;
do {
adr = adr + sofarRadix;
zRe[blockNo]= twiddleRe[blockNo] * yRe[adr]
- twiddleIm[blockNo] * yIm[adr];
zIm[blockNo]= twiddleRe[blockNo] * yIm[adr]
+ twiddleIm[blockNo] * yRe[adr];
blockNo++;
} while (blockNo < radix);
}
else {
for (blockNo=0; blockNo<radix; blockNo++)
{
zRe[blockNo]=yRe[adr];
zIm[blockNo]=yIm[adr];
adr=adr+sofarRadix;
}
}
switch(radix) {
case 2 : gem=zRe[0] + zRe[1];
zRe[1]=zRe[0] - zRe[1]; zRe[0]=gem;
gem=zIm[0] + zIm[1];
zIm[1]=zIm[0] - zIm[1]; zIm[0]=gem;
break;
case 3 : t1_re=zRe[1] + zRe[2]; t1_im=zIm[1] + zIm[2];
zRe[0]=zRe[0] + t1_re; zIm[0]=zIm[0] + t1_im;
m1_re=c3_1*t1_re; m1_im=c3_1*t1_im;
m2_re=c3_2*(zIm[1] - zIm[2]);
m2_im=c3_2*(zRe[2] - zRe[1]);
s1_re=zRe[0] + m1_re; s1_im=zIm[0] + m1_im;
zRe[1]=s1_re + m2_re; zIm[1]=s1_im + m2_im;
zRe[2]=s1_re - m2_re; zIm[2]=s1_im - m2_im;
break;
case 4 : t1_re=zRe[0] + zRe[2]; t1_im=zIm[0] + zIm[2];
t2_re=zRe[1] + zRe[3]; t2_im=zIm[1] + zIm[3];
m2_re=zRe[0] - zRe[2]; m2_im=zIm[0] - zIm[2];
m3_re=zIm[1] - zIm[3]; m3_im=zRe[3] - zRe[1];
zRe[0]=t1_re + t2_re; zIm[0]=t1_im + t2_im;
zRe[2]=t1_re - t2_re; zIm[2]=t1_im - t2_im;
zRe[1]=m2_re + m3_re; zIm[1]=m2_im + m3_im;
zRe[3]=m2_re - m3_re; zIm[3]=m2_im - m3_im;
break;
case 5 : t1_re=zRe[1] + zRe[4]; t1_im=zIm[1] + zIm[4];
t2_re=zRe[2] + zRe[3]; t2_im=zIm[2] + zIm[3];
t3_re=zRe[1] - zRe[4]; t3_im=zIm[1] - zIm[4];
t4_re=zRe[3] - zRe[2]; t4_im=zIm[3] - zIm[2];
t5_re=t1_re + t2_re; t5_im=t1_im + t2_im;
zRe[0]=zRe[0] + t5_re; zIm[0]=zIm[0] + t5_im;
m1_re=c5_1*t5_re; m1_im=c5_1*t5_im;
m2_re=c5_2*(t1_re - t2_re);
m2_im=c5_2*(t1_im - t2_im);
m3_re=-c5_3*(t3_im + t4_im);
m3_im=c5_3*(t3_re + t4_re);
m4_re=-c5_4*t4_im; m4_im=c5_4*t4_re;
m5_re=-c5_5*t3_im; m5_im=c5_5*t3_re;
s3_re=m3_re - m4_re; s3_im=m3_im - m4_im;
s5_re=m3_re + m5_re; s5_im=m3_im + m5_im;
s1_re=zRe[0] + m1_re; s1_im=zIm[0] + m1_im;
s2_re=s1_re + m2_re; s2_im=s1_im + m2_im;
s4_re=s1_re - m2_re; s4_im=s1_im - m2_im;
zRe[1]=s2_re + s3_re; zIm[1]=s2_im + s3_im;
zRe[2]=s4_re + s5_re; zIm[2]=s4_im + s5_im;
zRe[3]=s4_re - s5_re; zIm[3]=s4_im - s5_im;
zRe[4]=s2_re - s3_re; zIm[4]=s2_im - s3_im;
break;
case 8 : fft_8(zRe, zIm); break;
case 10 : fft_10(zRe, zIm); break;
default : fft_odd(radix, trigRe, trigIm, zRe, zIm); break;
}
adr=groupOffset;
for (blockNo=0; blockNo<radix; blockNo++)
{
yRe[adr]=zRe[blockNo]; yIm[adr]=zIm[blockNo];
adr=adr+sofarRadix;
}
groupOffset=groupOffset+sofarRadix*radix;
adr=groupOffset;
}
dataOffset=dataOffset+1;
groupOffset=dataOffset;
adr=groupOffset;
}
} /* twiddleTransf */
/*static*/ void fft(int n, float *xRe, float *xIm,
float *yRe, float *yIm)
{
int sofarRadix[maxFactorCount],
actualRadix[maxFactorCount],
remainRadix[maxFactorCount];
int nFactor;
int count;
#if 0
pi = 4*atan(1);
#endif
transTableSetup(sofarRadix, actualRadix, remainRadix, &nFactor, &n);
permute(n, nFactor, actualRadix, remainRadix, xRe, xIm, yRe, yIm);
for (count=1; count<=nFactor; count++)
twiddleTransf(sofarRadix[count], actualRadix[count], remainRadix[count],
yRe, yIm);
} /* fft */

View File

@ -0,0 +1,42 @@
#include "coding.h"
/* Decodes SunPlus' ADPCM codec used on the Tiger Game.com.
* Reverse engineered from the Game.com's BIOS. */
static uint16_t slopeTable[64] =
{
0x0000, 0x0100, 0x0200, 0x0400, 0x0610, 0x0810, 0x0C18, 0x1020,
0x0100, 0x0300, 0x0508, 0x0908, 0x0D18, 0x1118, 0x1920, 0x2128,
0x0208, 0x0508, 0x0810, 0x0E10, 0x1420, 0x1A20, 0x2628, 0x3230,
0x0310, 0x0710, 0x0B18, 0x1318, 0x1B28, 0x2328, 0x2930, 0x4338,
0x0418, 0x0918, 0x0E20, 0x1820, 0x2230, 0x2C30, 0x4038, 0x5438,
0x0520, 0x0B20, 0x1128, 0x1D28, 0x2938, 0x3538, 0x4D38, 0x6F38,
0x0628, 0x0D28, 0x1430, 0x2230, 0x3038, 0x3E38, 0x5A38, 0x7638,
0x0730, 0x0F30, 0x1738, 0x2738, 0x3738, 0x4738, 0x6738, 0x7D38
};
void decode_tgc(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int32_t first_sample, int32_t samples_to_do)
{
for (int i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count++)
{
uint8_t samp = ((uint8_t)read_8bit(i/2, stream->streamfile) >>
(i & 1 ? 4 : 0)) & 0xf;
uint8_t slopeIndex = stream->adpcm_scale | (samp >> 1);
stream->adpcm_step_index = slopeTable[slopeIndex] >> 8;
stream->adpcm_scale = slopeTable[slopeIndex] & 0xff;
stream->adpcm_history1_16 += (samp & 1) ?
-stream->adpcm_step_index:
stream->adpcm_step_index;
if (stream->adpcm_history1_16 < 0)
stream->adpcm_history1_16 = 0;
if (stream->adpcm_history1_16 > 0xff)
stream->adpcm_history1_16 = 0xff;
outbuf[sample_count] = stream->adpcm_history1_16 * 0x100 - 0x8000;
}
}

View File

@ -1,209 +1,201 @@
#include "../util.h"
#include "coding.h"
/* fixed point amount to scale the current step size */
static const unsigned int scale_step_aica[16] = {
230, 230, 230, 230, 307, 409, 512, 614,
230, 230, 230, 230, 307, 409, 512, 614
};
static const int scale_step_adpcmb[16] = {
57, 57, 57, 57, 77, 102, 128, 153,
57, 57, 57, 57, 77, 102, 128, 153,
};
/* look-up for 'mul' IMA's sign*((code&7) * 2 + 1) for every code */
static const int scale_delta[16] = {
1, 3, 5, 7, 9, 11, 13, 15,
-1, -3, -5, -7, -9,-11,-13,-15
};
/* Yamaha ADPCM-B (aka DELTA-T) expand used in YM2608/YM2610/etc (cross referenced with various sources and .so) */
static void yamaha_adpcmb_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_size, int16_t *out_sample) {
int code, delta, sample;
code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf;
delta = ((((code & 0x7) * 2) + 1) * (*step_size)) >> 3; /* like 'mul' IMA */
if (code & 8)
delta = -delta;
sample = *hist1 + delta;
sample = clamp16(sample); /* this may not be needed (not done in Aska) but no byte changes */
*step_size = ((*step_size) * scale_step_adpcmb[code]) >> 6;
if (*step_size < 0x7f) *step_size = 0x7f;
else if (*step_size > 0x6000) *step_size = 0x6000;
*out_sample = sample;
*hist1 = sample;
}
/* Yamaha AICA expand, slightly filtered vs "ACM" Yamaha ADPCM, same as Creative ADPCM
* (some info from https://github.com/vgmrips/vgmplay, https://wiki.multimedia.cx/index.php/Creative_ADPCM) */
static void yamaha_aica_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_size, int16_t *out_sample) {
int code, delta, sample;
*hist1 = *hist1 * 254 / 256; /* hist filter is vital to get correct waveform but not done in many emus */
code = ((read_8bit(byte_offset,stream->streamfile) >> nibble_shift))&0xf;
delta = (*step_size * scale_delta[code]) / 8; /* 'mul' IMA with table (not sure if part of encoder) */
sample = *hist1 + delta;
sample = clamp16(sample); /* apparently done by official encoder */
*step_size = ((*step_size) * scale_step_aica[code]) >> 8;
if (*step_size < 0x7f) *step_size = 0x7f;
else if (*step_size > 0x6000) *step_size = 0x6000;
*out_sample = sample;
*hist1 = sample;
}
/* info about Yamaha ADPCM as created by official yadpcm.acm (in 'Yamaha-ADPCM-ACM-Driver-100-j')
* - possibly RIFF codec 0x20
* - simply called "Yamaha ADPCM Codec" (even though not quite like Yamaha ADPCM-B)
* - block_align = (sample_rate / 0x3C + 0x04) * channels (ex. 0x2E6 for 22050 stereo, probably given in RIFF)
* - low nibble first, stereo or mono modes (no interleave)
* - expand (old IMA 'shift+add' style, not 'mul' style):
* delta = step_size >> 3;
* if (code & 1) delta += step_size >> 2;
* if (code & 2) delta += step_size >> 1;
* if (code & 4) delta += step_size;
* if (code & 8) delta = -delta;
* sample = hist + clamp16(delta);
* though compiled more like:
* sample = hist + (1-2*(code & 8) * (step_size/8 + step_size/2 * (code&2) + step_size/4 * (code&1) + step_size * (code&4))
* - step_size update:
* step_size = clamp_range(step_size * scale_step_aica[code] >> 8, 0x7F, 0x6000)
*/
/* Yamaha AICA ADPCM (also used in YMZ280B with high nibble first) */
void decode_aica(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo) {
int i, sample_count = 0;
int16_t out_sample;
int32_t hist1 = stream->adpcm_history1_16;
int step_size = stream->adpcm_step_index;
/* no header (external setup), pre-clamp for wrong values */
if (step_size < 0x7f) step_size = 0x7f;
if (step_size > 0x6000) step_size = 0x6000;
for (i = first_sample; i < first_sample + samples_to_do; i++) {
off_t byte_offset = is_stereo ?
stream->offset + i : /* stereo: one nibble per channel */
stream->offset + i/2; /* mono: consecutive nibbles */
int nibble_shift = is_stereo ?
(!(channel&1) ? 0:4) : /* even = low/L, odd = high/R */
(!(i&1) ? 0:4); /* low nibble first */
yamaha_aica_expand_nibble(stream, byte_offset, nibble_shift, &hist1, &step_size, &out_sample);
outbuf[sample_count] = out_sample;
sample_count += channelspacing;
}
stream->adpcm_history1_16 = hist1;
stream->adpcm_step_index = step_size;
}
/* tri-Ace Aska ADPCM, Yamaha ADPCM-B with headered frames (reversed from Android SO's .so)
* implements table with if-else/switchs too but that's too goofy */
void decode_aska(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
int i, sample_count = 0, num_frame;
int16_t out_sample;
int32_t hist1 = stream->adpcm_history1_32;
int step_size = stream->adpcm_step_index;
/* external interleave */
int block_samples = (0x40 - 0x04*channelspacing) * 2 / channelspacing;
num_frame = first_sample / block_samples;
first_sample = first_sample % block_samples;
/* header (hist+step) */
if (first_sample == 0) {
off_t header_offset = stream->offset + 0x40*num_frame + 0x04*channel;
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
step_size = read_16bitLE(header_offset+0x02,stream->streamfile);
/* in most files 1st frame has step 0 but it seems ok and accounted for */
//if (step_size < 0x7f) step_size = 0x7f;
//else if (step_size > 0x6000) step_size = 0x6000;
}
/* decode nibbles (layout: varies) */
for (i = first_sample; i < first_sample + samples_to_do; i++) {
off_t byte_offset = (channelspacing == 2) ?
(stream->offset + 0x40*num_frame + 0x04*channelspacing) + i : /* stereo: one nibble per channel */
(stream->offset + 0x40*num_frame + 0x04*channelspacing) + i/2; /* mono: consecutive nibbles */
int nibble_shift = (channelspacing == 2) ?
(!(channel&1) ? 0:4) :
(!(i&1) ? 0:4); /* even = low, odd = high */
yamaha_adpcmb_expand_nibble(stream, byte_offset, nibble_shift, &hist1, &step_size, &out_sample);
outbuf[sample_count] = out_sample;
sample_count += channelspacing;
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_size;
}
/* Yamaha ADPCM with unknown expand variation (noisy), step size is double of normal Yamaha? */
void decode_nxap(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i, sample_count = 0, num_frame;
int32_t hist1 = stream->adpcm_history1_32;
int step_size = stream->adpcm_step_index;
/* external interleave */
int block_samples = (0x40 - 0x4) * 2;
num_frame = first_sample / block_samples;
first_sample = first_sample % block_samples;
/* header (hist+step) */
if (first_sample == 0) {
off_t header_offset = stream->offset + 0x40*num_frame;
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
step_size = read_16bitLE(header_offset+0x02,stream->streamfile);
if (step_size < 0x7f) step_size = 0x7f;
else if (step_size > 0x6000) step_size = 0x6000;
}
/* decode nibbles (layout: all nibbles from one channel) */
for (i = first_sample; i < first_sample + samples_to_do; i++) {
int code, delta, sample;
off_t byte_offset = (stream->offset + 0x40*num_frame + 0x04) + i/2;
int nibble_shift = (i&1?4:0); /* low nibble first? */
code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
delta = (step_size * scale_delta[code]) / 8; //todo wrong
sample = hist1 + delta;
outbuf[sample_count] = clamp16(sample);
hist1 = outbuf[sample_count];
step_size = (step_size * scale_step_aica[code]) / 260.0; //todo wrong
if (step_size < 0x7f) step_size = 0x7f;
else if (step_size > 0x6000) step_size = 0x6000;
sample_count += channelspacing;
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_size;
}
size_t yamaha_bytes_to_samples(size_t bytes, int channels) {
if (channels <= 0) return 0;
/* 2 samples per byte (2 nibbles) in stereo or mono config */
return bytes * 2 / channels;
}
size_t aska_bytes_to_samples(size_t bytes, int channels) {
int block_align = 0x40;
if (channels <= 0) return 0;
return (bytes / block_align) * (block_align - 0x04*channels) * 2 / channels
+ ((bytes % block_align) ? ((bytes % block_align) - 0x04*channels) * 2 / channels : 0);
}
#include "../util.h"
#include "coding.h"
/* fixed point amount to scale the current step size */
static const unsigned int scale_step_aica[16] = {
230, 230, 230, 230, 307, 409, 512, 614,
230, 230, 230, 230, 307, 409, 512, 614
};
static const int scale_step_adpcmb[16] = {
57, 57, 57, 57, 77, 102, 128, 153,
57, 57, 57, 57, 77, 102, 128, 153,
};
/* look-up for 'mul' IMA's sign*((code&7) * 2 + 1) for every code */
static const int scale_delta[16] = {
1, 3, 5, 7, 9, 11, 13, 15,
-1, -3, -5, -7, -9,-11,-13,-15
};
/* Yamaha ADPCM-B (aka DELTA-T) expand used in YM2608/YM2610/etc (cross referenced with various sources and .so) */
static void yamaha_adpcmb_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_size, int16_t *out_sample) {
int code, delta, sample;
code = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift) & 0xf;
delta = ((((code & 0x7) * 2) + 1) * (*step_size)) >> 3; /* like 'mul' IMA */
if (code & 8)
delta = -delta;
sample = *hist1 + delta;
sample = clamp16(sample); /* not needed in Aska but seems others do */
*step_size = ((*step_size) * scale_step_adpcmb[code]) >> 6;
if (*step_size < 0x7f) *step_size = 0x7f;
else if (*step_size > 0x6000) *step_size = 0x6000;
*out_sample = sample;
*hist1 = sample;
}
/* Yamaha AICA expand, slightly filtered vs "ACM" Yamaha ADPCM, same as Creative ADPCM
* (some info from https://github.com/vgmrips/vgmplay, https://wiki.multimedia.cx/index.php/Creative_ADPCM) */
static void yamaha_aica_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t* hist1, int32_t* step_size, int16_t *out_sample) {
int code, delta, sample;
*hist1 = *hist1 * 254 / 256; /* hist filter is vital to get correct waveform but not done in many emus */
code = ((read_8bit(byte_offset,stream->streamfile) >> nibble_shift))&0xf;
delta = (*step_size * scale_delta[code]) / 8; /* 'mul' IMA with table (not sure if part of encoder) */
sample = *hist1 + delta;
sample = clamp16(sample); /* apparently done by official encoder */
*step_size = ((*step_size) * scale_step_aica[code]) >> 8;
if (*step_size < 0x7f) *step_size = 0x7f;
else if (*step_size > 0x6000) *step_size = 0x6000;
*out_sample = sample;
*hist1 = sample;
}
/* info about Yamaha ADPCM as created by official yadpcm.acm (in 'Yamaha-ADPCM-ACM-Driver-100-j')
* - possibly RIFF codec 0x20
* - simply called "Yamaha ADPCM Codec" (even though not quite like Yamaha ADPCM-B)
* - block_align = (sample_rate / 0x3C + 0x04) * channels (ex. 0x2E6 for 22050 stereo, probably given in RIFF)
* - low nibble first, stereo or mono modes (no interleave)
* - expand (old IMA 'shift+add' style, not 'mul' style):
* delta = step_size >> 3;
* if (code & 1) delta += step_size >> 2;
* if (code & 2) delta += step_size >> 1;
* if (code & 4) delta += step_size;
* if (code & 8) delta = -delta;
* sample = hist + clamp16(delta);
* though compiled more like:
* sample = hist + (1-2*(code & 8) * (step_size/8 + step_size/2 * (code&2) + step_size/4 * (code&1) + step_size * (code&4))
* - step_size update:
* step_size = clamp_range(step_size * scale_step_aica[code] >> 8, 0x7F, 0x6000)
*/
/* Yamaha AICA ADPCM (also used in YMZ280B with high nibble first) */
void decode_aica(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo) {
int i, sample_count = 0;
int16_t out_sample;
int32_t hist1 = stream->adpcm_history1_16;
int step_size = stream->adpcm_step_index;
/* no header (external setup), pre-clamp for wrong values */
if (step_size < 0x7f) step_size = 0x7f;
if (step_size > 0x6000) step_size = 0x6000;
for (i = first_sample; i < first_sample + samples_to_do; i++) {
off_t byte_offset = is_stereo ?
stream->offset + i : /* stereo: one nibble per channel */
stream->offset + i/2; /* mono: consecutive nibbles */
int nibble_shift = is_stereo ?
(!(channel&1) ? 0:4) : /* even = low/L, odd = high/R */
(!(i&1) ? 0:4); /* low nibble first */
yamaha_aica_expand_nibble(stream, byte_offset, nibble_shift, &hist1, &step_size, &out_sample);
outbuf[sample_count] = out_sample;
sample_count += channelspacing;
}
stream->adpcm_history1_16 = hist1;
stream->adpcm_step_index = step_size;
}
/* tri-Ace Aska ADPCM, Yamaha ADPCM-B with headered frames (reversed from Android SO's .so)
* implements table with if-else/switchs too but that's too goofy */
void decode_aska(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
int i, sample_count = 0, num_frame;
int16_t out_sample;
int32_t hist1 = stream->adpcm_history1_32;
int step_size = stream->adpcm_step_index;
/* external interleave */
int block_samples = (0x40 - 0x04*channelspacing) * 2 / channelspacing;
num_frame = first_sample / block_samples;
first_sample = first_sample % block_samples;
/* header (hist+step) */
if (first_sample == 0) {
off_t header_offset = stream->offset + 0x40*num_frame + 0x04*channel;
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
step_size = read_16bitLE(header_offset+0x02,stream->streamfile);
/* in most files 1st frame has step 0 but it seems ok and accounted for */
//if (step_size < 0x7f) step_size = 0x7f;
//else if (step_size > 0x6000) step_size = 0x6000;
}
/* decode nibbles (layout: varies) */
for (i = first_sample; i < first_sample + samples_to_do; i++) {
off_t byte_offset = (channelspacing == 2) ?
(stream->offset + 0x40*num_frame + 0x04*channelspacing) + i : /* stereo: one nibble per channel */
(stream->offset + 0x40*num_frame + 0x04*channelspacing) + i/2; /* mono: consecutive nibbles */
int nibble_shift = (channelspacing == 2) ?
(!(channel&1) ? 0:4) :
(!(i&1) ? 0:4); /* even = low, odd = high */
yamaha_adpcmb_expand_nibble(stream, byte_offset, nibble_shift, &hist1, &step_size, &out_sample);
outbuf[sample_count] = out_sample;
sample_count += channelspacing;
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_size;
}
/* NXAP ADPCM, Yamaha ADPCM-B with weird headered frames */
void decode_nxap(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i, sample_count = 0, num_frame;
int32_t hist1 = stream->adpcm_history1_32;
int step_size = stream->adpcm_step_index;
int16_t out_sample;
/* external interleave, mono */
int block_samples = (0x40 - 0x4) * 2;
num_frame = first_sample / block_samples;
first_sample = first_sample % block_samples;
/* header (hist+step) */
if (first_sample == 0) {
off_t header_offset = stream->offset + 0x40*num_frame;
hist1 = read_s16le(header_offset+0x00,stream->streamfile);
step_size = read_u16le(header_offset+0x02,stream->streamfile) >> 1; /* remove lower bit, also note unsignedness */
if (step_size < 0x7f) step_size = 0x7f;
else if (step_size > 0x6000) step_size = 0x6000;
/* step's lower bit is hist1 sign (useless), and code doesn't seem to do anything useful with it? */
}
/* decode nibbles (layout: all nibbles from one channel) */
for (i = first_sample; i < first_sample + samples_to_do; i++) {
off_t byte_offset = (stream->offset + 0x40*num_frame + 0x04) + i/2;
int nibble_shift = (i&1?0:4);
yamaha_adpcmb_expand_nibble(stream, byte_offset, nibble_shift, &hist1, &step_size, &out_sample);
outbuf[sample_count] = out_sample;
sample_count += channelspacing;
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_step_index = step_size;
}
size_t yamaha_bytes_to_samples(size_t bytes, int channels) {
if (channels <= 0) return 0;
/* 2 samples per byte (2 nibbles) in stereo or mono config */
return bytes * 2 / channels;
}
size_t aska_bytes_to_samples(size_t bytes, int channels) {
int block_align = 0x40;
if (channels <= 0) return 0;
return (bytes / block_align) * (block_align - 0x04*channels) * 2 / channels
+ ((bytes % block_align) ? ((bytes % block_align) - 0x04*channels) * 2 / channels : 0);
}

View File

@ -25,6 +25,7 @@ static const char* extension_list[] = {
"208",
"2dx9",
"2pfs",
"4", // for Game.com audio
"8", //txth/reserved [Gungage (PS1)]
"800",
"9tav",
@ -164,6 +165,7 @@ static const char* extension_list[] = {
"ezw",
"fag",
"fda",
"ffw",
"filp",
//"flac", //common
@ -171,6 +173,7 @@ static const char* extension_list[] = {
"fsb",
"fsv",
"fwav",
"fwse",
"g1l",
"gbts",
@ -268,6 +271,7 @@ static const char* extension_list[] = {
"lpcm",
"lpk",
"lps",
"lrmb",
"lse",
"lsf",
"lstm", //fake extension for .stm
@ -389,6 +393,7 @@ static const char* extension_list[] = {
"rxx", //txth/reserved [Full Auto (X360)]
"s14",
"s3v", //txth/reserved [Sound Voltex 5 (AC)]
"sab",
"sad",
"sap",
@ -418,6 +423,7 @@ static const char* extension_list[] = {
"sdf",
"sdt",
"seb",
"sed",
"seg",
"sf0",
"sfl",
@ -530,6 +536,8 @@ static const char* extension_list[] = {
"wavm",
"wavx", //txth/reserved [LEGO Star Wars (Xbox)]
"wb",
"wb2",
"wbd",
"wd",
"wem",
"wii",
@ -691,6 +699,7 @@ static const coding_info coding_info_list[] = {
{coding_ALP_IMA, "High Voltage ALP 4-bit IMA ADPCM"},
{coding_FFTA2_IMA, "Final Fantasy Tactics A2 4-bit IMA ADPCM"},
{coding_BLITZ_IMA, "Blitz Games 4-bit IMA ADPCM"},
{coding_MTF_IMA, "MT Framework 4-bit IMA ADPCM"},
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
{coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
@ -717,6 +726,7 @@ static const coding_info coding_info_list[] = {
{coding_AICA_int, "Yamaha AICA 4-bit ADPCM (mono/interleave)"},
{coding_ASKA, "tri-Ace Aska 4-bit ADPCM"},
{coding_NXAP, "Nex NXAP 4-bit ADPCM"},
{coding_TGC, "Tiger Game.com 4-bit ADPCM"},
{coding_NDS_PROCYON, "Procyon Studio Digital Sound Elements NDS 4-bit APDCM"},
{coding_L5_555, "Level-5 0x555 4-bit ADPCM"},
{coding_LSF, "lsf 4-bit ADPCM"},
@ -745,6 +755,7 @@ static const coding_info coding_info_list[] = {
{coding_EA_MT, "Electronic Arts MicroTalk"},
{coding_RELIC, "Relic Codec"},
{coding_CRI_HCA, "CRI HCA"},
#ifdef VGM_USE_VORBIS
@ -1120,7 +1131,7 @@ static const meta_info meta_info_list[] = {
{meta_FFMPEG, "FFmpeg supported file format"},
{meta_X360_CXS, "tri-Crescendo CXS header"},
{meta_AKB, "Square-Enix AKB header"},
{meta_X360_PASX, "Namco PASX header"},
{meta_X360_PASX, "Premium Agency PASX header"},
{meta_XMA_RIFF, "Microsoft XMA RIFF header"},
{meta_X360_AST, "Capcom AST (X360) header"},
{meta_WWISE_RIFF, "Audiokinetic Wwise RIFF header"},
@ -1224,7 +1235,7 @@ static const meta_info meta_info_list[] = {
{meta_XPCM, "Circus XPCM header"},
{meta_MSF_TAMASOFT, "Tama-Soft MSF header"},
{meta_XPS_DAT, "From Software .XPS+DAT header"},
{meta_ZSND, "Vicarious Visions ZSND header"},
{meta_ZSND, "Z-Axis ZSND header"},
{meta_DSP_ADPY, "AQUASTYLE ADPY header"},
{meta_DSP_ADPX, "AQUASTYLE ADPX header"},
{meta_OGG_OPUS, "Ogg Opus header"},
@ -1252,6 +1263,11 @@ static const meta_info meta_info_list[] = {
{meta_ISB, "Creative ISACT header"},
{meta_XSSB, "Artoon XSSB header"},
{meta_XMA_UE3, "Unreal Engine XMA header"},
{meta_FWSE, "MT Framework FWSE header"},
{meta_FDA, "Relic FDA header"},
{meta_TGC, "Tiger Game.com .4 header"},
{meta_KWB, "Koei Tecmo WaveBank header"},
{meta_LRMD, "Sony LRMD header"},
};

View File

@ -66,17 +66,30 @@ void block_update_ea_swvr(off_t block_offset, VGMSTREAM * vgmstream) {
header_size = 0x1c;
channel_size = (block_size - header_size) / vgmstream->channels;
break;
case 0x53484F43: /* "SHOC" (a generic block but hopefully has PC sounds) */
header_size = 0x14; //todo the first block is 0x18
channel_size = (block_size - header_size) / vgmstream->channels;
if (read_32bit(block_offset+0x10, streamFile) == 0x53444154) { /* "SDAT" */
header_size = 0x14;
channel_size = (block_size - header_size) / vgmstream->channels;
}
else {
header_size = 0;
channel_size = 0;
}
break;
case 0x46494C4C: /* "FILL" (FILLs do that up to 0x6000, but at 0x5FFC don't actually have size) */
case 0x46494C4C: /* "FILL" (FILLs do that up to a block size, but near end don't actually have size) */
if ((block_offset + 0x04) % 0x6000 == 0)
block_size = 0x04;
else if ((block_offset + 0x04) % 0x10000 == 0)
block_size = 0x04;
else if (block_size > 0x100000) { /* other unknown block sizes */
VGM_LOG("EA SWVR: bad block size at 0x%lx\n", block_offset);
block_size = 0x04;
}
header_size = 0x08;
break;
case 0xFFFFFFFF:
channel_size = -1; /* signal bad block */
break;

View File

@ -52,9 +52,9 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
/* get offsets of constituent segments */
for (i = 0; i < segment_count; i++) {
uint32_t offset, size;
int8_t segment_loop_flag = 0;
uint8_t segment_loop_flag = 0;
if (!utf_query_s8(utf, i, "lpflg", &segment_loop_flag)) /* usually in last segment */
if (!utf_query_u8(utf, i, "lpflg", &segment_loop_flag)) /* usually in last segment */
goto fail;
if (!utf_query_data(utf, i, "data", &offset, &size))
goto fail;
@ -138,8 +138,8 @@ fail:
VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int8_t loop_flag = 0, channel_count;
int sample_rate, num_samples, loop_start, loop_end, interleave;
uint8_t loop_flag = 0, channel_count;
uint32_t sample_rate, num_samples, loop_start, loop_end, interleave;
uint32_t data_offset, data_size, header_offset, header_size;
utf_context *utf = NULL;
@ -168,13 +168,13 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
if (rows != 1)
goto fail;
if (!utf_query_s32(utf, 0, "sfreq", &sample_rate))
if (!utf_query_u32(utf, 0, "sfreq", &sample_rate))
goto fail;
if (!utf_query_s32(utf, 0, "nsmpl", &num_samples))
if (!utf_query_u32(utf, 0, "nsmpl", &num_samples))
goto fail;
if (!utf_query_s8(utf, 0, "nch", &channel_count))
if (!utf_query_u8(utf, 0, "nch", &channel_count))
goto fail;
if (!utf_query_s8(utf, 0, "lpflg", &loop_flag)) /* full loops */
if (!utf_query_u8(utf, 0, "lpflg", &loop_flag)) /* full loops */
goto fail;
/* for some reason data is stored before header */
if (!utf_query_data(utf, 0, "data", &data_offset, &data_size))
@ -196,7 +196,7 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate;

View File

@ -183,22 +183,22 @@ static void add_acb_name(acb_header* acb, int8_t Waveform_Streaming) {
static int load_acb_waveform(acb_header* acb, int16_t Index) {
int16_t Waveform_Id;
int8_t Waveform_Streaming;
uint16_t Waveform_Id;
uint8_t Waveform_Streaming;
/* read Waveform[Index] */
if (!open_utf_subtable(acb, &acb->WaveformSf, &acb->WaveformTable, "WaveformTable", NULL))
goto fail;
if (!utf_query_s16(acb->WaveformTable, Index, "Id", &Waveform_Id)) { /* older versions use Id */
if (!utf_query_u16(acb->WaveformTable, Index, "Id", &Waveform_Id)) { /* older versions use Id */
if (acb->is_memory) {
if (!utf_query_s16(acb->WaveformTable, Index, "MemoryAwbId", &Waveform_Id))
if (!utf_query_u16(acb->WaveformTable, Index, "MemoryAwbId", &Waveform_Id))
goto fail;
} else {
if (!utf_query_s16(acb->WaveformTable, Index, "StreamAwbId", &Waveform_Id))
if (!utf_query_u16(acb->WaveformTable, Index, "StreamAwbId", &Waveform_Id))
goto fail;
}
}
if (!utf_query_s8(acb->WaveformTable, Index, "Streaming", &Waveform_Streaming))
if (!utf_query_u8(acb->WaveformTable, Index, "Streaming", &Waveform_Streaming))
goto fail;
//;VGM_LOG("ACB: Waveform[%i]: Id=%i, Streaming=%i\n", Index, Waveform_Id, Waveform_Streaming);
@ -222,7 +222,7 @@ static int load_acb_sequence(acb_header* acb, int16_t Index);
static int load_acb_synth(acb_header* acb, int16_t Index) {
int i, count;
int8_t Synth_Type;
uint8_t Synth_Type;
uint32_t Synth_ReferenceItems_offset;
uint32_t Synth_ReferenceItems_size;
@ -230,7 +230,7 @@ static int load_acb_synth(acb_header* acb, int16_t Index) {
/* read Synth[Index] */
if (!open_utf_subtable(acb, &acb->SynthSf, &acb->SynthTable, "SynthTable", NULL))
goto fail;
if (!utf_query_s8(acb->SynthTable, Index, "Type", &Synth_Type))
if (!utf_query_u8(acb->SynthTable, Index, "Type", &Synth_Type))
goto fail;
if (!utf_query_data(acb->SynthTable, Index, "ReferenceItems", &Synth_ReferenceItems_offset, &Synth_ReferenceItems_size))
goto fail;
@ -249,7 +249,7 @@ static int load_acb_synth(acb_header* acb, int16_t Index) {
* - 1: sequential (1 to N?)
* - 2: shuffle (1 from N?)
* - 3: random (1 from N?)
* - 4: no repeat
* - 4: random no repeat
* - 5: switch game variable
* - 6: combo sequential
* - 7: switch selector
@ -300,7 +300,7 @@ fail:
}
static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
int16_t Track_EventIndex;
uint16_t Track_EventIndex;
uint32_t Track_Command_offset;
uint32_t Track_Command_size;
@ -308,7 +308,7 @@ static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
/* read Track[Index] */
if (!open_utf_subtable(acb, &acb->TrackSf, &acb->TrackTable, "TrackTable", NULL))
goto fail;
if (!utf_query_s16(acb->TrackTable, Index, "EventIndex", &Track_EventIndex))
if (!utf_query_u16(acb->TrackTable, Index, "EventIndex", &Track_EventIndex))
goto fail;
//;VGM_LOG("ACB: Track[%i]: EventIndex=%i\n", Index, Track_EventIndex);
@ -370,6 +370,15 @@ static int load_acb_track_event_command(acb_header* acb, int16_t Index) {
goto fail;
break;
/* possible values? (from debug):
* - sequence
* - track
* - synth
* - trackEvent
* - seqParameterPallet,
* - trackParameterPallet,
* - synthParameterPallet,
*/
default:
VGM_LOG("ACB: unknown TLV type %x at %x + %x\n", tlv_type, offset, tlv_size);
max_offset = 0; /* force end without failing */
@ -390,7 +399,7 @@ fail:
static int load_acb_sequence(acb_header* acb, int16_t Index) {
int i;
int16_t Sequence_NumTracks;
uint16_t Sequence_NumTracks;
uint32_t Sequence_TrackIndex_offset;
uint32_t Sequence_TrackIndex_size;
@ -398,7 +407,7 @@ static int load_acb_sequence(acb_header* acb, int16_t Index) {
/* read Sequence[Index] */
if (!open_utf_subtable(acb, &acb->SequenceSf, &acb->SequenceTable, "SequenceTable", NULL))
goto fail;
if (!utf_query_s16(acb->SequenceTable, Index, "NumTracks", &Sequence_NumTracks))
if (!utf_query_u16(acb->SequenceTable, Index, "NumTracks", &Sequence_NumTracks))
goto fail;
if (!utf_query_data(acb->SequenceTable, Index, "TrackIndex", &Sequence_TrackIndex_offset, &Sequence_TrackIndex_size))
goto fail;
@ -433,7 +442,7 @@ fail:
static int load_acb_block(acb_header* acb, int16_t Index) {
int i;
int16_t Block_NumTracks;
uint16_t Block_NumTracks;
uint32_t Block_TrackIndex_offset;
uint32_t Block_TrackIndex_size;
@ -441,7 +450,7 @@ static int load_acb_block(acb_header* acb, int16_t Index) {
/* read Block[Index] */
if (!open_utf_subtable(acb, &acb->BlockSf, &acb->BlockTable, "BlockTable", NULL))
goto fail;
if (!utf_query_s16(acb->BlockTable, Index, "NumTracks", &Block_NumTracks))
if (!utf_query_u16(acb->BlockTable, Index, "NumTracks", &Block_NumTracks))
goto fail;
if (!utf_query_data(acb->BlockTable, Index, "TrackIndex", &Block_TrackIndex_offset, &Block_TrackIndex_size))
goto fail;
@ -467,16 +476,16 @@ fail:
}
static int load_acb_cue(acb_header* acb, int16_t Index) {
int8_t Cue_ReferenceType;
int16_t Cue_ReferenceIndex;
uint8_t Cue_ReferenceType;
uint16_t Cue_ReferenceIndex;
/* read Cue[Index] */
if (!open_utf_subtable(acb, &acb->CueSf, &acb->CueTable, "CueTable", NULL))
goto fail;
if (!utf_query_s8 (acb->CueTable, Index, "ReferenceType", &Cue_ReferenceType))
if (!utf_query_u8(acb->CueTable, Index, "ReferenceType", &Cue_ReferenceType))
goto fail;
if (!utf_query_s16(acb->CueTable, Index, "ReferenceIndex", &Cue_ReferenceIndex))
if (!utf_query_u16(acb->CueTable, Index, "ReferenceIndex", &Cue_ReferenceIndex))
goto fail;
//;VGM_LOG("ACB: Cue[%i]: ReferenceType=%i, ReferenceIndex=%i\n", Index, Cue_ReferenceType, Cue_ReferenceIndex);
@ -484,28 +493,35 @@ static int load_acb_cue(acb_header* acb, int16_t Index) {
/* usually older games use older references but not necessarily */
switch(Cue_ReferenceType) {
case 1: /* Cue > Waveform (ex. PES 2015) */
case 0x01: /* Cue > Waveform (ex. PES 2015) */
if (!load_acb_waveform(acb, Cue_ReferenceIndex))
goto fail;
break;
case 2: /* Cue > Synth > Waveform (ex. Ukiyo no Roushi) */
case 0x02: /* Cue > Synth > Waveform (ex. Ukiyo no Roushi) */
if (!load_acb_synth(acb, Cue_ReferenceIndex))
goto fail;
break;
case 3: /* Cue > Sequence > Track > Command > Synth > Waveform (ex. Valkyrie Profile anatomia, Yakuza Kiwami 2) */
case 0x03: /* Cue > Sequence > Track > Command > Synth > Waveform (ex. Valkyrie Profile anatomia, Yakuza Kiwami 2) */
if (!load_acb_sequence(acb, Cue_ReferenceIndex))
goto fail;
break;
case 8: /* Cue > Block > Track > Command > Synth > Waveform (ex. Sonic Lost World, rare) */
//todo "blockSequence"?
case 0x08: /* Cue > Block > Track > Command > Synth > Waveform (ex. Sonic Lost World, rare) */
if (!load_acb_block(acb, Cue_ReferenceIndex))
goto fail;
break;
case 6: /* Cue > (Waveform/Synth/Command)? (ex. PES 2014) */
case 7: /* Cue > (Waveform/Synth/Command)? (ex. PES 2014) */
case 0x00: /* none */
case 0x04: /* "track" */
case 0x05: /* "outsideLink" */
case 0x06: /* "insideLinkSynth" (ex. PES 2014) */
case 0x07: /* "insideLinkSequence" (ex. PES 2014) */
case 0x09: /* "insideLinkBlockSequence" */
case 0x0a: /* "eventCue_UnUse" */
case 0x0b: /* "soundGenerator" */
default:
VGM_LOG("ACB: unknown Cue.ReferenceType=%x, Cue.ReferenceIndex=%x\n", Cue_ReferenceType, Cue_ReferenceIndex);
break; /* ignore and continue */
@ -519,14 +535,14 @@ fail:
}
static int load_acb_cuename(acb_header* acb, int16_t Index) {
int16_t CueName_CueIndex;
uint16_t CueName_CueIndex;
const char* CueName_CueName;
/* read CueName[Index] */
if (!open_utf_subtable(acb, &acb->CueNameSf, &acb->CueNameTable, "CueNameTable", NULL))
goto fail;
if (!utf_query_s16(acb->CueNameTable, Index, "CueIndex", &CueName_CueIndex))
if (!utf_query_u16(acb->CueNameTable, Index, "CueIndex", &CueName_CueIndex))
goto fail;
if (!utf_query_string(acb->CueNameTable, Index, "CueName", &CueName_CueName))
goto fail;

View File

@ -1,376 +0,0 @@
#include "cri_utf.h"
/* possibly 3b+5b from clUTF decompilation */
#define COLUMN_BITMASK_STORAGE 0xf0
#define COLUMN_BITMASK_TYPE 0x0f
enum column_storage_t {
COLUMN_STORAGE_ZERO = 0x10,
COLUMN_STORAGE_CONSTANT = 0x30,
COLUMN_STORAGE_ROW = 0x50
//COLUMN_STORAGE_CONSTANT2 = 0x70 /* from vgmtoolbox */
};
enum column_type_t {
COLUMN_TYPE_SINT8 = 0x00,
COLUMN_TYPE_UINT8 = 0x01,
COLUMN_TYPE_SINT16 = 0x02,
COLUMN_TYPE_UINT16 = 0x03,
COLUMN_TYPE_SINT32 = 0x04,
COLUMN_TYPE_UINT32 = 0x05,
COLUMN_TYPE_SINT64 = 0x06,
//COLUMN_TYPE_UINT64 = 0x07,
COLUMN_TYPE_FLOAT = 0x08,
//COLUMN_TYPE_DOUBLE = 0x09,
COLUMN_TYPE_STRING = 0x0a,
COLUMN_TYPE_DATA = 0x0b
};
typedef struct {
int found;
enum column_type_t type;
union {
int8_t value_s8;
uint8_t value_u8;
int16_t value_s16;
uint16_t value_u16;
int32_t value_s32;
uint32_t value_u32;
int64_t value_s64;
uint64_t value_u64;
float value_float;
double value_double;
struct utf_data_t {
uint32_t offset;
uint32_t size;
} value_data;
const char *value_string;
} value;
} utf_result_t;
struct utf_context {
STREAMFILE *sf;
uint32_t table_offset;
/* header */
uint32_t table_size;
uint16_t version;
uint16_t rows_offset;
uint32_t strings_offset;
uint32_t data_offset;
uint32_t name_offset;
uint16_t columns;
uint16_t row_width;
uint32_t rows;
struct utf_column_t {
uint8_t flags;
const char *name;
uint32_t offset;
} *schema;
/* derived */
uint32_t schema_offset;
uint32_t strings_size;
char *string_table;
const char *table_name;
};
/* @UTF table context creation */
utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const char **p_row_name) {
utf_context* utf = NULL;
utf = calloc(1, sizeof(utf_context));
if (!utf) goto fail;
utf->sf = sf;
utf->table_offset = table_offset;
/* check header */
if (read_u32be(table_offset + 0x00, sf) != 0x40555446) /* "@UTF" */
goto fail;
/* load table header */
utf->table_size = read_u32be(table_offset + 0x04, sf) + 0x08;
utf->version = read_u16be(table_offset + 0x08, sf);
utf->rows_offset = read_u16be(table_offset + 0x0a, sf) + 0x08;
utf->strings_offset = read_u32be(table_offset + 0x0c, sf) + 0x08;
utf->data_offset = read_u32be(table_offset + 0x10, sf) + 0x08;
utf->name_offset = read_u32be(table_offset + 0x14, sf); /* within string table */
utf->columns = read_u16be(table_offset + 0x18, sf);
utf->row_width = read_u16be(table_offset + 0x1a, sf);
utf->rows = read_u32be(table_offset + 0x1c, sf);
utf->schema_offset = 0x20;
utf->strings_size = utf->data_offset - utf->strings_offset;
/* 00: early (32b rows_offset?), 01: +2017 (no apparent differences) */
if (utf->version != 0x00 && utf->version != 0x01) {
VGM_LOG("@UTF: unknown version\n");
}
if (utf->table_offset + utf->table_size > get_streamfile_size(sf))
goto fail;
if (utf->rows_offset > utf->table_size || utf->strings_offset > utf->table_size || utf->data_offset > utf->table_size)
goto fail;
if (utf->strings_size <= 0 || utf->name_offset > utf->strings_size)
goto fail;
/* no rows is possible for empty tables (have schema and columns names but no data) [PES 2013 (PC)] */
if (utf->columns <= 0 /*|| utf->rows <= 0 || utf->rows_width <= 0*/)
goto fail;
/* load string table */
{
size_t read;
utf->string_table = calloc(utf->strings_size + 1, sizeof(char));
if (!utf->string_table) goto fail;
utf->table_name = utf->string_table + utf->name_offset;
read = read_streamfile((unsigned char*)utf->string_table, utf->table_offset + utf->strings_offset, utf->strings_size, sf);
if (utf->strings_size != read) goto fail;
}
/* load column schema */
{
int i;
uint32_t value_size, column_offset = 0;
uint32_t schema_offset = utf->table_offset + utf->schema_offset;
utf->schema = malloc(sizeof(struct utf_column_t) * utf->columns);
if (!utf->schema) goto fail;
for (i = 0; i < utf->columns; i++) {
uint8_t flags = read_u8(schema_offset + 0x00, sf);
uint32_t name_offset = read_u32be(schema_offset + 0x01, sf);
if (name_offset > utf->strings_size)
goto fail;
utf->schema[i].flags = flags;
utf->schema[i].name = utf->string_table + name_offset;
schema_offset += 0x01 + 0x04;
switch (utf->schema[i].flags & COLUMN_BITMASK_TYPE) {
case COLUMN_TYPE_SINT8:
case COLUMN_TYPE_UINT8:
value_size = 0x01;
break;
case COLUMN_TYPE_SINT16:
case COLUMN_TYPE_UINT16:
value_size = 0x02;
break;
case COLUMN_TYPE_SINT32:
case COLUMN_TYPE_UINT32:
case COLUMN_TYPE_FLOAT:
case COLUMN_TYPE_STRING:
value_size = 0x04;
break;
case COLUMN_TYPE_SINT64:
//case COLUMN_TYPE_UINT64:
//case COLUMN_TYPE_DOUBLE:
case COLUMN_TYPE_DATA:
value_size = 0x08;
break;
default:
VGM_LOG("@UTF: unknown column type\n");
goto fail;
}
switch (utf->schema[i].flags & COLUMN_BITMASK_STORAGE) {
case COLUMN_STORAGE_ROW:
utf->schema[i].offset = column_offset;
column_offset += value_size;
break;
case COLUMN_STORAGE_CONSTANT:
//case COLUMN_STORAGE_CONSTANT2:
utf->schema[i].offset = schema_offset - (utf->table_offset + utf->schema_offset); /* relative to schema */
schema_offset += value_size;
break;
case COLUMN_STORAGE_ZERO:
utf->schema[i].offset = 0; /* ? */
break;
default:
VGM_LOG("@UTF: unknown column storage\n");
goto fail;
}
}
}
/* write info */
if (p_rows) *p_rows = utf->rows;
if (p_row_name) *p_row_name = utf->string_table + utf->name_offset;
return utf;
fail:
utf_close(utf);
VGM_LOG("@UTF: fail\n");
return NULL;
}
void utf_close(utf_context *utf) {
if (!utf) return;
free(utf->string_table);
free(utf->schema);
free(utf);
}
static int utf_query(utf_context *utf, int row, const char *column, utf_result_t *result) {
int i;
result->found = 0;
if (row >= utf->rows || row < 0)
goto fail;
/* find target column */
for (i = 0; i < utf->columns; i++) {
struct utf_column_t *col = &utf->schema[i];
uint32_t data_offset;
if (strcmp(col->name, column) != 0)
continue;
result->found = 1;
result->type = col->flags & COLUMN_BITMASK_TYPE;
switch (col->flags & COLUMN_BITMASK_STORAGE) {
case COLUMN_STORAGE_ROW:
data_offset = utf->table_offset + utf->rows_offset + row * utf->row_width + col->offset;
break;
case COLUMN_STORAGE_CONSTANT:
//case COLUMN_STORAGE_CONSTANT2:
data_offset = utf->table_offset + utf->schema_offset + col->offset;
break;
case COLUMN_STORAGE_ZERO:
data_offset = 0;
memset(&result->value, 0, sizeof(result->value));
break;
default:
goto fail;
}
/* ignore zero value */
if (!data_offset)
break;
/* read row/constant value */
switch (col->flags & COLUMN_BITMASK_TYPE) {
case COLUMN_TYPE_SINT8:
result->value.value_s8 = read_s8(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT8:
result->value.value_u8 = read_u8(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT16:
result->value.value_s16 = read_s16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT16:
result->value.value_u16 = read_u16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT32:
result->value.value_s32 = read_s32be(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT32:
result->value.value_u32 = read_u32be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT64:
result->value.value_s64 = read_s64be(data_offset, utf->sf);
break;
#if 0
case COLUMN_TYPE_UINT64:
result->value.value_u64 = read_u64be(data_offset, utf->sf);
break;
#endif
case COLUMN_TYPE_FLOAT: {
result->value.value_float = read_f32be(data_offset, utf->sf);
break;
}
#if 0
case COLUMN_TYPE_DOUBLE: {
result->value.value_double = read_d64be(data_offset, utf->sf);
break;
}
#endif
case COLUMN_TYPE_STRING: {
uint32_t name_offset = read_u32be(data_offset, utf->sf);
if (name_offset > utf->strings_size)
goto fail;
result->value.value_string = utf->string_table + name_offset;
break;
}
case COLUMN_TYPE_DATA:
result->value.value_data.offset = read_u32be(data_offset + 0x00, utf->sf);
result->value.value_data.size = read_u32be(data_offset + 0x04, utf->sf);
break;
default:
goto fail;
}
break; /* column found and read */
}
return 1;
fail:
return 0;
}
static int utf_query_value(utf_context *utf, int row, const char *column, void *value, enum column_type_t type) {
utf_result_t result = {0};
int valid;
valid = utf_query(utf, row, column, &result);
if (!valid || !result.found || result.type != type)
return 0;
switch(result.type) {
case COLUMN_TYPE_SINT8: (*(int8_t*)value) = result.value.value_s8; break;
case COLUMN_TYPE_UINT8: (*(uint8_t*)value) = result.value.value_u8; break;
case COLUMN_TYPE_SINT16: (*(int16_t*)value) = result.value.value_s16; break;
case COLUMN_TYPE_UINT16: (*(uint16_t*)value) = result.value.value_u16; break;
case COLUMN_TYPE_SINT32: (*(int32_t*)value) = result.value.value_s32; break;
case COLUMN_TYPE_UINT32: (*(uint32_t*)value) = result.value.value_u32; break;
case COLUMN_TYPE_SINT64: (*(int64_t*)value) = result.value.value_s64; break;
//case COLUMN_TYPE_UINT64: (*(uint64_t*)value) = result.value.value_u64; break;
case COLUMN_TYPE_STRING: (*(const char**)value) = result.value.value_string; break;
default:
return 0;
}
return 1;
}
int utf_query_s8(utf_context *utf, int row, const char *column, int8_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT8);
}
int utf_query_s16(utf_context *utf, int row, const char *column, int16_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT16);
}
int utf_query_s32(utf_context *utf, int row, const char *column, int32_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT32);
}
int utf_query_string(utf_context *utf, int row, const char *column, const char **value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_STRING);
}
int utf_query_data(utf_context *utf, int row, const char *column, uint32_t *p_offset, uint32_t *p_size) {
utf_result_t result = {0};
int valid;
valid = utf_query(utf, row, column, &result);
if (!valid || !result.found || result.type != COLUMN_TYPE_DATA)
return 0;
if (p_offset) *p_offset = utf->table_offset + utf->data_offset + result.value.value_data.offset;
if (p_size) *p_size = result.value.value_data.size;
return 1;
}

View File

@ -187,6 +187,12 @@ static const adxkey_info adxkey8_list[] = {
/* Lucky Star: RAvish Romance (PS2) [Vridge] */
{0x5347,0x4FB7,0x6415, "LUCKYSRARPS2",0},
/* Katekyoo Hitman Reborn! Nerae! Ring x Bongole Trainers (PS2) */
{0x61C7,0x4549,0x4337, "ORN2HITMAN",0},
/* Katekyoo Hitman Reborn! Let's Ansatsu! Nerawareta 10-daime! (PS2) */
{0x5381,0x52E5,0x53E9, "REBHITMAN",0},
};
static const adxkey_info adxkey9_list[] = {

View File

@ -1,15 +1,17 @@
#include "meta.h"
#include "../layout/layout.h"
#include "../coding/coding.h"
/* for reading integers inexplicably packed into 80-bit ('double extended') floats */
static uint32_t read80bitSANE(off_t offset, STREAMFILE *streamFile) {
uint8_t buf[10];
uint8_t buf[0x0a];
int32_t exponent;
int32_t mantissa;
int i;
if (read_streamfile(buf,offset,10,streamFile) != 10) return 0;
if (read_streamfile(buf,offset,0x0a,streamFile) != 0x0a)
return 0;
exponent = ((buf[0]<<8)|(buf[1]))&0x7fff;
exponent -= 16383;
@ -26,13 +28,13 @@ static uint32_t read80bitSANE(off_t offset, STREAMFILE *streamFile) {
return mantissa*((buf[0]&0x80)?-1:1);
}
static uint32_t find_marker(STREAMFILE *streamFile, off_t MarkerChunkOffset, int marker_id) {
static uint32_t find_marker(STREAMFILE *streamFile, off_t mark_offset, int marker_id) {
uint16_t marker_count;
int i;
off_t marker_offset;
marker_count = read_16bitBE(MarkerChunkOffset+8,streamFile);
marker_offset = MarkerChunkOffset+10;
marker_count = read_16bitBE(mark_offset+8,streamFile);
marker_offset = mark_offset+10;
for (i=0;i<marker_count;i++) {
int name_length;
@ -61,8 +63,8 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
int32_t loop_start = 0, loop_end = 0;
int is_aiff_ext = 0, is_aifc_ext = 0, is_aiff = 0, is_aifc = 0;
int FormatVersionChunkFound = 0, CommonChunkFound = 0, SoundDataChunkFound = 0, MarkerChunkFound = 0, InstrumentChunkFound = 0;
off_t MarkerChunkOffset = -1, InstrumentChunkOffset = -1;
int fver_found = 0, comm_found = 0, data_found = 0, mark_found = 0, inst_found = 0;
off_t mark_offset = -1, inst_offset = -1;
/* checks */
@ -74,12 +76,13 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
* .acm: Crusader - No Remorse (SAT)
* .adp: Sonic Jam (SAT)
* .ai: Dragon Force (SAT)
* (extensionless: Doom (3DO) */
* (extensionless: Doom (3DO)
* .fda: Homeworld 2 (PC) */
if (check_extensions(streamFile, "aif,laif,")) {
is_aifc_ext = 1;
is_aiff_ext = 1;
}
else if (check_extensions(streamFile, "aifc,laifc,aifcl,afc,cbd2,bgm")) {
else if (check_extensions(streamFile, "aifc,laifc,aifcl,afc,cbd2,bgm,fda")) {
is_aifc_ext = 1;
}
else if (check_extensions(streamFile, "aiff,laiff,acm,adp,ai,aiffl")) {
@ -123,9 +126,9 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
switch(chunk_type) {
case 0x46564552: /* "FVER" (version info) */
if (FormatVersionChunkFound) goto fail;
if (fver_found) goto fail;
if (is_aiff) goto fail; /* plain AIFF shouldn't have */
FormatVersionChunkFound = 1;
fver_found = 1;
/* specific size */
if (chunk_size != 4) goto fail;
@ -135,8 +138,8 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
break;
case 0x434F4D4D: /* "COMM" (main header) */
if (CommonChunkFound) goto fail;
CommonChunkFound = 1;
if (comm_found) goto fail;
comm_found = 1;
channel_count = read_16bitBE(current_chunk+8,streamFile);
if (channel_count <= 0) goto fail;
@ -146,24 +149,45 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
sample_rate = read80bitSANE(current_chunk+0x10,streamFile);
if (is_aifc) {
switch (read_32bitBE(current_chunk+0x1a,streamFile)) {
uint32_t codec = read_32bitBE(current_chunk+0x1a,streamFile);
switch (codec) {
case 0x53445832: /* "SDX2" [3DO games: Super Street Fighter II Turbo (3DO), etc] */
coding_type = coding_SDX2;
interleave = 0x01;
break;
case 0x43424432: /* "CBD2" [M2 (arcade 3DO) games: IMSA Racing (M2), etc] */
coding_type = coding_CBD2;
interleave = 0x01;
break;
case 0x41445034: /* "ADP4" */
coding_type = coding_DVI_IMA_int;
if (channel_count != 1) break; /* don't know how stereo DVI is laid out */
break;
case 0x696D6134: /* "ima4" [Alida (PC), Lunar SSS (iOS)] */
coding_type = coding_APPLE_IMA4;
interleave = 0x22;
sample_count = sample_count * ((interleave-0x2)*2);
break;
case 0x434F4D50: { /* "COMP" (generic compression) */
uint8_t comp_name[255] = {0};
uint8_t comp_size = read_8bit(current_chunk + 0x1e, streamFile);
if (comp_size >= sizeof(comp_name) - 1) goto fail;
read_streamfile(comp_name, current_chunk + 0x1f, comp_size, streamFile);
if (memcmp(comp_name, "Relic Codec v1.6", comp_size) == 0) { /* Homeworld 2 (PC) */
coding_type = coding_RELIC;
sample_count = sample_count * 512;
}
else {
goto fail;
}
break;
}
default:
VGM_LOG("AIFC: unknown codec\n");
goto fail;
@ -192,25 +216,25 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
case 0x53534E44: /* "SSND" (main data) */
case 0x4150434D: /* "APCM" (main data for XA) */
if (SoundDataChunkFound) goto fail;
SoundDataChunkFound = 1;
if (data_found) goto fail;
data_found = 1;
start_offset = current_chunk + 0x10 + read_32bitBE(current_chunk+0x08,streamFile);
/* when "APCM" XA frame size is at 0x0c, fixed to 0x914 */
break;
case 0x4D41524B: /* "MARK" (loops) */
if (MarkerChunkFound) goto fail;
MarkerChunkFound = 1;
if (mark_found) goto fail;
mark_found = 1;
MarkerChunkOffset = current_chunk;
mark_offset = current_chunk;
break;
case 0x494E5354: /* "INST" (loops) */
if (InstrumentChunkFound) goto fail;
InstrumentChunkFound = 1;
if (inst_found) goto fail;
inst_found = 1;
InstrumentChunkOffset = current_chunk;
inst_offset = current_chunk;
break;
default:
@ -223,28 +247,28 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
}
if (is_aifc) {
if (!FormatVersionChunkFound || !CommonChunkFound || !SoundDataChunkFound)
if (!fver_found || !comm_found || !data_found)
goto fail;
} else if (is_aiff) {
if (!CommonChunkFound || !SoundDataChunkFound)
if (!comm_found || !data_found)
goto fail;
}
/* read loop points */
if (InstrumentChunkFound && MarkerChunkFound) {
if (inst_found && mark_found) {
int start_marker;
int end_marker;
/* use the sustain loop */
/* if playMode=ForwardLooping */
if (read_16bitBE(InstrumentChunkOffset+16,streamFile) == 1) {
start_marker = read_16bitBE(InstrumentChunkOffset+18,streamFile);
end_marker = read_16bitBE(InstrumentChunkOffset+20,streamFile);
if (read_16bitBE(inst_offset+16,streamFile) == 1) {
start_marker = read_16bitBE(inst_offset+18,streamFile);
end_marker = read_16bitBE(inst_offset+20,streamFile);
/* check for sustain markers != 0 (invalid marker no) */
if (start_marker && end_marker) {
/* find start marker */
loop_start = find_marker(streamFile,MarkerChunkOffset,start_marker);
loop_end = find_marker(streamFile,MarkerChunkOffset,end_marker);
loop_start = find_marker(streamFile,mark_offset,start_marker);
loop_end = find_marker(streamFile,mark_offset,end_marker);
/* find_marker is type uint32_t as the spec says that's the type
* of the position value, but it returns a -1 on error, and the
@ -257,6 +281,8 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
loop_flag = 0;
}
}
/* Relic has "beg loop" "end loop" comments but no actual looping? */
}
@ -270,14 +296,28 @@ VGMSTREAM * init_vgmstream_aifc(STREAMFILE *streamFile) {
vgmstream->loop_end_sample = loop_end;
vgmstream->coding_type = coding_type;
if (coding_type == coding_XA) {
vgmstream->layout_type = layout_blocked_xa_aiff;
/* AIFF XA can use sample rates other than 37800/18900 */
/* some Crusader: No Remorse tracks have XA headers with incorrect 0xFF, rip bug/encoder feature? */
}
else {
vgmstream->layout_type = (channel_count > 1) ? layout_interleave : layout_none;
vgmstream->interleave_block_size = interleave;
switch(coding_type) {
case coding_XA:
vgmstream->layout_type = layout_blocked_xa_aiff;
/* AIFF XA can use sample rates other than 37800/18900 */
/* some Crusader: No Remorse tracks have XA headers with incorrect 0xFF, rip bug/encoder feature? */
break;
case coding_RELIC: {
int bitrate = read_16bitBE(start_offset, streamFile);
start_offset += 0x02;
vgmstream->codec_data = init_relic(channel_count, bitrate, sample_rate);
if (!vgmstream->codec_data) goto fail;
vgmstream->layout_type = layout_none;
vgmstream->sample_rate = 44100; /* fixed output */
break;
}
default:
vgmstream->layout_type = (channel_count > 1) ? layout_interleave : layout_none;
vgmstream->interleave_block_size = interleave;
break;
}
if (is_aifc)

View File

@ -1,133 +1,51 @@
#ifndef _AIX_STREAMFILE_H_
#define _AIX_STREAMFILE_H_
#include "../streamfile.h"
typedef struct {
/* config */
off_t stream_offset;
size_t stream_size;
int layer_number;
/* state */
off_t logical_offset; /* fake offset */
off_t physical_offset; /* actual offset */
size_t block_size; /* current size */
size_t skip_size; /* size from block start to reach data */
size_t data_size; /* usable size in a block */
size_t logical_size;
} aix_io_data;
static size_t aix_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, aix_io_data* data) {
size_t total_read = 0;
/* re-start when previous offset (can't map logical<>physical offsets) */
if (data->logical_offset < 0 || offset < data->logical_offset) {
data->physical_offset = data->stream_offset;
data->logical_offset = 0x00;
data->data_size = 0;
}
/* read blocks */
while (length > 0) {
/* ignore EOF */
if (offset < 0 || data->physical_offset >= data->stream_offset + data->stream_size) {
break;
}
/* process new block */
if (data->data_size == 0) {
uint32_t block_id = read_u32be(data->physical_offset+0x00, streamfile);
data->block_size = read_u32be(data->physical_offset+0x04, streamfile) + 0x08;
/* check valid block "AIXP" id, knowing that AIX segments end with "AIXE" block too */
if (block_id != 0x41495850 || data->block_size == 0 || data->block_size == 0xFFFFFFFF) {
break;
}
/* read target layer, otherwise skip to next block and try again */
if (read_s8(data->physical_offset+0x08, streamfile) == data->layer_number) {
/* 0x09(1): layer count */
data->data_size = read_s16be(data->physical_offset+0x0a, streamfile);
/* 0x0c: -1 */
data->skip_size = 0x10;
}
/* strange AIX in Tetris Collection (PS2) with padding before ADX start (no known flag) */
if (data->logical_offset == 0x00 &&
read_u32be(data->physical_offset + 0x10, streamfile) == 0 &&
read_u16be(data->physical_offset + data->block_size - 0x28, streamfile) == 0x8000) {
data->data_size = 0x28;
data->skip_size = data->block_size - 0x28;
}
}
/* move to next block */
if (data->data_size == 0 || offset >= data->logical_offset + data->data_size) {
data->physical_offset += data->block_size;
data->logical_offset += data->data_size;
data->data_size = 0;
continue;
}
/* read data */
{
size_t bytes_consumed, bytes_done, to_read;
bytes_consumed = offset - data->logical_offset;
to_read = data->data_size - bytes_consumed;
if (to_read > length)
to_read = length;
bytes_done = read_streamfile(dest, data->physical_offset + data->skip_size + bytes_consumed, to_read, streamfile);
total_read += bytes_done;
dest += bytes_done;
offset += bytes_done;
length -= bytes_done;
if (bytes_done != to_read || bytes_done == 0) {
break; /* error/EOF */
}
}
}
return total_read;
}
static size_t aix_io_size(STREAMFILE *streamfile, aix_io_data* data) {
uint8_t buf[1];
if (data->logical_size)
return data->logical_size;
/* force a fake read at max offset, to get max logical_offset (will be reset next read) */
aix_io_read(streamfile, buf, 0x7FFFFFFF, 1, data);
data->logical_size = data->logical_offset;
return data->logical_size;
}
/* Handles deinterleaving of AIX blocked layer streams */
static STREAMFILE* setup_aix_streamfile(STREAMFILE *sf, off_t stream_offset, size_t stream_size, int layer_number, const char* extension) {
STREAMFILE *new_sf = NULL;
aix_io_data io_data = {0};
io_data.stream_offset = stream_offset;
io_data.stream_size = stream_size;
io_data.layer_number = layer_number;
io_data.logical_offset = -1; /* force reset */
new_sf = open_wrap_streamfile(sf);
new_sf = open_io_streamfile_f(new_sf, &io_data, sizeof(aix_io_data), aix_io_read, aix_io_size);
new_sf = open_buffer_streamfile_f(new_sf, 0);
if (extension) {
new_sf = open_fakename_streamfile_f(new_sf, NULL, extension);
}
return new_sf;
}
#endif /* _AIX_STREAMFILE_H_ */
#ifndef _AIX_STREAMFILE_H_
#define _AIX_STREAMFILE_H_
#include "deblock_streamfile.h"
//todo block size must check >= stream_size
static void block_callback(STREAMFILE *sf, deblock_io_data *data) {
uint32_t block_id = read_u32be(data->physical_offset + 0x00, sf);
data->block_size = read_u32be(data->physical_offset + 0x04, sf) + 0x08;
/* check "AIXP" id, (AIX segments end with "AIXE" too) */
if (block_id != 0x41495850) {
return;
}
/* read target layer, otherwise ignore block */
if (read_s8(data->physical_offset + 0x08, sf) == data->cfg.track_number) {
/* 0x09(1): layer count */
data->data_size = read_s16be(data->physical_offset + 0x0a, sf);
/* 0x0c: -1 */
data->skip_size = 0x10;
}
/* strange AIX in Tetris Collection (PS2) with padding before ADX start (no known flag) */
if (data->logical_offset == 0x00 &&
read_u32be(data->physical_offset + 0x10, sf) == 0 &&
read_u16be(data->physical_offset + data->block_size - 0x28, sf) == 0x8000) {
data->data_size = 0x28;
data->skip_size = data->block_size - 0x28;
}
}
/* Deinterleaves AIX layers */
static STREAMFILE* setup_aix_streamfile(STREAMFILE *sf, off_t stream_offset, size_t stream_size, int layer_number, const char* extension) {
STREAMFILE *new_sf = NULL;
deblock_config_t cfg = {0};
cfg.stream_start = stream_offset;
cfg.stream_size = stream_size;
cfg.track_number = layer_number;
cfg.block_callback = block_callback;
new_sf = open_wrap_streamfile(sf);
new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
//new_sf = open_buffer_streamfile_f(new_sf, 0);
if (extension)
new_sf = open_fakename_streamfile_f(new_sf, NULL, extension);
return new_sf;
}
#endif /* _AIX_STREAMFILE_H_ */

View File

@ -10,7 +10,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
size_t stream_size, interleave = 0;
off_t sblk_offset, data_offset;
size_t data_size;
int channel_count = 0, loop_flag, sample_rate, parts, version, big_endian;
int channel_count = 0, loop_flag, sample_rate, parts, sblk_version, big_endian;
int loop_start = 0, loop_end = 0;
uint32_t pitch, flags;
uint32_t atrac9_info = 0;
@ -18,6 +18,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
int total_subsongs, target_subsong = streamFile->stream_index;
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
float (*read_f32)(off_t,STREAMFILE*) = NULL;
bnk_codec codec;
@ -25,14 +26,17 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
if (!check_extensions(streamFile, "bnk"))
goto fail;
/* bnk version */
if (read_32bitBE(0x00,streamFile) == 0x00000003) { /* PS3 */
read_32bit = read_32bitBE;
read_16bit = read_16bitBE;
read_f32 = read_f32be;
big_endian = 1;
}
else if (read_32bitBE(0x00,streamFile) == 0x03000000) { /* Vita/PS4 */
else if (read_32bitBE(0x00,streamFile) == 0x03000000) { /* PS2/Vita/PS4 */
read_32bit = read_32bitLE;
read_16bit = read_16bitLE;
read_f32 = read_f32le;
big_endian = 0;
}
else {
@ -58,9 +62,9 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
/* SBlk part: parse header */
if (read_32bit(sblk_offset+0x00,streamFile) != 0x6B6C4253) /* "klBS" (SBlk = sample block?) */
goto fail;
version = read_32bit(sblk_offset+0x04,streamFile);
/* 0x08: possibly when version=0x0d, 0x03=Vita, 0x06=PS4 */
//;VGM_LOG("BNK: sblk_offset=%lx, data_offset=%lx, version %x\n", sblk_offset, data_offset, version);
sblk_version = read_32bit(sblk_offset+0x04,streamFile);
/* 0x08: possibly when sblk_version=0x0d, 0x03=Vita, 0x06=PS4 */
//;VGM_LOG("BNK: sblk_offset=%lx, data_offset=%lx, sblk_version %x\n", sblk_offset, data_offset, sblk_version);
{
int i;
@ -73,9 +77,23 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
off_t table4_entries_offset, table4_names_offset;
switch(version) {
case 0x03: /* L@ove Once - Mermaid's Tears (PS3) */
switch(sblk_version) {
case 0x01: /* Ratchet & Clank (PS2) */
section_entries = (uint16_t)read_16bit(sblk_offset+0x16,streamFile); /* entry size: ~0x0c */
material_entries = (uint16_t)read_16bit(sblk_offset+0x18,streamFile); /* entry size: ~0x28 */
stream_entries = (uint16_t)read_16bit(sblk_offset+0x1a,streamFile); /* entry size: none (count) */
table1_offset = sblk_offset + read_32bit(sblk_offset+0x1c,streamFile);
table2_offset = sblk_offset + read_32bit(sblk_offset+0x20,streamFile);
table3_offset = table2_offset; /* mixed table in this version */
table4_offset = 0; /* not included */
table1_entry_size = 0; /* not used */
table1_suboffset = 0;
table2_suboffset = 0;
break;
case 0x04: /* Test banks */
case 0x05: /* Ratchet & Clank (PS3) */
case 0x09: /* Puyo Puyo Tetris (PS4) */
section_entries = (uint16_t)read_16bit(sblk_offset+0x16,streamFile); /* entry size: ~0x0c */
material_entries = (uint16_t)read_16bit(sblk_offset+0x18,streamFile); /* entry size: ~0x08 */
@ -106,7 +124,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
break;
default:
VGM_LOG("BNK: unknown version %x\n", version);
VGM_LOG("BNK: unknown version %x\n", sblk_version);
goto fail;
}
@ -125,28 +143,44 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
* - get stream offsets
* - find if one section points to the selected material, and get section name = stream name */
/* parse materials */
total_subsongs = 0;
if (target_subsong == 0) target_subsong = 1;
for (i = 0; i < material_entries; i++) {
uint32_t table2_value, table2_subinfo, table2_subtype;
switch(sblk_version) {
case 0x01:
/* table2/3 has size 0x28 entries, seemingly:
* 0x00: subtype(01=sound)
* 0x0A: pitch
* 0x18: stream offset
* there is no stream size so we'd need some sample counting
* many sounds repeat entries for no apparent reason
*/
table2_value = (uint32_t)read_32bit(table2_offset+(i*0x08)+table2_suboffset+0x00,streamFile);
table2_subinfo = (table2_value >> 0) & 0xFFFF;
table2_subtype = (table2_value >> 16) & 0xFFFF;
if (table2_subtype != 0x100)
continue; /* not sounds */
goto fail;
total_subsongs++;
if (total_subsongs == target_subsong) {
table2_entry_offset = (i*0x08);
table3_entry_offset = table2_subinfo;
/* continue to count all subsongs*/
}
default:
for (i = 0; i < material_entries; i++) {
uint32_t table2_value, table2_subinfo, table2_subtype;
table2_value = (uint32_t)read_32bit(table2_offset+(i*0x08)+table2_suboffset+0x00,streamFile);
table2_subinfo = (table2_value >> 0) & 0xFFFF;
table2_subtype = (table2_value >> 16) & 0xFFFF;
if (table2_subtype != 0x100)
continue; /* not sounds */
total_subsongs++;
if (total_subsongs == target_subsong) {
table2_entry_offset = (i*0x08);
table3_entry_offset = table2_subinfo;
/* continue to count all subsongs*/
}
}
break;
}
//;VGM_LOG("BNK: subsongs %i, table2_entry=%lx, table3_entry=%lx\n", total_subsongs,table2_entry_offset,table3_entry_offset);
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
@ -159,9 +193,10 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
//;VGM_LOG("BNK: header entry at %lx\n", table3_offset+table3_entry_offset);
/* parse sounds */
switch(version) {
switch(sblk_version) {
case 0x03:
case 0x04:
case 0x05:
case 0x09:
pitch = (uint8_t)read_8bit(table3_offset+table3_entry_offset+0x02,streamFile);
flags = (uint8_t)read_8bit(table3_offset+table3_entry_offset+0x0f,streamFile);
@ -185,6 +220,8 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
case 0xAC: sample_rate = 12000; break; //?
case 0xAA: sample_rate = 11025; break;
case 0xA9: sample_rate = 10000; break; //?
case 0xA4: sample_rate = 6000; break; //?
case 0x9d: sample_rate = 4000; break; //?
default:
VGM_LOG("BNK: unknown pitch %x\n", pitch);
goto fail;
@ -196,20 +233,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
flags = (uint8_t)read_8bit(table3_offset+table3_entry_offset+0x12,streamFile);
stream_offset = read_32bit(table3_offset+table3_entry_offset+0x44,streamFile);
stream_size = read_32bit(table3_offset+table3_entry_offset+0x48,streamFile);
pitch = (uint32_t)read_32bit(table3_offset+table3_entry_offset+0x4c,streamFile);
/* this looks like "((pitch >> 9) & 0xC000) | ((pitch >> 8) & 0xFFFF)" but... why??? */
switch(pitch) {
case 0x467A0000: sample_rate = 64000; break; //?
case 0x46BB8000: sample_rate = 48000; break;
case 0x473B8000: sample_rate = 48000; break;
case 0x46AC4400: sample_rate = 44100; break;
case 0x47AC4400: sample_rate = 44100; break;
case 0x472C4400: sample_rate = 44100; break;
default:
VGM_LOG("BNK: unknown pitch %x\n", pitch);
goto fail;
}
sample_rate = (int)read_f32(table3_offset+table3_entry_offset+0x4c,streamFile);
break;
default:
@ -219,7 +243,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
//;VGM_LOG("BNK: stream at %lx + %x\n", stream_offset, stream_size);
/* parse names */
switch(version) {
switch(sblk_version) {
//case 0x03: /* different format? */
//case 0x04: /* different format? */
case 0x09:
@ -271,9 +295,11 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
size_t extradata_size = 0, postdata_size = 0;
start_offset = data_offset + stream_offset;
switch(version) {
switch(sblk_version) {
case 0x01:
case 0x03:
case 0x04:
case 0x05:
channel_count = 1;
/* hack for PS3 files that use dual subsongs as stereo */
@ -382,6 +408,7 @@ VGMSTREAM * init_vgmstream_bnk_sony(STREAMFILE *streamFile) {
break;
default:
VGM_LOG("BNK: unknown data version %x\n", sblk_version);
goto fail;
}

View File

@ -1,14 +1,18 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../util.h"
#include "bnsf_keys.h"
/* BNSF - Namco Bandai's Bandai Namco Sound Format/File [Tales of Graces (Wii), Tales of Berseria (PS4)] */
static void find_bnsf_key(g7221_codec_data *data, off_t start, STREAMFILE *sf, uint8_t *best_key);
/* BNSF - Bandai Namco Sound Format/File [Tales of Graces (Wii), Tales of Berseria (PS4)] */
VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset = 0, first_offset = 0x0C;
int loop_flag = 0, channel_count = 0, sample_rate;
int num_samples, loop_start = 0, loop_end = 0, loop_adjust, block_samples;
uint32_t codec, subcodec = 0;
uint32_t codec, flags = 0;
size_t bnsf_size, sdat_size, block_size;
off_t loop_chunk = 0, sfmt_chunk, sdat_chunk;
@ -19,11 +23,10 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
if (read_32bitBE(0,streamFile) != 0x424E5346) /* "BNSF" */
goto fail;
bnsf_size = read_32bitBE(0x04,streamFile);
codec = read_32bitBE(0x08,streamFile);
/* check file size (siren22 uses full size) */
bnsf_size = read_32bitBE(0x04,streamFile);
if (bnsf_size + (codec == 0x49533232 ? 0x00 : 0x08) != get_streamfile_size(streamFile))
if (bnsf_size + (codec == 0x49533232 ? 0x00 : 0x08) != get_streamfile_size(streamFile)) /* IS22 uses full size */
goto fail;
if (!find_chunk_be(streamFile, 0x73666d74,first_offset,0, &sfmt_chunk,NULL)) /* "sfmt" */
@ -32,28 +35,27 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
goto fail;
if ( find_chunk_be(streamFile, 0x6C6F6F70,first_offset,0, &loop_chunk,NULL)) { /* "loop" */
loop_flag = 1;
loop_start = read_32bitBE(loop_chunk+0x00, streamFile); /* block-aligned */
loop_start = read_32bitBE(loop_chunk+0x00,streamFile); /* block-aligned */
loop_end = read_32bitBE(loop_chunk+0x04,streamFile) + 1;
}
subcodec = read_16bitBE(sfmt_chunk+0x00,streamFile);
flags = read_16bitBE(sfmt_chunk+0x00,streamFile);
channel_count = read_16bitBE(sfmt_chunk+0x02,streamFile);
sample_rate = read_32bitBE(sfmt_chunk+0x04,streamFile);
num_samples = read_32bitBE(sfmt_chunk+0x08,streamFile);
loop_adjust = read_32bitBE(sfmt_chunk+0x0c,streamFile); /* 0 if no looping */
loop_adjust = read_32bitBE(sfmt_chunk+0x0c,streamFile); /* 0 when no loop */
block_size = read_16bitBE(sfmt_chunk+0x10,streamFile);
block_samples = read_16bitBE(sfmt_chunk+0x12,streamFile);
//max_samples = sdat_size / block_size * block_samples /* num_samples is smaller */
//max_samples = sdat_size / block_size * block_samples;
start_offset = sdat_chunk;
/* without adjust some files have a small pop when looping */
if (loop_adjust >= block_samples)
goto fail; /* shouldn't happen, plus decoder can't handle it */
if (loop_adjust >= block_samples) /* decoder can't handle this */
goto fail;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate;
@ -63,24 +65,38 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
vgmstream->meta_type = meta_BNSF;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = block_size/channel_count;
/* Late IS14 voice/ambient files use subcodec 0x02 [Tales of Zestiria (PS3/PC), The Idolm@ster 2 (PS3)].
* Bitstream looks modified (most noticeable in silent frames), probably not encrypted, still 1ch frames */
if (subcodec != 0)
goto fail;
vgmstream->interleave_block_size = block_size / channel_count;
switch (codec) {
#ifdef VGM_USE_G7221
case 0x49533134: /* "IS14" */
case 0x49533134: /* "IS14" (interleaved Siren14) */
vgmstream->coding_type = coding_G7221C;
vgmstream->codec_data = init_g7221(vgmstream->channels, vgmstream->interleave_block_size);
if (!vgmstream->codec_data) goto fail;
/* get decryption key in .bnsfkey file or list, for later games' voices
* [The Idolm@ster 2 (PS3/X360), Tales of Zestiria (PS3/PC)] */
if (flags != 0) { /* only known value is 0x02 though */
size_t keysize;
uint8_t key[24] = {0}; /* keystring 0-padded to 192-bit */
keysize = read_key_file(key, sizeof(key), streamFile);
if (keysize <= 0 || keysize > sizeof(key)) {
find_bnsf_key(vgmstream->codec_data, start_offset, streamFile, key);
}
set_key_g7221(vgmstream->codec_data, key);
}
break;
#endif
#ifdef VGM_USE_G719
case 0x49533232: /* "IS22" */
case 0x49533232: /* "IS22" (interleaved Siren22) */
/* same encryption as IS14 but not seen */
if (flags != 0)
goto fail;
vgmstream->coding_type = coding_G719;
vgmstream->codec_data = init_g719(vgmstream->channels, vgmstream->interleave_block_size);
if (!vgmstream->codec_data) goto fail;
@ -100,3 +116,41 @@ fail:
close_vgmstream(vgmstream);
return NULL;
}
static void find_bnsf_key(g7221_codec_data* data, off_t start, STREAMFILE* sf, uint8_t* best_key) {
const size_t keys_length = sizeof(s14key_list) / sizeof(bnsfkey_info);
int score, best_score = -1;
int i;
uint8_t tmpkey[24];
for (i = 0; i < keys_length; i++) {
const char* key = s14key_list[i].key;
int keylen = strlen(key);
if (keylen > sizeof(tmpkey))
continue;
memcpy(tmpkey, key, keylen);
memset(tmpkey + keylen, 0, sizeof(tmpkey) - keylen);
//;VGM_LOG("BNSF: test key=%.24s\n", tmpkey);
set_key_g7221(data, tmpkey);
score = test_key_g7221(data, start, sf);
if (score < 0) continue;
if (best_score <= 0 || (score < best_score && score > 0)) {
best_score = score;
memcpy(best_key, key, keylen);
memset(best_key + keylen, 0, sizeof(tmpkey) - keylen);
}
if (best_score == 1) {
break;
}
}
VGM_ASSERT(best_score > 0, "BNSF: best key=%.24s (score=%i)\n", best_key, best_score);
VGM_ASSERT(best_score < 0, "BNSF: key not found\n"); /* defaults to all 0s */
}

View File

@ -0,0 +1,16 @@
#ifndef _BNSF_KEYS_H_
#define _BNSF_KEYS_H_
typedef struct {
const char* key;
} bnsfkey_info;
/* Known keys, extracted from games' exe */
static const bnsfkey_info s14key_list[] = {
/* THE iDOLM@STER 2 (PS3/X360) */
{"haruka17imas"},
};
#endif/*_BNSF_KEYS_H_*/

View File

@ -1,29 +1,30 @@
#include "cri_utf.h"
/* possibly 3b+5b from clUTF decompilation */
#define COLUMN_BITMASK_STORAGE 0xf0
#define COLUMN_BITMASK_TYPE 0x0f
#define COLUMN_BITMASK_FLAG 0xf0
#define COLUMN_BITMASK_TYPE 0x0f
enum column_storage_t {
COLUMN_STORAGE_ZERO = 0x10,
COLUMN_STORAGE_CONSTANT = 0x30,
COLUMN_STORAGE_ROW = 0x50
//COLUMN_STORAGE_CONSTANT2 = 0x70 /* from vgmtoolbox */
enum columna_flag_t {
COLUMN_FLAG_NAME = 0x10,
COLUMN_FLAG_DEFAULT = 0x20,
COLUMN_FLAG_ROW = 0x40,
COLUMN_FLAG_UNDEFINED = 0x80 /* shouldn't exist */
};
enum column_type_t {
COLUMN_TYPE_SINT8 = 0x00,
COLUMN_TYPE_UINT8 = 0x01,
COLUMN_TYPE_SINT16 = 0x02,
COLUMN_TYPE_UINT16 = 0x03,
COLUMN_TYPE_SINT32 = 0x04,
COLUMN_TYPE_UINT32 = 0x05,
COLUMN_TYPE_SINT64 = 0x06,
//COLUMN_TYPE_UINT64 = 0x07,
COLUMN_TYPE_UINT8 = 0x00,
COLUMN_TYPE_SINT8 = 0x01,
COLUMN_TYPE_UINT16 = 0x02,
COLUMN_TYPE_SINT16 = 0x03,
COLUMN_TYPE_UINT32 = 0x04,
COLUMN_TYPE_SINT32 = 0x05,
COLUMN_TYPE_UINT64 = 0x06,
COLUMN_TYPE_SINT64 = 0x07,
COLUMN_TYPE_FLOAT = 0x08,
//COLUMN_TYPE_DOUBLE = 0x09,
COLUMN_TYPE_DOUBLE = 0x09,
COLUMN_TYPE_STRING = 0x0a,
COLUMN_TYPE_DATA = 0x0b
COLUMN_TYPE_VLDATA = 0x0b,
COLUMN_TYPE_UINT128 = 0x0c, /* for GUIDs */
COLUMN_TYPE_UNDEFINED = -1
};
typedef struct {
@ -44,6 +45,10 @@ typedef struct {
uint32_t offset;
uint32_t size;
} value_data;
//struct utf_u128_t {
// uint64_t hi;
// uint64_t lo;
//} value_u128;
const char *value_string;
} value;
} utf_result_t;
@ -63,7 +68,8 @@ struct utf_context {
uint16_t row_width;
uint32_t rows;
struct utf_column_t {
uint8_t flags;
uint8_t flag;
uint8_t type;
const char *name;
uint32_t offset;
} *schema;
@ -77,7 +83,7 @@ struct utf_context {
/* @UTF table context creation */
utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const char **p_row_name) {
utf_context* utf_open(STREAMFILE* sf, uint32_t table_offset, int* p_rows, const char** p_row_name) {
utf_context* utf = NULL;
@ -145,61 +151,75 @@ utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const
if (!utf->schema) goto fail;
for (i = 0; i < utf->columns; i++) {
uint8_t flags = read_u8(schema_offset + 0x00, sf);
uint8_t info = read_u8(schema_offset + 0x00, sf);
uint32_t name_offset = read_u32be(schema_offset + 0x01, sf);
if (name_offset > utf->strings_size)
goto fail;
utf->schema[i].flags = flags;
utf->schema[i].name = utf->string_table + name_offset;
schema_offset += 0x01 + 0x04;
switch (utf->schema[i].flags & COLUMN_BITMASK_TYPE) {
case COLUMN_TYPE_SINT8:
utf->schema[i].flag = info & COLUMN_BITMASK_FLAG;
utf->schema[i].type = info & COLUMN_BITMASK_TYPE;
utf->schema[i].name = NULL;
utf->schema[i].offset = 0;
/* known flags are name+default or name+row, but name+default+row is mentioned in VGMToolbox
* even though isn't possible in CRI's craft utils, and no name is apparently possible */
if ( (utf->schema[i].flag == 0) ||
!(utf->schema[i].flag & COLUMN_FLAG_NAME) ||
((utf->schema[i].flag & COLUMN_FLAG_DEFAULT) && (utf->schema[i].flag & COLUMN_FLAG_ROW)) ||
(utf->schema[i].flag & COLUMN_FLAG_UNDEFINED) ) {
VGM_LOG("@UTF: unknown column flag combo found\n");
goto fail;
}
switch (utf->schema[i].type) {
case COLUMN_TYPE_UINT8:
case COLUMN_TYPE_SINT8:
value_size = 0x01;
break;
case COLUMN_TYPE_SINT16:
case COLUMN_TYPE_UINT16:
case COLUMN_TYPE_SINT16:
value_size = 0x02;
break;
case COLUMN_TYPE_SINT32:
case COLUMN_TYPE_UINT32:
case COLUMN_TYPE_SINT32:
case COLUMN_TYPE_FLOAT:
case COLUMN_TYPE_STRING:
value_size = 0x04;
break;
case COLUMN_TYPE_UINT64:
case COLUMN_TYPE_SINT64:
//case COLUMN_TYPE_UINT64:
//case COLUMN_TYPE_DOUBLE:
case COLUMN_TYPE_DATA:
//case COLUMN_TYPE_DOUBLE:
case COLUMN_TYPE_VLDATA:
value_size = 0x08;
break;
//case COLUMN_TYPE_UINT128:
// value_size = 0x16;
default:
VGM_LOG("@UTF: unknown column type\n");
goto fail;
}
switch (utf->schema[i].flags & COLUMN_BITMASK_STORAGE) {
case COLUMN_STORAGE_ROW:
utf->schema[i].offset = column_offset;
column_offset += value_size;
break;
case COLUMN_STORAGE_CONSTANT:
//case COLUMN_STORAGE_CONSTANT2:
utf->schema[i].offset = schema_offset - (utf->table_offset + utf->schema_offset); /* relative to schema */
schema_offset += value_size;
break;
case COLUMN_STORAGE_ZERO:
utf->schema[i].offset = 0; /* ? */
break;
default:
VGM_LOG("@UTF: unknown column storage\n");
goto fail;
if (utf->schema[i].flag & COLUMN_FLAG_NAME) {
utf->schema[i].name = utf->string_table + name_offset;
}
if (utf->schema[i].flag & COLUMN_FLAG_DEFAULT) {
/* data is found relative to schema start */
utf->schema[i].offset = schema_offset - (utf->table_offset + utf->schema_offset);
schema_offset += value_size;
}
if (utf->schema[i].flag & COLUMN_FLAG_ROW) {
/* data is found relative to row start */
utf->schema[i].offset = column_offset;
column_offset += value_size;
}
}
}
/* next section is row and variable length data (pointed above) then end of table */
/* write info */
if (p_rows) *p_rows = utf->rows;
@ -212,7 +232,7 @@ fail:
return NULL;
}
void utf_close(utf_context *utf) {
void utf_close(utf_context* utf) {
if (!utf) return;
free(utf->string_table);
@ -221,7 +241,7 @@ void utf_close(utf_context *utf) {
}
static int utf_query(utf_context *utf, int row, const char *column, utf_result_t *result) {
static int utf_query(utf_context* utf, int row, const char* column, utf_result_t* result) {
int i;
@ -235,60 +255,54 @@ static int utf_query(utf_context *utf, int row, const char *column, utf_result_t
struct utf_column_t *col = &utf->schema[i];
uint32_t data_offset;
if (strcmp(col->name, column) != 0)
if (col->name == NULL || strcmp(col->name, column) != 0)
continue;
result->found = 1;
result->type = col->flags & COLUMN_BITMASK_TYPE;
result->type = col->type;
switch (col->flags & COLUMN_BITMASK_STORAGE) {
case COLUMN_STORAGE_ROW:
data_offset = utf->table_offset + utf->rows_offset + row * utf->row_width + col->offset;
break;
case COLUMN_STORAGE_CONSTANT:
//case COLUMN_STORAGE_CONSTANT2:
data_offset = utf->table_offset + utf->schema_offset + col->offset;
break;
case COLUMN_STORAGE_ZERO:
data_offset = 0;
memset(&result->value, 0, sizeof(result->value));
break;
default:
goto fail;
if (col->flag & COLUMN_FLAG_DEFAULT) {
data_offset = utf->table_offset + utf->schema_offset + col->offset;
}
else if (col->flag & COLUMN_FLAG_ROW) {
data_offset = utf->table_offset + utf->rows_offset + row * utf->row_width + col->offset;
}
else {
data_offset = 0;
}
/* ignore zero value */
if (!data_offset)
if (data_offset == 0) {
memset(&result->value, 0, sizeof(result->value)); /* just in case... */
break;
}
/* read row/constant value */
switch (col->flags & COLUMN_BITMASK_TYPE) {
case COLUMN_TYPE_SINT8:
result->value.value_s8 = read_s8(data_offset, utf->sf);
break;
switch (col->type) {
case COLUMN_TYPE_UINT8:
result->value.value_u8 = read_u8(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT16:
result->value.value_s16 = read_s16be(data_offset, utf->sf);
case COLUMN_TYPE_SINT8:
result->value.value_s8 = read_s8(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT16:
result->value.value_u16 = read_u16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT32:
result->value.value_s32 = read_s32be(data_offset, utf->sf);
case COLUMN_TYPE_SINT16:
result->value.value_s16 = read_s16be(data_offset, utf->sf);
break;
case COLUMN_TYPE_UINT32:
result->value.value_u32 = read_u32be(data_offset, utf->sf);
break;
case COLUMN_TYPE_SINT64:
result->value.value_s64 = read_s64be(data_offset, utf->sf);
case COLUMN_TYPE_SINT32:
result->value.value_s32 = read_s32be(data_offset, utf->sf);
break;
#if 0
case COLUMN_TYPE_UINT64:
result->value.value_u64 = read_u64be(data_offset, utf->sf);
break;
#endif
case COLUMN_TYPE_SINT64:
result->value.value_s64 = read_s64be(data_offset, utf->sf);
break;
case COLUMN_TYPE_FLOAT: {
result->value.value_float = read_f32be(data_offset, utf->sf);
break;
@ -307,11 +321,17 @@ static int utf_query(utf_context *utf, int row, const char *column, utf_result_t
break;
}
case COLUMN_TYPE_DATA:
case COLUMN_TYPE_VLDATA:
result->value.value_data.offset = read_u32be(data_offset + 0x00, utf->sf);
result->value.value_data.size = read_u32be(data_offset + 0x04, utf->sf);
break;
#if 0
case COLUMN_TYPE_UINT128: {
result->value.value_u128.hi = read_u64be(data_offset + 0x00, utf->sf);
result->value.value_u128.lo = read_u64be(data_offset + 0x08, utf->sf);
break;
}
#endif
default:
goto fail;
}
@ -324,7 +344,7 @@ fail:
return 0;
}
static int utf_query_value(utf_context *utf, int row, const char *column, void *value, enum column_type_t type) {
static int utf_query_value(utf_context* utf, int row, const char* column, void* value, enum column_type_t type) {
utf_result_t result = {0};
int valid;
@ -333,14 +353,14 @@ static int utf_query_value(utf_context *utf, int row, const char *column, void *
return 0;
switch(result.type) {
case COLUMN_TYPE_SINT8: (*(int8_t*)value) = result.value.value_s8; break;
case COLUMN_TYPE_UINT8: (*(uint8_t*)value) = result.value.value_u8; break;
case COLUMN_TYPE_SINT16: (*(int16_t*)value) = result.value.value_s16; break;
case COLUMN_TYPE_SINT8: (*(int8_t*)value) = result.value.value_s8; break;
case COLUMN_TYPE_UINT16: (*(uint16_t*)value) = result.value.value_u16; break;
case COLUMN_TYPE_SINT32: (*(int32_t*)value) = result.value.value_s32; break;
case COLUMN_TYPE_SINT16: (*(int16_t*)value) = result.value.value_s16; break;
case COLUMN_TYPE_UINT32: (*(uint32_t*)value) = result.value.value_u32; break;
case COLUMN_TYPE_SINT32: (*(int32_t*)value) = result.value.value_s32; break;
case COLUMN_TYPE_UINT64: (*(uint64_t*)value) = result.value.value_u64; break;
case COLUMN_TYPE_SINT64: (*(int64_t*)value) = result.value.value_s64; break;
//case COLUMN_TYPE_UINT64: (*(uint64_t*)value) = result.value.value_u64; break;
case COLUMN_TYPE_STRING: (*(const char**)value) = result.value.value_string; break;
default:
return 0;
@ -349,25 +369,25 @@ static int utf_query_value(utf_context *utf, int row, const char *column, void *
return 1;
}
int utf_query_s8(utf_context *utf, int row, const char *column, int8_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT8);
int utf_query_u8(utf_context* utf, int row, const char* column, uint8_t* value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_UINT8);
}
int utf_query_s16(utf_context *utf, int row, const char *column, int16_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT16);
int utf_query_u16(utf_context* utf, int row, const char* column, uint16_t* value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_UINT16);
}
int utf_query_s32(utf_context *utf, int row, const char *column, int32_t *value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_SINT32);
int utf_query_u32(utf_context* utf, int row, const char* column, uint32_t* value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_UINT32);
}
int utf_query_string(utf_context *utf, int row, const char *column, const char **value) {
int utf_query_string(utf_context* utf, int row, const char* column, const char** value) {
return utf_query_value(utf, row, column, (void*)value, COLUMN_TYPE_STRING);
}
int utf_query_data(utf_context *utf, int row, const char *column, uint32_t *p_offset, uint32_t *p_size) {
int utf_query_data(utf_context* utf, int row, const char* column, uint32_t* p_offset, uint32_t* p_size) {
utf_result_t result = {0};
int valid;
valid = utf_query(utf, row, column, &result);
if (!valid || !result.found || result.type != COLUMN_TYPE_DATA)
if (!valid || !result.found || result.type != COLUMN_TYPE_VLDATA)
return 0;
if (p_offset) *p_offset = utf->table_offset + utf->data_offset + result.value.value_data.offset;

View File

@ -3,13 +3,14 @@
#include "../streamfile.h"
/* CRI @UTF (Universal Table Format?) is a generic database-like table made of
* rows/columns that contain numbers/strings/binary data, which also can be other tables.
/* CRI @UTF (Universal Table Format?) is a generic database-like table made of rows (called records)
* and columns (called fields) that contain numbers/strings/binary data, which also can be other tables.
*
* A table starts with "@UTF" and defines some values (row/data/string offsets, counts, etc)
* then DB schema (columns type+name), then rows, string table and binary data. Formats using @UTF
* then DB schema (column type+name), then rows, string table and binary data. Formats using @UTF
* store and read data by row number + column name. Being a generic table with no fixed schema
* CRI uses it for different purposes (.acf: cues, .cpk: files, .aax: bgm, .usm: video, etc).
* CRI uses it for different purposes (.acf: cues, .cpk: files, .aax: bgm, .usm: video, etc),
* and seems used to serialize classes/objects too.
*
* (adapted from hcs's code to do multiple querys in the same table)
*/
@ -20,13 +21,13 @@
typedef struct utf_context utf_context;
/* open a CRI UTF table at offset, returning table name and rows. Passed streamfile is used internally for next calls */
utf_context* utf_open(STREAMFILE *sf, uint32_t table_offset, int *p_rows, const char **p_row_name);
void utf_close(utf_context *utf);
utf_context* utf_open(STREAMFILE* sf, uint32_t table_offset, int* p_rows, const char** p_row_name);
void utf_close(utf_context* utf);
/* query calls */
int utf_query_s8(utf_context *utf, int row, const char *column, int8_t *value);
int utf_query_s16(utf_context *utf, int row, const char *column, int16_t *value);
int utf_query_s32(utf_context *utf, int row, const char *column, int32_t *value);
int utf_query_string(utf_context *utf, int row, const char *column, const char **value);
int utf_query_data(utf_context *utf, int row, const char *column, uint32_t *offset, uint32_t *size);
int utf_query_u8(utf_context* utf, int row, const char* column, uint8_t* value);
int utf_query_u16(utf_context* utf, int row, const char* column, uint16_t* value);
int utf_query_u32(utf_context* utf, int row, const char* column, uint32_t* value);
int utf_query_string(utf_context* utf, int row, const char* column, const char** value);
int utf_query_data(utf_context* utf, int row, const char* column, uint32_t* offset, uint32_t* size);
#endif /* _CRI_UTF_H_ */

View File

@ -12,7 +12,7 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
utf_context *utf = NULL;
utf_context *utf_sdl = NULL;
int total_subsongs, target_subsong = streamFile->stream_index;
int8_t fmt = 0;
uint8_t fmt = 0;
const char *stream_name;
@ -31,7 +31,7 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
const char *sdl_name;
uint32_t sdl_offset, sdl_size, offset, size;
uint32_t table_offset = 0x00;
int8_t ttype;
uint8_t ttype;
int found = 0;
@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
/* get SOUND_ELEMENT and table */
if (!utf_query_string(utf, sdl_row, "name", &row_name) || strcmp(row_name, "SOUND_ELEMENT") != 0)
goto fail;
if (!utf_query_s8(utf, sdl_row, "ttype", &ttype) || ttype != 4)
if (!utf_query_u8(utf, sdl_row, "ttype", &ttype) || ttype != 4)
goto fail;
if (!utf_query_data(utf, sdl_row, "utf", &sdl_offset, &sdl_size))
goto fail;
@ -71,13 +71,13 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
/* get target subsong */
for (i = 0; i < sdl_rows; i++) {
int8_t stmflg;
uint8_t stream_flag;
if (!utf_query_s8(utf_sdl, i, "stmflg", &stmflg))
if (!utf_query_u8(utf_sdl, i, "stmflg", &stream_flag))
goto fail;
/* only internal data for now (when 1 this refers to a .cpk subfile probably using "name", has size 0) */
if (stmflg)
if (stream_flag)
continue;
total_subsongs++;
@ -87,9 +87,8 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
goto fail;
if (!utf_query_data(utf_sdl, i, "data", &offset, &size))
goto fail;
if (!utf_query_s8(utf_sdl, i, "fmt", &fmt))
if (!utf_query_u8(utf_sdl, i, "fmt", &fmt))
goto fail;
VGM_LOG("fmt=%i\n", fmt);
/* also nch/sfreq/nsmpl info */
found = 1;
@ -98,7 +97,7 @@ VGMSTREAM * init_vgmstream_csb(STREAMFILE *streamFile) {
if (!found) goto fail;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
VGM_LOG("5: %x, %x\n", sdl_offset, offset);
subfile_offset = /*sdl_offset +*/ offset;
subfile_size = size;
@ -107,14 +106,12 @@ VGM_LOG("5: %x, %x\n", sdl_offset, offset);
goto fail;
}
;VGM_LOG("CSB: subfile offset=%lx + %x\n", subfile_offset, subfile_size);
//;VGM_LOG("CSB: subfile offset=%lx + %x\n", subfile_offset, subfile_size);
temp_sf = setup_subfile_streamfile(streamFile, subfile_offset, subfile_size, "aax");
if (!temp_sf) goto fail;
VGM_LOG("7: %i\n", fmt);
switch(fmt) {
case 0: /* AAX */
case 6: /* HCA */
@ -132,8 +129,6 @@ VGM_LOG("5: %x, %x\n", sdl_offset, offset);
goto fail;
}
VGM_LOG("8\n");
vgmstream->num_streams = total_subsongs;
strncpy(vgmstream->stream_name, stream_name, STREAM_NAME_SIZE-1);

View File

@ -0,0 +1,181 @@
#include "deblock_streamfile.h"
//todo move to utils or something
static void block_callback_default(STREAMFILE *sf, deblock_io_data *data) {
data->block_size = data->cfg.chunk_size;
data->skip_size = data->cfg.skip_size;
data->data_size = data->block_size - data->skip_size;
//;VGM_LOG("DEBLOCK: of=%lx, bs=%lx, ss=%lx, ds=%lx\n", data->physical_offset, data->block_size, data->skip_size, data->data_size);
}
static size_t deblock_io_read(STREAMFILE *sf, uint8_t *dest, off_t offset, size_t length, deblock_io_data* data) {
size_t total_read = 0;
/* re-start when previous offset (can't map logical<>physical offsets) */
if (data->logical_offset < 0 || offset < data->logical_offset) {
;VGM_LOG("DEBLOCK: restart offset=%lx + %x, po=%lx, lo=%lx\n", offset, length, data->physical_offset, data->logical_offset);
data->physical_offset = data->cfg.stream_start;
data->logical_offset = 0x00;
data->block_size = 0;
data->data_size = 0;
data->skip_size = 0;
data->step_count = data->cfg.step_start;
/*
data->read_count = data->cfg.read_count;
*/
}
/* read blocks */
while (length > 0) {
/* ignore EOF */
if (offset < 0 ||
(data->physical_offset >= data->cfg.stream_start + data->physical_size) ||
(data->logical_size > 0 && offset > data->logical_size)) {
break;
}
/* process new block */
if (data->data_size <= 0) {
data->cfg.block_callback(sf, data);
if (data->block_size <= 0) {
VGM_LOG("DEBLOCK: block size not set at %lx\n", data->physical_offset);
break;
}
}
#if 1
if (data->step_count > 0) {
data->step_count--;
data->physical_offset += data->block_size;
data->data_size = 0;
continue;
}
#else
/* handle blocks from multiple streams */
{
if (data->step_count > 0) {
data->step_count--;
data->data_size = 0; /* step over this block */
}
else if (data->read_count) {//must detect when blocks has been read
data->read_count--; /* read this block */
/* reset */
if (data->step_count == 0 && data->read_count == 0) {
data->step_count = data->cfg.step_count;
data->read_count = data->cfg.read_count;
}
}
}
#endif
/* move to next block */
if (data->data_size == 0 || offset >= data->logical_offset + data->data_size) {
data->physical_offset += data->block_size;
data->logical_offset += data->data_size;
data->data_size = 0;
data->step_count = data->cfg.step_count;
//VGM_LOG("ignore at %lx + %lx, skips=%i, reads=%i\n", data->physical_offset, data->block_size, data->step_count, data->read_count);
continue;
}
//VGM_LOG("accept at %lx + %lx, skips=%i, reads=%i\n", data->physical_offset, data->block_size, data->step_count, data->read_count);
/* read block data */
{
size_t bytes_consumed, bytes_done, to_read;
bytes_consumed = offset - data->logical_offset;
to_read = data->data_size - bytes_consumed;
if (to_read > length)
to_read = length;
bytes_done = read_streamfile(dest, data->physical_offset + data->skip_size + bytes_consumed, to_read, sf);
total_read += bytes_done;
dest += bytes_done;
offset += bytes_done;
length -= bytes_done;
if (bytes_done != to_read || bytes_done == 0) {
break; /* error/EOF */
}
}
}
return total_read;
}
static size_t deblock_io_size(STREAMFILE *streamfile, deblock_io_data* data) {
uint8_t buf[0x04];
if (data->logical_size)
return data->logical_size;
if (data->cfg.logical_size) {
data->logical_size = data->cfg.logical_size;
return data->logical_size;
}
/* force a fake read at max offset, to get max logical_offset (will be reset next read) */
deblock_io_read(streamfile, buf, 0x7FFFFFFF, 1, data);
data->logical_size = data->logical_offset;
//todo tests:
//if (logical_size > max_physical_offset)
// return 0;
//if (logical_size != data->stream_size)
// return 0;
return data->logical_size;
}
/* generic "de-blocker" helper for streams divided in blocks that have weird interleaves, their
* decoder can't easily use blocked layout, or some other weird feature. It "filters" data so
* reader only sees clean data without blocks. Must pass setup config and a callback that sets
* sizes of a single block. */
STREAMFILE* open_io_deblock_streamfile_f(STREAMFILE *sf, deblock_config_t *cfg) {
STREAMFILE *new_sf = NULL;
deblock_io_data io_data = {0};
/* prepare data */
io_data.cfg = *cfg; /* memcpy */
if (io_data.cfg.block_callback == NULL)
io_data.cfg.block_callback = block_callback_default;
if (io_data.cfg.stream_start < 0)
goto fail;
if (io_data.cfg.step_start < 0 || io_data.cfg.step_count < 0)
goto fail;
if (io_data.cfg.step_count > 0) {
io_data.cfg.step_count--;
}
/*
if (io_data.cfg.read_count == 0)
io_data.cfg.read_count = 1;
*/
io_data.physical_size = io_data.cfg.stream_size;
if (io_data.physical_size > get_streamfile_size(sf) + io_data.cfg.stream_start || io_data.physical_size == 0)
io_data.physical_size = get_streamfile_size(sf) - io_data.cfg.stream_start;
io_data.physical_end = io_data.cfg.stream_start + io_data.physical_size;
io_data.logical_offset = -1; /* read reset */
//TODO: other validations
/* setup subfile */
new_sf = open_io_streamfile_f(sf, &io_data, sizeof(deblock_io_data), deblock_io_read, deblock_io_size);
return new_sf;
fail:
VGM_LOG("DEBLOCK: bad init\n");
close_streamfile(sf);
return NULL;
}

View File

@ -0,0 +1,61 @@
#ifndef _DEBLOCK_STREAMFILE_H_
#define _DEBLOCK_STREAMFILE_H_
#include "../streamfile.h"
typedef struct deblock_config_t deblock_config_t;
typedef struct deblock_io_data deblock_io_data;
struct deblock_config_t {
/* config (all optional) */
size_t logical_size; /* pre-calculated size for performance (otherwise has to read the whole thing) */
off_t stream_start; /* data start */
size_t stream_size; /* data max */
size_t chunk_size; /* some size like a constant interleave */
size_t frame_size; /* some other size */
size_t skip_size; /* same */
int codec; /* codec or type variations */
int channels;
int big_endian;
uint32_t config; /* some non-standard config value */
/* read=blocks from out stream to read) and "steps" (blocks from other streams to skip) */
int step_start; /* initial step_count at stream start (often 0) */
int step_count; /* number of blocks to step over from other streams */
//int read_count; /* number of blocks to read from this stream, after steps */
size_t track_size;
int track_number;
int track_count;
uint32_t track_type;
size_t interleave_count;
size_t interleave_last_count;
/* callback that setups deblock_io_data state, normally block_size and data_size */
void (*block_callback)(STREAMFILE *sf, deblock_io_data *data);
} ;
struct deblock_io_data {
/* initial config */
deblock_config_t cfg;
/* state */
off_t logical_offset; /* fake deblocked offset */
off_t physical_offset; /* actual file offset */
off_t block_size; /* current block (added to physical offset) */
off_t skip_size; /* data to skip from block start to reach data (like a header) */
off_t data_size; /* usable data in a block (added to logical offset) */
int step_count; /* number of blocks to step over */
//int read_count; /* number of blocks to read */
size_t logical_size;
size_t physical_size;
off_t physical_end;
};
STREAMFILE* open_io_deblock_streamfile_f(STREAMFILE *sf, deblock_config_t *cfg);
#endif /* _DEBLOCK_STREAMFILE_H_ */

View File

@ -39,7 +39,7 @@ static VGMSTREAM *parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16
VGMSTREAM * init_vgmstream_gin_header(STREAMFILE *streamFile, off_t offset);
/* .SNR+SNS - from EA latest games (~2008-2013), v0 header */
/* .SNR+SNS - from EA latest games (~2005-2010), v0 header */
VGMSTREAM * init_vgmstream_ea_snr_sns(STREAMFILE * streamFile) {
/* check extension, case insensitive */
if (!check_extensions(streamFile,"snr"))
@ -51,7 +51,7 @@ fail:
return NULL;
}
/* .SPS - from EA latest games (~2014), v1 header */
/* .SPS - from EA latest games (~2010~present), v1 header */
VGMSTREAM * init_vgmstream_ea_sps(STREAMFILE * streamFile) {
/* check extension, case insensitive */
if (!check_extensions(streamFile,"sps"))
@ -1262,7 +1262,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
#endif
#ifdef VGM_USE_FFMPEG
case EAAC_CODEC_EAOPUS: { /* EAOpus (unknown FourCC) [FIFA 17 (PC), FIFA 19 (Switch)]*/
case EAAC_CODEC_EAOPUS: { /* "Eop0"? : EAOpus [FIFA 17 (PC), FIFA 19 (Switch)]*/
vgmstream->layout_data = build_layered_eaaudiocore(streamFile, &eaac, 0x00);
if (!vgmstream->layout_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
@ -1556,6 +1556,7 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_
uint8_t buf[0x100];
int bytes, block_size, block_count;
size_t stream_size;
int is_xma1;
temp_sf = setup_eaac_audio_streamfile(sf_data, eaac->version, eaac->codec, eaac->streamed,i,layers, start_offset);
if (!temp_sf) goto fail;
@ -1564,7 +1565,14 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_
block_size = 0x10000; /* unused */
block_count = stream_size / block_size + (stream_size % block_size ? 1 : 0);
bytes = ffmpeg_make_riff_xma2(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, block_count, block_size);
/* EA adopted XMA2 when it appeared around 2006, but detection isn't so easy
* (SNS with XMA2 do exist). Decoder should work when playing XMA1 as XMA2, but
* the other way around can cause issues, so it's safer to just use XMA2. */
is_xma1 = 0; //eaac->version == EAAC_VERSION_V0; /* approximate */
if (is_xma1)
bytes = ffmpeg_make_riff_xma1(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0);
else
bytes = ffmpeg_make_riff_xma2(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, block_count, block_size);
data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, 0x00, stream_size);
if (!data->layers[i]->codec_data) goto fail;

Some files were not shown because too many files have changed in this diff Show More