Created
August 1, 2020 21:58
-
-
Save grechnik/35249daf34574e420404d5d1bdbcfe90 to your computer and use it in GitHub Desktop.
call bink2w32.dll to extract the raw sound
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
typedef void* (__stdcall *BinkOpen_t)(const char*, unsigned); | |
typedef void (__stdcall *BinkNextFrame_t)(void*); | |
typedef void (__stdcall *BinkClose_t)(void*); | |
typedef int (__stdcall *BinkSetVideoOnOff_t)(void*, int); | |
typedef void* (__stdcall *BinkOpenTrack_t)(void*, unsigned); | |
typedef void (__stdcall *BinkCloseTrack_t)(void*); | |
typedef unsigned (__stdcall *BinkGetTrackData_t)(void*, void*); | |
typedef void (__stdcall *BinkSetSoundTrack_t)(unsigned, unsigned*); | |
int main(int argc, const char* argv[]) | |
{ | |
if (argc != 3) { | |
printf("Usage: extract_pcm <input.bk2> <output.pcm>\n"); | |
return 1; | |
} | |
HANDLE bink2w32 = LoadLibrary(TEXT("bink2w32.dll")); | |
if (!bink2w32) { | |
printf("failed to load bink2w32.dll\n"); | |
return 1; | |
} | |
BinkOpen_t BinkOpen = (BinkOpen_t)GetProcAddress(bink2w32, "_BinkOpen@8"); | |
BinkNextFrame_t BinkNextFrame = (BinkNextFrame_t)GetProcAddress(bink2w32, "_BinkNextFrame@4"); | |
BinkClose_t BinkClose = (BinkClose_t)GetProcAddress(bink2w32, "_BinkClose@4"); | |
BinkSetVideoOnOff_t BinkSetVideoOnOff = (BinkSetVideoOnOff_t)GetProcAddress(bink2w32, "_BinkSetVideoOnOff@8"); | |
BinkOpenTrack_t BinkOpenTrack = (BinkOpenTrack_t)GetProcAddress(bink2w32, "_BinkOpenTrack@8"); | |
BinkCloseTrack_t BinkCloseTrack = (BinkCloseTrack_t)GetProcAddress(bink2w32, "_BinkCloseTrack@4"); | |
BinkGetTrackData_t BinkGetTrackData = (BinkGetTrackData_t)GetProcAddress(bink2w32, "_BinkGetTrackData@8"); | |
BinkSetSoundTrack_t BinkSetSoundTrack = (BinkSetSoundTrack_t)GetProcAddress(bink2w32, "_BinkSetSoundTrack@8"); | |
if (!BinkOpen || !BinkNextFrame || !BinkClose || !BinkSetVideoOnOff || !BinkOpenTrack || !BinkCloseTrack || !BinkGetTrackData || !BinkSetSoundTrack) { | |
printf("required functions not found\n"); | |
FreeLibrary(bink2w32); | |
return 1; | |
} | |
BinkSetSoundTrack(0, NULL); | |
// 0x400 = don't allocate frame buffers, we're not interested in video anyway | |
// 0x4000 = use data from BinkSetSoundTrack | |
void* bink = BinkOpen(argv[1], 0x4400); | |
if (!bink) { | |
printf("failed to open %s\n", argv[1]); | |
FreeLibrary(bink2w32); | |
return 1; | |
} | |
BinkSetVideoOnOff(bink, 0); | |
void* track = BinkOpenTrack(bink, 0); | |
if (!track) { | |
printf("failed to open track\n"); | |
BinkClose(bink); | |
FreeLibrary(bink2w32); | |
return 1; | |
} | |
unsigned largestAudio = ((unsigned*)track)[3]; | |
void* pcm = malloc(largestAudio + 0x20); | |
if (!pcm) { | |
printf("failed to allocate memory\n"); | |
BinkCloseTrack(track); | |
BinkClose(bink); | |
FreeLibrary(bink2w32); | |
return 1; | |
} | |
void* pcm_aligned = (char*)pcm + (-(unsigned)pcm & 0x1F); | |
FILE* out = fopen(argv[2], "wb"); | |
if (!out) { | |
printf("failed to create %s\n", argv[2]); | |
free(pcm); | |
BinkCloseTrack(track); | |
BinkClose(bink); | |
FreeLibrary(bink2w32); | |
return 1; | |
} | |
int ret = 0; | |
for (;;) { | |
unsigned n = BinkGetTrackData(track, pcm_aligned); | |
if (n > largestAudio) printf("internal error\n"); | |
if (fwrite(pcm_aligned, 1, n, out) != n) { | |
printf("write error\n"); | |
ret = 1; | |
break; | |
} | |
if (((int*)bink)[2] == ((int*)bink)[3]) | |
break; | |
BinkNextFrame(bink); | |
} | |
if (fclose(out)) { | |
if (!ret) { | |
printf("write error\n"); | |
ret = 1; | |
} | |
} | |
if (!ret) | |
printf("ok\n"); | |
free(pcm); | |
BinkCloseTrack(track); | |
BinkClose(bink); | |
FreeLibrary(bink2w32); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment