update DivaSound source
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user