forked from LeenkxTeam/LNXRNT
Kore Update
This commit is contained in:
@ -6,6 +6,8 @@
|
||||
|
||||
#include <dsound.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace {
|
||||
IDirectSound8 *dsound = nullptr;
|
||||
IDirectSoundBuffer *dbuffer = nullptr;
|
||||
@ -19,7 +21,6 @@ namespace {
|
||||
const int gap = 10 * 1024;
|
||||
DWORD writePos = gap;
|
||||
|
||||
void (*a2_callback)(kinc_a2_buffer_t *buffer, int samples) = nullptr;
|
||||
kinc_a2_buffer_t a2_buffer;
|
||||
}
|
||||
|
||||
@ -30,12 +31,15 @@ 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 = new uint8_t[a2_buffer.data_size];
|
||||
a2_buffer.channel_count = 2;
|
||||
a2_buffer.channels[0] = new float[a2_buffer.data_size];
|
||||
a2_buffer.channels[1] = new float[a2_buffer.data_size];
|
||||
|
||||
kinc_microsoft_affirm(DirectSoundCreate8(nullptr, &dsound, nullptr));
|
||||
// TODO (DK) only for the main window?
|
||||
@ -61,25 +65,29 @@ void kinc_a2_init() {
|
||||
kinc_microsoft_affirm(dsound->CreateSoundBuffer(&bufferDesc, &dbuffer, nullptr));
|
||||
|
||||
DWORD size1;
|
||||
uint8_t *buffer1;
|
||||
uint8_t *buffer1 = NULL;
|
||||
kinc_microsoft_affirm(dbuffer->Lock(writePos, gap, (void **)&buffer1, &size1, nullptr, nullptr, 0));
|
||||
for (int i = 0; i < gap; ++i)
|
||||
assert(buffer1 != NULL);
|
||||
for (DWORD i = 0; i < size1; ++i) {
|
||||
buffer1[i] = 0;
|
||||
}
|
||||
kinc_microsoft_affirm(dbuffer->Unlock(buffer1, size1, nullptr, 0));
|
||||
|
||||
kinc_microsoft_affirm(dbuffer->Play(0, 0, DSBPLAY_LOOPING));
|
||||
}
|
||||
|
||||
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 samplesPerSecond;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void copySample(uint8_t *buffer, DWORD &index) {
|
||||
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;
|
||||
void copySample(uint8_t *buffer, DWORD &index, bool left) {
|
||||
float value = *(float *)&a2_buffer.channels[left ? 0 : 1][a2_buffer.read_location];
|
||||
if (!left) {
|
||||
a2_buffer.read_location += 1;
|
||||
if (a2_buffer.read_location >= a2_buffer.data_size) {
|
||||
a2_buffer.read_location = 0;
|
||||
}
|
||||
}
|
||||
*(int16_t *)&buffer[index] = static_cast<int16_t>(value * 32767);
|
||||
index += 2;
|
||||
@ -92,47 +100,49 @@ void kinc_a2_update() {
|
||||
kinc_microsoft_affirm(dbuffer->GetCurrentPosition(&playPosition, &writePosition));
|
||||
|
||||
int dif;
|
||||
if (writePos >= writePosition)
|
||||
if (writePos >= writePosition) {
|
||||
dif = writePos - writePosition;
|
||||
else
|
||||
dif = dsize - writePosition + writePos;
|
||||
|
||||
if (dif < gap)
|
||||
return;
|
||||
if (writePos + gap >= dsize) {
|
||||
if (playPosition >= writePos || playPosition <= gap)
|
||||
return;
|
||||
if (writePosition >= writePos || writePosition <= gap)
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (playPosition >= writePos && playPosition <= writePos + gap)
|
||||
return;
|
||||
if (writePosition >= writePos && writePosition <= writePos + gap)
|
||||
return;
|
||||
dif = dsize - writePosition + writePos;
|
||||
}
|
||||
|
||||
a2_callback(&a2_buffer, gap / 2);
|
||||
if (dif < gap) {
|
||||
return;
|
||||
}
|
||||
if (writePos + gap >= dsize) {
|
||||
if (playPosition >= writePos || playPosition <= gap) {
|
||||
return;
|
||||
}
|
||||
if (writePosition >= writePos || writePosition <= gap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (playPosition >= writePos && playPosition <= writePos + gap) {
|
||||
return;
|
||||
}
|
||||
if (writePosition >= writePos && writePosition <= writePos + gap) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD size1, size2;
|
||||
uint8_t *buffer1, *buffer2;
|
||||
kinc_microsoft_affirm(dbuffer->Lock(writePos, gap, (void **)&buffer1, &size1, (void **)&buffer2, &size2, 0));
|
||||
kinc_a2_internal_callback(&a2_buffer, (uint32_t)(gap / 4));
|
||||
|
||||
DWORD size1;
|
||||
uint8_t *buffer1;
|
||||
kinc_microsoft_affirm(dbuffer->Lock(writePos, gap, (void **)&buffer1, &size1, NULL, NULL, 0));
|
||||
|
||||
for (DWORD i = 0; i < size1 - (bitsPerSample / 8 - 1);) {
|
||||
copySample(buffer1, i);
|
||||
copySample(buffer1, i, ((writePos + i) / 2) % 2 == 0);
|
||||
}
|
||||
writePos += size1;
|
||||
if (buffer2 != nullptr) {
|
||||
for (DWORD i = 0; i < size2 - (bitsPerSample / 8 - 1);) {
|
||||
copySample(buffer2, i);
|
||||
}
|
||||
writePos = size2;
|
||||
}
|
||||
|
||||
kinc_microsoft_affirm(dbuffer->Unlock(buffer1, size1, buffer2, size2));
|
||||
kinc_microsoft_affirm(dbuffer->Unlock(buffer1, size1, NULL, 0));
|
||||
|
||||
if (writePos >= dsize)
|
||||
if (writePos >= dsize) {
|
||||
writePos -= dsize;
|
||||
}
|
||||
}
|
||||
|
||||
void kinc_a2_shutdown() {
|
||||
|
||||
@ -7,6 +7,9 @@
|
||||
|
||||
// Windows 7
|
||||
#define WINVER 0x0601
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
#endif
|
||||
#define _WIN32_WINNT 0x0601
|
||||
|
||||
#define NOATOM
|
||||
@ -16,7 +19,7 @@
|
||||
#define NOCTLMGR
|
||||
#define NODEFERWINDOWPOS
|
||||
#define NODRAWTEXT
|
||||
//#define NOGDI
|
||||
// #define NOGDI
|
||||
#define NOGDICAPMASKS
|
||||
#define NOHELP
|
||||
#define NOICONS
|
||||
@ -28,7 +31,7 @@
|
||||
#define NOMENUS
|
||||
#define NOMETAFILE
|
||||
#define NOMINMAX
|
||||
//#define NOMSG
|
||||
// #define NOMSG
|
||||
#define NONLS
|
||||
#define NOOPENFILE
|
||||
#define NOPROFILER
|
||||
@ -40,7 +43,7 @@
|
||||
#define NOSYSCOMMANDS
|
||||
#define NOSYSMETRICS
|
||||
#define NOTEXTMETRIC
|
||||
//#define NOUSER
|
||||
// #define NOUSER
|
||||
#define NOVIRTUALKEYCODES
|
||||
#define NOWH
|
||||
#define NOWINMESSAGES
|
||||
@ -53,6 +56,7 @@
|
||||
#include <AudioClient.h>
|
||||
#include <mmdeviceapi.h>
|
||||
|
||||
#ifndef __MINGW32__
|
||||
// MIDL_INTERFACE("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2")
|
||||
DEFINE_GUID(IID_IAudioClient, 0x1CB9AD4C, 0xDBFA, 0x4c32, 0xB1, 0x78, 0xC2, 0xF5, 0x68, 0xA7, 0x03, 0xB2);
|
||||
// MIDL_INTERFACE("F294ACFC-3146-4483-A7BF-ADDCA7C260E2")
|
||||
@ -61,9 +65,9 @@ DEFINE_GUID(IID_IAudioRenderClient, 0xF294ACFC, 0x3146, 0x4483, 0xA7, 0xBF, 0xAD
|
||||
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xA95664D2, 0x9614, 0x4F35, 0xA7, 0x46, 0xDE, 0x8D, 0xB6, 0x36, 0x17, 0xE6);
|
||||
// DECLSPEC_UUID("BCDE0395-E52F-467C-8E3D-C4579291692E")
|
||||
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xBCDE0395, 0xE52F, 0x467C, 0x8E, 0x3D, 0xC4, 0x57, 0x92, 0x91, 0x69, 0x2E);
|
||||
#endif
|
||||
|
||||
// based on the implementation in soloud and Microsoft sample code
|
||||
static volatile void (*a2_callback)(kinc_a2_buffer_t *buffer, int samples) = NULL;
|
||||
static kinc_a2_buffer_t a2_buffer;
|
||||
|
||||
static IMMDeviceEnumerator *deviceEnumerator;
|
||||
@ -71,11 +75,15 @@ static IMMDevice *device;
|
||||
static IAudioClient *audioClient = NULL;
|
||||
static IAudioRenderClient *renderClient = NULL;
|
||||
static HANDLE bufferEndEvent = 0;
|
||||
static HANDLE audioProcessingDoneEvent;
|
||||
static UINT32 bufferFrames;
|
||||
static WAVEFORMATEX requestedFormat;
|
||||
static WAVEFORMATEX *closestFormat;
|
||||
static WAVEFORMATEX *format;
|
||||
static uint32_t samples_per_second = 44100;
|
||||
|
||||
uint32_t kinc_a2_samples_per_second(void) {
|
||||
return samples_per_second;
|
||||
}
|
||||
|
||||
static bool initDefaultDevice() {
|
||||
if (renderClient != NULL) {
|
||||
@ -130,10 +138,12 @@ static bool initDefaultDevice() {
|
||||
return false;
|
||||
}
|
||||
|
||||
kinc_a2_samples_per_second = format->nSamplesPerSec;
|
||||
a2_buffer.format.samples_per_second = kinc_a2_samples_per_second;
|
||||
a2_buffer.format.bits_per_sample = 16;
|
||||
a2_buffer.format.channels = 2;
|
||||
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->lpVtbl->GetBufferSize(audioClient, &bufferFrames));
|
||||
@ -152,22 +162,6 @@ static bool initDefaultDevice() {
|
||||
}
|
||||
}
|
||||
|
||||
static void copyS16Sample(int16_t *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 = (int16_t)(value * 32767);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static void submitEmptyBuffer(unsigned frames) {
|
||||
BYTE *buffer = NULL;
|
||||
HRESULT result = renderClient->lpVtbl->GetBuffer(renderClient, frames, &buffer);
|
||||
@ -180,31 +174,53 @@ static void submitEmptyBuffer(unsigned frames) {
|
||||
result = renderClient->lpVtbl->ReleaseBuffer(renderClient, frames, 0);
|
||||
}
|
||||
|
||||
static void restartAudio() {
|
||||
initDefaultDevice();
|
||||
submitEmptyBuffer(bufferFrames);
|
||||
audioClient->lpVtbl->Start(audioClient);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static void submitBuffer(unsigned frames) {
|
||||
BYTE *buffer = NULL;
|
||||
HRESULT result = renderClient->lpVtbl->GetBuffer(renderClient, frames, &buffer);
|
||||
if (FAILED(result)) {
|
||||
if (result == AUDCLNT_E_DEVICE_INVALIDATED) {
|
||||
initDefaultDevice();
|
||||
submitEmptyBuffer(bufferFrames);
|
||||
audioClient->lpVtbl->Start(audioClient);
|
||||
restartAudio();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (a2_callback != NULL) {
|
||||
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((int16_t *)&buffer[i * format->nBlockAlign]);
|
||||
copyS16Sample((int16_t *)&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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,9 +231,7 @@ static void submitBuffer(unsigned frames) {
|
||||
result = renderClient->lpVtbl->ReleaseBuffer(renderClient, frames, 0);
|
||||
if (FAILED(result)) {
|
||||
if (result == AUDCLNT_E_DEVICE_INVALIDATED) {
|
||||
initDefaultDevice();
|
||||
submitEmptyBuffer(bufferFrames);
|
||||
audioClient->lpVtbl->Start(audioClient);
|
||||
restartAudio();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,15 +239,13 @@ static void submitBuffer(unsigned frames) {
|
||||
static DWORD WINAPI audioThread(LPVOID ignored) {
|
||||
submitBuffer(bufferFrames);
|
||||
audioClient->lpVtbl->Start(audioClient);
|
||||
while (WAIT_OBJECT_0 != WaitForSingleObject(audioProcessingDoneEvent, 0)) {
|
||||
while (1) {
|
||||
WaitForSingleObject(bufferEndEvent, INFINITE);
|
||||
UINT32 padding = 0;
|
||||
HRESULT result = audioClient->lpVtbl->GetCurrentPadding(audioClient, &padding);
|
||||
if (FAILED(result)) {
|
||||
if (result == AUDCLNT_E_DEVICE_INVALIDATED) {
|
||||
initDefaultDevice();
|
||||
submitEmptyBuffer(bufferFrames);
|
||||
audioClient->lpVtbl->Start(audioClient);
|
||||
restartAudio();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -252,15 +264,15 @@ 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);
|
||||
|
||||
audioProcessingDoneEvent = CreateEvent(0, FALSE, FALSE, 0);
|
||||
kinc_affirm(audioProcessingDoneEvent != 0);
|
||||
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));
|
||||
|
||||
kinc_windows_co_initialize();
|
||||
kinc_microsoft_affirm(CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void **)&deviceEnumerator));
|
||||
@ -270,10 +282,6 @@ void kinc_a2_init() {
|
||||
}
|
||||
}
|
||||
|
||||
void kinc_a2_set_callback(void (*kinc_a2_audio_callback)(kinc_a2_buffer_t *buffer, int samples)) {
|
||||
a2_callback = kinc_a2_audio_callback;
|
||||
}
|
||||
|
||||
void kinc_a2_update() {}
|
||||
|
||||
#define SAFE_RELEASE(punk) \
|
||||
|
||||
@ -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() {}
|
||||
|
||||
Reference in New Issue
Block a user