update DivaSound source

This commit is contained in:
somewhatlurker
2020-02-28 05:08:50 +11:00
parent 0159a7f367
commit 43012451e7
2 changed files with 170 additions and 71 deletions
@@ -32,18 +32,36 @@ void NopBytes(void* address, unsigned int num)
void resizeInternalBuffers(int frames)
{
float* oldMixbuffer = divaAudioMixCls->mixbuffer;
float* oldState2buffer = divaAudioMixCls->state2->buffer;
divaBufSizeInFrames = frames;
divaAudioMixCls->mixbuffer = (float*)malloc(divaBufSizeInFrames * 4 * 4);
divaAudioMixCls->mixbuffer_size = divaBufSizeInFrames * 4 * 4;
divaAudioMixCls->state2->buffer = (float*)malloc(divaBufSizeInFrames * 4 * 4);
divaAudioMixCls->state2->buffer_size = divaBufSizeInFrames * 4 * 4;
free(oldMixbuffer);
for (int i = 0; i < divaAudioMixCls->streamingChannels_len; i++)
{
float* oldChannelBuffer = divaAudioMixCls->streamingChannels[i].buffer;
if (oldChannelBuffer != nullptr)
{
if (divaAudioMixCls->streamingChannels[i].playing == 0)
{
divaAudioMixCls->streamingChannels[i].buffer = (float*)malloc(divaBufSizeInFrames * 4 * 4);
divaAudioMixCls->streamingChannels[i].buffer_size = divaBufSizeInFrames * 4 * 4;
free(oldChannelBuffer);
}
else if (divaAudioMixCls->streamingChannels[i].mutex != nullptr && mtx_lock_0(&divaAudioMixCls->streamingChannels[i].mutex) == 0)
{
divaAudioMixCls->streamingChannels[i].buffer = (float*)malloc(divaBufSizeInFrames * 4 * 4);
divaAudioMixCls->streamingChannels[i].buffer_size = divaBufSizeInFrames * 4 * 4;
free(oldChannelBuffer);
mtx_unlock(&divaAudioMixCls->streamingChannels[i].mutex);
//printf("[DivaSound] %d\n", i);
}
}
}
divaAudCls->buffer_size = divaBufSizeInFrames;
free(oldMixbuffer);
free(oldState2buffer);
printf("[DivaSound] Resized internal buffers to %d frames\n", frames);
}
@@ -52,12 +70,12 @@ void resizeTestLoop()
bool dir = true;
while (true)
{
Sleep(5000);
Sleep(3000);
if (dir)
resizeInternalBuffers(divaBufSizeInFrames + 3000);
resizeInternalBuffers(divaBufSizeInFrames + 10000);
else
resizeInternalBuffers(divaBufSizeInFrames - 3000);
resizeInternalBuffers(divaBufSizeInFrames - 10000);
dir = !dir;
}
@@ -442,13 +460,28 @@ void hookedAudioInit(initClass *cls, uint64_t unk, uint64_t unk2)
{
if (!maInit()) return;
maInternalBufferSizeInMilliseconds = device.playback.internalBufferSizeInFrames * 1000 / device.playback.internalSampleRate; // because miniaudio doesn't seem to have this
printf("[DivaSound] Output buffer size: %d (%dms at %dHz)\n", device.playback.internalBufferSizeInFrames, maInternalBufferSizeInMilliseconds, device.playback.internalSampleRate);
printf("[DivaSound] Buffer periods: %d\n", device.playback.internalPeriods);
if (device.playback.internalSampleRate)
{
maInternalBufferSizeInMilliseconds = device.playback.internalBufferSizeInFrames * 1000 / device.playback.internalSampleRate; // because miniaudio doesn't seem to have this
printf("[DivaSound] Output buffer size: %d (%dms at %dHz)\n", device.playback.internalBufferSizeInFrames, maInternalBufferSizeInMilliseconds, device.playback.internalSampleRate);
printf("[DivaSound] Buffer periods: %d\n", device.playback.internalPeriods);
divaBufSizeInFrames = device.playback.internalBufferSizeInFrames * device.sampleRate / device.playback.internalSampleRate; // +128; // 128 is just a bit extra in case resampling needs it or something. idk
divaBufSizeInMilliseconds = divaBufSizeInFrames * 1000 / device.sampleRate;
printf("[DivaSound] PDAFT buffer size: %d (%dms at %dHz)\n", divaBufSizeInFrames, divaBufSizeInMilliseconds, device.sampleRate);
divaBufSizeInFrames = device.playback.internalBufferSizeInFrames * device.sampleRate / device.playback.internalSampleRate; // +128; // 128 is just a bit extra in case resampling needs it or something. idk
divaBufSizeInMilliseconds = divaBufSizeInFrames * 1000 / device.sampleRate;
printf("[DivaSound] PDAFT buffer size: %d (%dms at %dHz)\n", divaBufSizeInFrames, divaBufSizeInMilliseconds, device.sampleRate);
}
else
{
printf("[DivaSound] Unable to determine output sample rate. Assuming 44100Hz.\n");
maInternalBufferSizeInMilliseconds = device.playback.internalBufferSizeInFrames * 1000 / 44100; // because miniaudio doesn't seem to have this
printf("[DivaSound] Output buffer size: %d (%dms at %dHz)\n", device.playback.internalBufferSizeInFrames, maInternalBufferSizeInMilliseconds, 44100);
printf("[DivaSound] Buffer periods: %d\n", device.playback.internalPeriods);
divaBufSizeInFrames = device.playback.internalBufferSizeInFrames * device.sampleRate / 44100;
divaBufSizeInMilliseconds = divaBufSizeInFrames * 1000 / device.sampleRate;
printf("[DivaSound] PDAFT buffer size: %d (%dms at %dHz)\n", divaBufSizeInFrames, divaBufSizeInMilliseconds, device.sampleRate);
}
divaAudioAllocMixer(divaAudioMixCls, unk, unk2, divaBufSizeInFrames);
@@ -12,43 +12,127 @@
#include <mmdeviceapi.h>
#include <audioclient.h>
void (__cdecl* divaAudioInit)(void* cls, uint64_t unk, uint64_t unk2) = (void(__cdecl*)(void* cls, uint64_t unk, uint64_t unk2))0x1406269F0;
void (*divaAudioInit)(void* cls, uint64_t unk, uint64_t unk2) = (void(*)(void* cls, uint64_t unk, uint64_t unk2))0x1406269F0;
void (__cdecl* divaAudioFillbuffer)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase) = (void(__cdecl*)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase))0x140627370;
void (*divaAudioFillbuffer)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase) = (void(*)(void* mixer, int16_t* buf, uint64_t nFrames, bool disableHpVol, bool invertPhase))0x140627370;
// mixer is a pointer to an audioMixer (from audio init's cls + 0x70)
// disableHpVol uses speaker volume for headphones (only works in 4ch mode)
// invertPhase inverts the output signal (only works if disableHpVol == false)
int (__cdecl* divaAudioAllocMixer)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames) = (int(__cdecl*)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames))0x140626710;
int (*divaAudioAllocMixer)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames) = (int(*)(void* cls, uint64_t unk, uint64_t unk2, int64_t nFrames))0x140626710;
// unks are the same as from the init call. they seem to set the internal mixing channel counts(?)
// cls is the same as mixer in divaAudioFillbuffer
// nFrames is number of audio frames to hold in the mixing buffers (only used when divaAudioFillbuffer is called). Internally this is multiplied by 16 (buffers are built using 32bit floats)
int(__cdecl* mtx_init)(void* mutex, int type) = (int(__cdecl*)(void* mutex, int type))0x14081DEF4;
int(*mtx_init)(void* mutex, int type) = (int(*)(void* mutex, int type))0x14081DEF4;
int(*mtx_lock_0)(void* mutex) = (int(*)(void* mutex))0x14081DF50;
int(*mtx_unlock)(void* mutex) = (int(*)(void* mutex))0x14081DFD4;
typedef void streamingCallback(float* buffer, int64_t nFrames, void* userdata);
#pragma pack(push, 1)
struct _50 {
byte padding00[0x50];
};
struct _70 {
byte padding00[0x70];
};
struct initClass; // define these earlier so they can be used in other structs
struct audioMixer;
// known streaming channel variables
// + 0x00 = pointer to mixer class
// + 0x08 = buffer pointer (float)
// + 0x10 = buffer size (frame count * 16)
// + 0x18 = playing (32 bits, set to 0 for pause)
// + 0x1c = reset (32 bits, set to 0 to kill channel)
// + 0x20 = mutex pointer
// + 0x28 = master volume float (multiply other volumes by this)
// + 0x2c = ch1 volume
// + 0x30 = ch2 volume
// + 0x34 = ch3 volume
// + 0x38 = ch4 volume
//
// + 0x40 = callback func
// + 0x48 = callback userdata pointer
struct streamingChannel {
audioMixer* mixer;
struct streamingState {
std::vector<_50>* state;
float* buffer;
uint64_t buffer_size;
uint64_t buffer_size; // in bytes
uint32_t playing; // set to 0 for pause (usually ==1)
uint32_t reset; // set to 1 to kill (usually ==0)
void* mutex;
float volume_master;
float volume_channels[4];
byte padding3c[0x4];
streamingCallback callback;
void* userdata;
};
struct initClass;
// known SE channel variables
// + 0x00 = pointer to mixer class
// + 0x08 = some kind of toggle (is playing)?
// + 0x10 = mutex pointer
// + 0x18 = master volume float (multiply other volumes by this)
// + 0x1c = ch1 volume
// + 0x20 = ch2 volume
// + 0x24 = ch3 volume
// + 0x28 = ch4 volume
// + 0x30 = buffer pointer (float)
// + 0x38 = buffer size????? (frame count * 16)??? (buffers seem to hold whole sounds)
// + 0x40 = num channels
// + 0x48 = num frames
// + 0x50 = sample rate???
// + 0x58 = loop start frame???
// + 0x60 = loop end frame???
// + 0x68 = current playback time
struct seChannel {
audioMixer* mixer;
uint32_t unk1; // toggle on/off?
byte padding0c[0x4];
void* mutex;
float volume_master;
float volume_channels[4];
byte padding2c[0x4];
float* buffer;
byte padding38[0x8]; // probably buffer size
int64_t nChannels; // seems to affect mapping
uint64_t length; // in frames
byte padding50[0x8]; // sample rate?
uint64_t loop_start; // ?
uint64_t loop_end; // ?
uint64_t curTime;
};
// known internal audio mixer variables (used by divaAudioFillbuffer and divaAudioAllocMixer)
// cls + 0x00 = pointer to main audio/init class
// cls + 0x08 = SE channels pointer
// cls + 0x10 = SE channels count
// cls + 0x18 = streaming channels pointer
// cls + 0x20 = streaming channels count
// cls + 0x28 = mixing buffer pointer (when a buffer is generated, this is filled with 32bit floats (four per frame)
// cls + 0x30 = mixing buffer size (frame count * 16)
//
// cls + 0x38 = mutex lock for volume
// cls + 0x40 = master volume float (multiply other volumes by this)
// cls + 0x44 = ch1 volume
// cls + 0x48 = ch2 volume
// cls + 0x4c = ch3 volume
// cls + 0x50 = ch4 volume
struct audioMixer {
initClass* audioClass;
std::vector<_70>** state1;
uint64_t state1_len;
streamingState* state2;
uint64_t state2_len;
seChannel* seChannels;
uint64_t seChannels_len;
streamingChannel* streamingChannels;
uint64_t streamingChannels_len;
float* mixbuffer;
uint64_t mixbuffer_size;
@@ -60,6 +144,27 @@ struct audioMixer {
byte padding54[4];
};
// known main/init audio class variables (used by divaAudioInit)
// cls + 0x0 = WAVEFORMATEXTENSIBLE wave_format (null with old method) (length 0x28)
// cls + 0x28 = IMMDeviceEnumerator *pEnumerator
// cls + 0x30 = IMMDevice *pDevice (default device)
// cls + 0x38 = IAudioClient *pAudioClient
//
// cls + 0x40 = buffer size in frames
//
// cls + 0x48 = IAudioRenderClient *pRenderClient
//
// cls + 0x50 = HANDLE hEvent (for original WASAPI buffer timing)
//
// cls + 0x58 = number of output channels
// cls + 0x60 = audio sample rate
// cls + 0x68 = audio bit depth (only 16bit works)
//
// cls + 0x70 = pointer to mixer class
//
// cls + 0x78 = HANDLE* hCallback (handle to original callback thread)
//
// cls + 0x80 = break flag dword (becomes 1 on exit)
struct initClass {
WAVEFORMATEXTENSIBLE wave_format;
IMMDeviceEnumerator *pEnumerator;
@@ -83,45 +188,6 @@ struct initClass {
};
#pragma pack(pop)
// known internal audio mixer variables (used by divaAudioFillbuffer and divaAudioAllocMixer)
// cls + 0x00 = pointer to main audio/init class
// cls + 0x08 = internal state 1 (SE?) vector pointer (or full class?)
// cls + 0x10 = internal state 1 (SE?) length (channels?)
// cls + 0x18 = internal state 2 (streaming?) vector pointer (or full class?)
// cls + 0x20 = internal state 2 (streaming?) length (channels?)
// cls + 0x28 = mixing buffer pointer (when a buffer is generated, this is filled with 32bit floats (four per frame)
// cls + 0x30 = mixing buffer size (frame count * 16)
//
// cls + 0x38 = mutex lock for volume
// cls + 0x40 = master volume float (multiply other volumes by this)
// cls + 0x44 = ch1 volume
// cls + 0x48 = ch2 volume
// cls + 0x4c = ch3 volume
// cls + 0x50 = ch4 volume
//
//
// known main/init audio class variables (used by divaAudioInit)
// cls + 0x0 = WAVEFORMATEXTENSIBLE wave_format (null with old method) (length 0x28)
// cls + 0x28 = IMMDeviceEnumerator *pEnumerator
// cls + 0x30 = IMMDevice *pDevice (default device)
// cls + 0x38 = IAudioClient *pAudioClient
//
// cls + 0x40 = buffer size in frames
//
// cls + 0x48 = IAudioRenderClient *pRenderClient
//
// cls + 0x50 = HANDLE hEvent (for original WASAPI buffer timing)
//
// cls + 0x58 = number of output channels
// cls + 0x60 = audio sample rate
// cls + 0x68 = audio bit depth (only 16bit works)
//
// cls + 0x70 = pointer to mixer class
//
// cls + 0x78 = HANDLE* hCallback (handle to original callback thread)
//
// cls + 0x80 = break flag dword (becomes 1 on exit)
initClass *divaAudCls;
audioMixer *divaAudioMixCls;