Kore Update

This commit is contained in:
Gorochu
2026-06-09 12:45:01 -07:00
parent a2d5c9aea4
commit 7558d03739
371 changed files with 30188 additions and 7466 deletions

View File

@ -9,15 +9,13 @@
#include <AudioClient.h>
#include <Windows.h>
#include <initguid.h>
#ifdef KORE_WINRT
#ifdef KINC_WINDOWSAPP
#include <mfapi.h>
#endif
#include <mmdeviceapi.h>
#include <wrl/implements.h>
using namespace Kore;
#ifdef KORE_WINRT
#ifdef KINC_WINDOWSAPP
using namespace ::Microsoft::WRL;
using namespace Windows::Media::Devices;
using namespace Windows::Storage::Streams;
@ -40,7 +38,6 @@ template <class T> void SafeRelease(__deref_inout_opt T **ppT) {
// based on the implementation in soloud and Microsoft sample code
namespace {
kinc_thread_t thread;
void (*a2_callback)(kinc_a2_buffer_t *buffer, int samples) = nullptr;
kinc_a2_buffer_t a2_buffer;
IMMDeviceEnumerator *deviceEnumerator;
@ -48,16 +45,16 @@ namespace {
IAudioClient *audioClient = NULL;
IAudioRenderClient *renderClient = NULL;
HANDLE bufferEndEvent = 0;
HANDLE audioProcessingDoneEvent;
UINT32 bufferFrames;
WAVEFORMATEX requestedFormat;
WAVEFORMATEX *closestFormat;
WAVEFORMATEX *format;
static uint32_t samples_per_second = 44100;
bool initDefaultDevice();
void audioThread(LPVOID);
#ifdef KORE_WINRT
#ifdef KINC_WINDOWSAPP
class AudioRenderer : public RuntimeClass<RuntimeClassFlags<ClassicCom>, FtmBase, IActivateAudioInterfaceCompletionHandler> {
public:
STDMETHOD(ActivateCompleted)(IActivateAudioInterfaceAsyncOperation *operation) {
@ -77,7 +74,7 @@ namespace {
#endif
bool initDefaultDevice() {
#ifdef KORE_WINRT
#ifdef KINC_WINDOWSAPP
HRESULT hr = S_OK;
#else
if (renderClient != NULL) {
@ -132,8 +129,12 @@ namespace {
return false;
}
kinc_a2_samples_per_second = format->nSamplesPerSec;
a2_buffer.format.samples_per_second = kinc_a2_samples_per_second;
uint32_t old_samples_per_second = samples_per_second;
samples_per_second = format->nSamplesPerSec;
if (samples_per_second != old_samples_per_second) {
kinc_a2_internal_sample_rate_callback();
}
a2_buffer.channel_count = 2;
bufferFrames = 0;
kinc_microsoft_affirm(audioClient->GetBufferSize(&bufferFrames));
@ -152,18 +153,26 @@ namespace {
}
}
void copyS16Sample(s16 *buffer) {
float value = *(float *)&a2_buffer.data[a2_buffer.read_location];
a2_buffer.read_location += 4;
if (a2_buffer.read_location >= a2_buffer.data_size) a2_buffer.read_location = 0;
*buffer = (s16)(value * 32767);
void copyS16Sample(int16_t *left, int16_t *right) {
float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
a2_buffer.read_location += 1;
if (a2_buffer.read_location >= a2_buffer.data_size) {
a2_buffer.read_location = 0;
}
*left = (int16_t)(left_value * 32767);
*right = (int16_t)(right_value * 32767);
}
void copyFloatSample(float *buffer) {
float value = *(float *)&a2_buffer.data[a2_buffer.read_location];
a2_buffer.read_location += 4;
if (a2_buffer.read_location >= a2_buffer.data_size) a2_buffer.read_location = 0;
*buffer = value;
void copyFloatSample(float *left, float *right) {
float left_value = *(float *)&a2_buffer.channels[0][a2_buffer.read_location];
float right_value = *(float *)&a2_buffer.channels[1][a2_buffer.read_location];
a2_buffer.read_location += 1;
if (a2_buffer.read_location >= a2_buffer.data_size) {
a2_buffer.read_location = 0;
}
*left = left_value;
*right = right_value;
}
void submitEmptyBuffer(unsigned frames) {
@ -190,19 +199,15 @@ namespace {
return;
}
if (a2_callback != nullptr) {
a2_callback(&a2_buffer, frames * 2);
memset(buffer, 0, frames * format->nBlockAlign);
if (kinc_a2_internal_callback(&a2_buffer, frames)) {
if (format->wFormatTag == WAVE_FORMAT_PCM) {
for (UINT32 i = 0; i < frames; ++i) {
copyS16Sample((s16 *)&buffer[i * format->nBlockAlign]);
copyS16Sample((s16 *)&buffer[i * format->nBlockAlign + 2]);
copyS16Sample((int16_t *)&buffer[i * format->nBlockAlign], (int16_t *)&buffer[i * format->nBlockAlign + 2]);
}
}
else {
for (UINT32 i = 0; i < frames; ++i) {
copyFloatSample((float *)&buffer[i * format->nBlockAlign]);
copyFloatSample((float *)&buffer[i * format->nBlockAlign + 4]);
copyFloatSample((float *)&buffer[i * format->nBlockAlign], (float *)&buffer[i * format->nBlockAlign + 4]);
}
}
}
@ -223,7 +228,7 @@ namespace {
void audioThread(LPVOID) {
submitBuffer(bufferFrames);
audioClient->Start();
while (WAIT_OBJECT_0 != WaitForSingleObject(audioProcessingDoneEvent, 0)) {
while (true) {
WaitForSingleObject(bufferEndEvent, INFINITE);
UINT32 padding = 0;
HRESULT result = audioClient->GetCurrentPadding(&padding);
@ -242,7 +247,7 @@ namespace {
} // namespace
#ifndef KORE_WINRT
#ifndef KINC_WINDOWSAPP
extern "C" void kinc_windows_co_initialize(void);
#endif
@ -253,17 +258,17 @@ void kinc_a2_init() {
return;
}
kinc_a2_internal_init();
initialized = true;
a2_buffer.read_location = 0;
a2_buffer.write_location = 0;
a2_buffer.data_size = 128 * 1024;
a2_buffer.data = (uint8_t *)malloc(a2_buffer.data_size);
a2_buffer.channel_count = 2;
a2_buffer.channels[0] = (float *)malloc(a2_buffer.data_size * sizeof(float));
a2_buffer.channels[1] = (float *)malloc(a2_buffer.data_size * sizeof(float));
audioProcessingDoneEvent = CreateEvent(0, FALSE, FALSE, 0);
kinc_affirm(audioProcessingDoneEvent != 0);
#ifdef KORE_WINRT
#ifdef KINC_WINDOWSAPP
renderer = Make<AudioRenderer>();
IActivateAudioInterfaceAsyncOperation *asyncOp;
@ -281,8 +286,8 @@ void kinc_a2_init() {
#endif
}
void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, int samples)) {
a2_callback = kinc_a2_audio_callback;
uint32_t kinc_a2_samples_per_second(void) {
return samples_per_second;
}
void kinc_a2_update() {}