refactor/code: Change hooks::soundbank::snd_bank::resampler_ to user definable

> add support for `extra.sndb_resampler` in linux.json
> revert default resampler back to `bmswac_resampler_s16`
> backward support for 0.2.x
This commit is contained in:
[ ]
2025-12-22 22:50:50 +09:00
parent aa9ea9204b
commit f13c9d0e50
+43 -27
View File
@@ -23,12 +23,14 @@ enum pcm_resampler : int8_t
}; };
typedef enum pcm_resampler pcm_resampler_t; typedef enum pcm_resampler pcm_resampler_t;
typedef void (*BmswConfigInit_t)(const char *path); typedef void (*BmswConfigInit_t)(const char *path);
typedef uint64_t (*BmswEnumValidSoundbanksAddr_t)();
typedef int (*BmswSymlink_t)(const char *srcwpath, const char *dstwpath, int canonic); typedef int (*BmswSymlink_t)(const char *srcwpath, const char *dstwpath, int canonic);
typedef uint64_t (*BmswTranscoderEnumValidSoundbanksAddr_t)();
typedef pcm_resampler (*BmswTranscoderResampler_t)();
typedef int (*BmswTranscoderAsfToWav_t)(const uint8_t *srcasf, uint32_t srcsz, uint8_t **dstwav, uint32_t *dstsz, pcm_resampler_t resampler); typedef int (*BmswTranscoderAsfToWav_t)(const uint8_t *srcasf, uint32_t srcsz, uint8_t **dstwav, uint32_t *dstsz, pcm_resampler_t resampler);
static BmswConfigInit_t BmswConfigInit; static BmswConfigInit_t BmswConfigInit;
BmswEnumValidSoundbanksAddr_t BmswEnumValidSoundbanksAddr;
static BmswSymlink_t BmswSymlink; static BmswSymlink_t BmswSymlink;
static BmswTranscoderEnumValidSoundbanksAddr_t BmswTranscoderEnumValidSoundbanksAddr;
static BmswTranscoderResampler_t BmswTranscoderResampler;
static BmswTranscoderAsfToWav_t BmswTranscoderAsfToWav; static BmswTranscoderAsfToWav_t BmswTranscoderAsfToWav;
static HMODULE bmsw_ = nullptr; static HMODULE bmsw_ = nullptr;
bool init() bool init()
@@ -41,10 +43,22 @@ bool init()
if ((bmsw_ = libutils::try_library(MODULE_PATH / "bmsound-wine.dll"))) if ((bmsw_ = libutils::try_library(MODULE_PATH / "bmsound-wine.dll")))
{ {
BmswConfigInit = (BmswConfigInit_t) GetProcAddress(bmsw_, "BmswConfigInit"); BmswConfigInit = (BmswConfigInit_t) GetProcAddress(bmsw_, "BmswConfigInit");
BmswEnumValidSoundbanksAddr = (BmswEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswEnumValidSoundbanksAddr");
BmswSymlink = (BmswSymlink_t) GetProcAddress(bmsw_, "BmswSymlink"); BmswSymlink = (BmswSymlink_t) GetProcAddress(bmsw_, "BmswSymlink");
BmswTranscoderEnumValidSoundbanksAddr = (BmswTranscoderEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswTranscoderEnumValidSoundbanksAddr");
BmswTranscoderResampler = (BmswTranscoderResampler_t) GetProcAddress(bmsw_, "BmswTranscoderResampler");
BmswTranscoderAsfToWav = (BmswTranscoderAsfToWav_t) GetProcAddress(bmsw_, "BmswTranscoderAsfToWav"); BmswTranscoderAsfToWav = (BmswTranscoderAsfToWav_t) GetProcAddress(bmsw_, "BmswTranscoderAsfToWav");
//_REM: 0.2.x support (old behaviour), remove on 0.3.0
if (!BmswTranscoderEnumValidSoundbanksAddr || !BmswTranscoderResampler)
{
BmswTranscoderEnumValidSoundbanksAddr = (BmswTranscoderEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswEnumValidSoundbanksAddr");
BmswTranscoderResampler = []() -> pcm_resampler
{
return bmswac_resampler_s16_ad;
};
}
// Load config // Load config
BmswConfigInit("prop/linux.json"); BmswConfigInit("prop/linux.json");
return true; return true;
@@ -244,7 +258,7 @@ constexpr int operator "" _i(long double x) { return static_cast<int>(x); }
typedef struct snd_bank snd_bank; typedef struct snd_bank snd_bank;
typedef struct snd_s3p snd_s3p; typedef struct snd_s3p snd_s3p;
typedef struct snd_2dx snd_2dx; typedef struct snd_2dx snd_2dx;
typedef void *(*BmsbEnumValidSoundbanks_t)(void *, int32_t, int32_t); typedef void *(*EnumValidSoundbanks_t)(void *, int32_t, int32_t);
struct snd_2dx struct snd_2dx
{ {
@@ -693,7 +707,7 @@ static struct offset_t
intptr_t RD_05d_c_s3p; // %05d/%05d%c.s3p intptr_t RD_05d_c_s3p; // %05d/%05d%c.s3p
intptr_t RD_05d_2dx; // %05d/%05d.2dx intptr_t RD_05d_2dx; // %05d/%05d.2dx
intptr_t RD_05d_c_2dx; // %05d/%05d%c.2dx intptr_t RD_05d_c_2dx; // %05d/%05d%c.2dx
intptr_t TX_BmsbEnumValidSoundbanks; // enumerates above databank paths, simple exist check (lstat()/OPEN -> CLOSE_NOWRITE only) intptr_t TX_EnumValidSoundbanks; // enumerates above databank paths, simple exist check (lstat()/OPEN -> CLOSE_NOWRITE only)
intptr_t DAT_song_titlel; intptr_t DAT_song_titlel;
intptr_t DAT_song_artistl; intptr_t DAT_song_artistl;
intptr_t DAT_song_id; intptr_t DAT_song_id;
@@ -702,8 +716,8 @@ static struct offset_t
} offset_; } offset_;
snd_bank *snd_bank::cache_ = nullptr; snd_bank *snd_bank::cache_ = nullptr;
size_t snd_bank::cachesz_ = 0; size_t snd_bank::cachesz_ = 0;
avcodec::pcm_resampler_t snd_bank::resampler_ = avcodec::bmswac_resampler_s16_ad; //_REM: Temporary (revert to bmswac_resampler_s16) avcodec::pcm_resampler_t snd_bank::resampler_ = avcodec::bmswac_resampler_s16;
static BmsbEnumValidSoundbanks_t BmsbEnumValidSoundbanks; static EnumValidSoundbanks_t EnumValidSoundbanks;
void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2) void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2)
{ {
// Keysounds populated into CtrlSound::Bank[2][X] = [0:s3p][1:2dx][2:_pre.2dx], always uses lowest i databank for resource confirmed valid by this function // Keysounds populated into CtrlSound::Bank[2][X] = [0:s3p][1:2dx][2:_pre.2dx], always uses lowest i databank for resource confirmed valid by this function
@@ -729,7 +743,7 @@ void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2)
{ {
log_warning("hooks::soundbank", "soundbank::get_bank() was 0x0, this shouldn't happen.."); log_warning("hooks::soundbank", "soundbank::get_bank() was 0x0, this shouldn't happen..");
memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX); memcpy(reinterpret_cast<void *>(offset_.RD_05d_2dx), "%05d/%05d", SNDPATHFMTMAX);
return BmsbEnumValidSoundbanks(song, difficulty, unk2); return EnumValidSoundbanks(song, difficulty, unk2);
} }
else if (!snd_bank::has_format(keysounds->avspath, ".2dx")) else if (!snd_bank::has_format(keysounds->avspath, ".2dx"))
{ {
@@ -765,7 +779,7 @@ void *on_enum_valid_soundbanks(void *song, int32_t difficulty, int32_t unk2)
log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast<const char *>(offset_.RD_05d_2dx)); log_info("hooks::soundbank", "RD_05d_2dx set to '{}'", reinterpret_cast<const char *>(offset_.RD_05d_2dx));
log_info("hooks::soundbank", "Processing completed"); log_info("hooks::soundbank", "Processing completed");
*((char *) song + offset_.DAT_song_id + 8 + difficulty) = '0'; *((char *) song + offset_.DAT_song_id + 8 + difficulty) = '0';
void *r = BmsbEnumValidSoundbanks(song, difficulty, unk2); void *r = EnumValidSoundbanks(song, difficulty, unk2);
*((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix; *((char *) song + offset_.DAT_song_id + 8 + difficulty) = suffix;
return r; return r;
} }
@@ -854,8 +868,8 @@ public:
} }
// Caching and intermediate 2dx storage detection // Caching and intermediate 2dx storage detection
BmsbEnumValidSoundbanks_t t = BmsbEnumValidSoundbanks; EnumValidSoundbanks_t t = EnumValidSoundbanks;
BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; }; EnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; };
char *tmp = (char *) malloc(0x3b8 + strlen("00000000") + 1); char *tmp = (char *) malloc(0x3b8 + strlen("00000000") + 1);
int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095}; int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095};
strcpy(tmp, "SJISTITLE"); strcpy(tmp, "SJISTITLE");
@@ -868,7 +882,7 @@ public:
} }
free(tmp); free(tmp);
BmsbEnumValidSoundbanks = t; EnumValidSoundbanks = t;
snd_bank::flush_cache(); snd_bank::flush_cache();
mf_broken::deinit(); mf_broken::deinit();
} }
@@ -913,42 +927,44 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
switch (to_hash(ext)) switch (to_hash(ext))
{ {
case to_hash("2018091900"): case to_hash("2018091900"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0;
break; break;
case to_hash("2019090200"): case to_hash("2019090200"):
case to_hash("2019100700"): case to_hash("2019100700"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x37a540; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x37a540;
break; break;
case to_hash("2020092900"): case to_hash("2020092900"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460;
break; break;
case to_hash("2021083000"): case to_hash("2021083000"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0;
break; break;
case to_hash("2021091500"): case to_hash("2021091500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766c60; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766c60;
break; break;
case to_hash("2022082400"): case to_hash("2022082400"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x46e160; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x46e160;
break; break;
case to_hash("2023090500"): case to_hash("2023090500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0xafd780; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0xafd780;
break; break;
case to_hash("2024082600"): case to_hash("2024082600"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40;
break; break;
case to_hash("2025082500"): case to_hash("2025082500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0; offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0;
break; break;
default: default:
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + (int64_t) avcodec::BmswEnumValidSoundbanksAddr(); break;
if (offset_.TX_BmsbEnumValidSoundbanks == (intptr_t) hmodule) }
snd_bank::resampler_ = avcodec::BmswTranscoderResampler() == avcodec::bmswac_resampler_none ? snd_bank::resampler_ : avcodec::BmswTranscoderResampler();
offset_.TX_EnumValidSoundbanks = avcodec::BmswTranscoderEnumValidSoundbanksAddr() == 0x0 ? offset_.TX_EnumValidSoundbanks : (intptr_t) hmodule + (int64_t) avcodec::BmswTranscoderEnumValidSoundbanksAddr();
if (offset_.TX_EnumValidSoundbanks == (intptr_t) hmodule)
{ {
log_warning("hooks::soundbank", "Unsupported game version({}), skipping..", ext); log_warning("hooks::soundbank", "Unsupported game version({}), skipping..", ext);
return; return;
} }
log_info("hooks::soundbank", "Using user supplied offsets(0x{:x}), support may be limited..", offset_.TX_BmsbEnumValidSoundbanks); log_info("hooks::soundbank", "Hooking EnumValidSoundbanks(0x{:x})", offset_.TX_EnumValidSoundbanks);
}
log_info("hooks::soundbank", "Supported game version({})", ext); log_info("hooks::soundbank", "Supported game version({})", ext);
// Override .rdata // Override .rdata
@@ -956,7 +972,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
offset_.RD_05d_c_s3p = replace_pattern(hmodule, "253035642f2530356425632e73337000", "003035642f2530356425632e73337000", 0, 0); offset_.RD_05d_c_s3p = replace_pattern(hmodule, "253035642f2530356425632e73337000", "003035642f2530356425632e73337000", 0, 0);
offset_.RD_05d_2dx = replace_pattern(hmodule, "253035642F253035642E32647800", "73797374656D2F30302E32647800", 0, 0); offset_.RD_05d_2dx = replace_pattern(hmodule, "253035642F253035642E32647800", "73797374656D2F30302E32647800", 0, 0);
offset_.RD_05d_c_2dx = replace_pattern(hmodule, "253035642f2530356425632e32647800", "253035642f2530356425632e32647800", 0, 0); offset_.RD_05d_c_2dx = replace_pattern(hmodule, "253035642f2530356425632e32647800", "253035642f2530356425632e32647800", 0, 0);
if (!(offset_.TX_BmsbEnumValidSoundbanks && offset_.RD_05d_s3p && offset_.RD_05d_c_s3p && offset_.RD_05d_2dx && offset_.RD_05d_c_2dx)) if (!(offset_.TX_EnumValidSoundbanks && offset_.RD_05d_s3p && offset_.RD_05d_c_s3p && offset_.RD_05d_2dx && offset_.RD_05d_c_2dx))
{ {
log_warning("hooks::soundbank", "Could not find valid offsets, skipping.."); log_warning("hooks::soundbank", "Could not find valid offsets, skipping..");
return; return;
@@ -964,7 +980,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
// Setup on_enum_valid_ksbd and optional tests // Setup on_enum_valid_ksbd and optional tests
offset_.guard = new memutils::VProtectGuard((void *) offset_.RD_05d_2dx, SNDPATHFMTMAX); offset_.guard = new memutils::VProtectGuard((void *) offset_.RD_05d_2dx, SNDPATHFMTMAX);
detour::trampoline(reinterpret_cast<void *>(offset_.TX_BmsbEnumValidSoundbanks), reinterpret_cast<void *>(on_enum_valid_soundbanks), reinterpret_cast<void **>(&BmsbEnumValidSoundbanks)); detour::trampoline(reinterpret_cast<void *>(offset_.TX_EnumValidSoundbanks), reinterpret_cast<void *>(on_enum_valid_soundbanks), reinterpret_cast<void **>(&EnumValidSoundbanks));
hooks::devel::bind_routine(&tests_); hooks::devel::bind_routine(&tests_);
log_info("hooks::soundbank", "Soundbank preprocessor ready"); log_info("hooks::soundbank", "Soundbank preprocessor ready");