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
+46 -30
View File
@@ -23,12 +23,14 @@ enum pcm_resampler : int8_t
};
typedef enum pcm_resampler pcm_resampler_t;
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 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);
static BmswConfigInit_t BmswConfigInit;
BmswEnumValidSoundbanksAddr_t BmswEnumValidSoundbanksAddr;
static BmswSymlink_t BmswSymlink;
static BmswTranscoderEnumValidSoundbanksAddr_t BmswTranscoderEnumValidSoundbanksAddr;
static BmswTranscoderResampler_t BmswTranscoderResampler;
static BmswTranscoderAsfToWav_t BmswTranscoderAsfToWav;
static HMODULE bmsw_ = nullptr;
bool init()
@@ -41,10 +43,22 @@ bool init()
if ((bmsw_ = libutils::try_library(MODULE_PATH / "bmsound-wine.dll")))
{
BmswConfigInit = (BmswConfigInit_t) GetProcAddress(bmsw_, "BmswConfigInit");
BmswEnumValidSoundbanksAddr = (BmswEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswEnumValidSoundbanksAddr");
BmswSymlink = (BmswSymlink_t) GetProcAddress(bmsw_, "BmswSymlink");
BmswTranscoderEnumValidSoundbanksAddr = (BmswTranscoderEnumValidSoundbanksAddr_t) GetProcAddress(bmsw_, "BmswTranscoderEnumValidSoundbanksAddr");
BmswTranscoderResampler = (BmswTranscoderResampler_t) GetProcAddress(bmsw_, "BmswTranscoderResampler");
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
BmswConfigInit("prop/linux.json");
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_s3p snd_s3p;
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
{
@@ -693,7 +707,7 @@ static struct offset_t
intptr_t RD_05d_c_s3p; // %05d/%05d%c.s3p
intptr_t RD_05d_2dx; // %05d/%05d.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_artistl;
intptr_t DAT_song_id;
@@ -702,8 +716,8 @@ static struct offset_t
} offset_;
snd_bank *snd_bank::cache_ = nullptr;
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)
static BmsbEnumValidSoundbanks_t BmsbEnumValidSoundbanks;
avcodec::pcm_resampler_t snd_bank::resampler_ = avcodec::bmswac_resampler_s16;
static EnumValidSoundbanks_t EnumValidSoundbanks;
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
@@ -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..");
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"))
{
@@ -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", "Processing completed");
*((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;
return r;
}
@@ -854,8 +868,8 @@ public:
}
// Caching and intermediate 2dx storage detection
BmsbEnumValidSoundbanks_t t = BmsbEnumValidSoundbanks;
BmsbEnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; };
EnumValidSoundbanks_t t = EnumValidSoundbanks;
EnumValidSoundbanks = [](void *, int32_t, int32_t) -> void * { return nullptr; };
char *tmp = (char *) malloc(0x3b8 + strlen("00000000") + 1);
int arr[6] = {25073, 24016, 26057, 25073, 26087, 29095};
strcpy(tmp, "SJISTITLE");
@@ -868,7 +882,7 @@ public:
}
free(tmp);
BmsbEnumValidSoundbanks = t;
EnumValidSoundbanks = t;
snd_bank::flush_cache();
mf_broken::deinit();
}
@@ -913,42 +927,44 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
switch (to_hash(ext))
{
case to_hash("2018091900"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x1170b0;
break;
case to_hash("2019090200"):
case to_hash("2019100700"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x37a540;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x37a540;
break;
case to_hash("2020092900"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x5ac460;
break;
case to_hash("2021083000"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766bc0;
break;
case to_hash("2021091500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x766c60;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x766c60;
break;
case to_hash("2022082400"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x46e160;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x46e160;
break;
case to_hash("2023090500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0xafd780;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0xafd780;
break;
case to_hash("2024082600"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x8eae40;
break;
case to_hash("2025082500"):
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0;
offset_.TX_EnumValidSoundbanks = (intptr_t) hmodule + 0x969fb0;
break;
default:
offset_.TX_BmsbEnumValidSoundbanks = (intptr_t) hmodule + (int64_t) avcodec::BmswEnumValidSoundbanksAddr();
if (offset_.TX_BmsbEnumValidSoundbanks == (intptr_t) hmodule)
{
log_warning("hooks::soundbank", "Unsupported game version({}), skipping..", ext);
return;
}
log_info("hooks::soundbank", "Using user supplied offsets(0x{:x}), support may be limited..", offset_.TX_BmsbEnumValidSoundbanks);
break;
}
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);
return;
}
log_info("hooks::soundbank", "Hooking EnumValidSoundbanks(0x{:x})", offset_.TX_EnumValidSoundbanks);
log_info("hooks::soundbank", "Supported game version({})", ext);
// 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_2dx = replace_pattern(hmodule, "253035642F253035642E32647800", "73797374656D2F30302E32647800", 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..");
return;
@@ -964,7 +980,7 @@ void init(HINSTANCE hmodule, const char *model, const char *ext)
// Setup on_enum_valid_ksbd and optional tests
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_);
log_info("hooks::soundbank", "Soundbank preprocessor ready");