mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-30 05:31:39 +00:00
faudio: Import upstream release 24.06.
This commit is contained in:
parent
951e0e27a7
commit
41c65022c1
|
@ -494,7 +494,7 @@ extern FAudioGUID DATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||||
|
|
||||||
#define FAUDIO_ABI_VERSION 0
|
#define FAUDIO_ABI_VERSION 0
|
||||||
#define FAUDIO_MAJOR_VERSION 24
|
#define FAUDIO_MAJOR_VERSION 24
|
||||||
#define FAUDIO_MINOR_VERSION 5
|
#define FAUDIO_MINOR_VERSION 6
|
||||||
#define FAUDIO_PATCH_VERSION 0
|
#define FAUDIO_PATCH_VERSION 0
|
||||||
|
|
||||||
#define FAUDIO_COMPILED_VERSION ( \
|
#define FAUDIO_COMPILED_VERSION ( \
|
||||||
|
|
|
@ -85,7 +85,7 @@ static inline float FACT_INTERNAL_CalculateFilterFrequency(
|
||||||
*
|
*
|
||||||
* -@Woflox
|
* -@Woflox
|
||||||
*/
|
*/
|
||||||
float freq = 2 * FAudio_sin(
|
float freq = 2.0f * FAudio_sinf(
|
||||||
F3DAUDIO_PI *
|
F3DAUDIO_PI *
|
||||||
FAudio_min(desiredFrequency / sampleRate, 0.5f)
|
FAudio_min(desiredFrequency / sampleRate, 0.5f)
|
||||||
);
|
);
|
||||||
|
@ -1027,21 +1027,21 @@ float FACT_INTERNAL_CalculateRPC(
|
||||||
}
|
}
|
||||||
else if (rpc->points[i].type == 1) /* Fast */
|
else if (rpc->points[i].type == 1) /* Fast */
|
||||||
{
|
{
|
||||||
result += maxY * (1.0f - FAudio_pow(1.0f - FAudio_pow(deltaXNormalized, 1.0f / 1.5f), 1.5f));
|
result += maxY * (1.0f - FAudio_powf(1.0f - FAudio_powf(deltaXNormalized, 1.0f / 1.5f), 1.5f));
|
||||||
}
|
}
|
||||||
else if (rpc->points[i].type == 2) /* Slow */
|
else if (rpc->points[i].type == 2) /* Slow */
|
||||||
{
|
{
|
||||||
result += maxY * (1.0f - FAudio_pow(1.0f - FAudio_pow(deltaXNormalized, 1.5f), 1.0f / 1.5f));
|
result += maxY * (1.0f - FAudio_powf(1.0f - FAudio_powf(deltaXNormalized, 1.5f), 1.0f / 1.5f));
|
||||||
}
|
}
|
||||||
else if (rpc->points[i].type == 3) /* SinCos */
|
else if (rpc->points[i].type == 3) /* SinCos */
|
||||||
{
|
{
|
||||||
if (maxY > 0.0f)
|
if (maxY > 0.0f)
|
||||||
{
|
{
|
||||||
result += maxY * (1.0f - FAudio_pow(1.0f - FAudio_sqrtf(deltaXNormalized), 2.0f));
|
result += maxY * (1.0f - FAudio_powf(1.0f - FAudio_sqrtf(deltaXNormalized), 2.0f));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result += maxY * (1.0f - FAudio_sqrtf(1.0f - FAudio_pow(deltaXNormalized, 2.0f)));
|
result += maxY * (1.0f - FAudio_sqrtf(1.0f - FAudio_powf(deltaXNormalized, 2.0f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2066,8 +2066,8 @@ uint32_t FACT_INTERNAL_ParseAudioEngine(
|
||||||
rpcOffset,
|
rpcOffset,
|
||||||
dspPresetOffset,
|
dspPresetOffset,
|
||||||
dspParameterOffset;
|
dspParameterOffset;
|
||||||
uint16_t blob1Count, blob2Count;
|
uint16_t blob1Count, blob2Count, tool;
|
||||||
uint8_t version, tool;
|
uint8_t version;
|
||||||
uint8_t se;
|
uint8_t se;
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
size_t memsize;
|
size_t memsize;
|
||||||
|
|
|
@ -183,7 +183,7 @@ static inline void DspBiQuad_Change(
|
||||||
float q,
|
float q,
|
||||||
float gain
|
float gain
|
||||||
) {
|
) {
|
||||||
const float TWOPI = 6.283185307179586476925286766559005;
|
const float TWOPI = (float)6.283185307179586476925286766559005;
|
||||||
float theta_c = (TWOPI * frequency) / (float) filter->sampleRate;
|
float theta_c = (TWOPI * frequency) / (float) filter->sampleRate;
|
||||||
float mu = DbGainToFactor(gain);
|
float mu = DbGainToFactor(gain);
|
||||||
float beta = (type == DSP_BIQUAD_LOWSHELVING) ?
|
float beta = (type == DSP_BIQUAD_LOWSHELVING) ?
|
||||||
|
|
|
@ -383,6 +383,12 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
if ( voice->src.callback != NULL &&
|
if ( voice->src.callback != NULL &&
|
||||||
voice->src.callback->OnBufferStart != NULL )
|
voice->src.callback->OnBufferStart != NULL )
|
||||||
{
|
{
|
||||||
|
FAudio_PlatformUnlockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
|
FAudio_PlatformUnlockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
@ -393,6 +399,12 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
|
|
||||||
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->src.bufferLock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +454,12 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
if ( voice->src.callback != NULL &&
|
if ( voice->src.callback != NULL &&
|
||||||
voice->src.callback->OnLoopEnd != NULL )
|
voice->src.callback->OnLoopEnd != NULL )
|
||||||
{
|
{
|
||||||
|
FAudio_PlatformUnlockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
|
FAudio_PlatformUnlockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
@ -452,6 +470,12 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
|
|
||||||
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->src.bufferLock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -504,6 +528,12 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
/* Callbacks */
|
/* Callbacks */
|
||||||
if (voice->src.callback != NULL)
|
if (voice->src.callback != NULL)
|
||||||
{
|
{
|
||||||
|
FAudio_PlatformUnlockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
|
FAudio_PlatformUnlockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
@ -522,6 +552,15 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
/* One last chance at redemption */
|
/* One last chance at redemption */
|
||||||
if (buffer == NULL && voice->src.bufferList != NULL)
|
if (buffer == NULL && voice->src.bufferList != NULL)
|
||||||
{
|
{
|
||||||
|
@ -531,14 +570,29 @@ static void FAudio_INTERNAL_DecodeBuffers(
|
||||||
|
|
||||||
if (buffer != NULL && voice->src.callback->OnBufferStart != NULL)
|
if (buffer != NULL && voice->src.callback->OnBufferStart != NULL)
|
||||||
{
|
{
|
||||||
|
FAudio_PlatformUnlockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
|
FAudio_PlatformUnlockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
|
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
voice->src.callback->OnBufferStart(
|
voice->src.callback->OnBufferStart(
|
||||||
voice->src.callback,
|
voice->src.callback,
|
||||||
buffer->pContext
|
buffer->pContext
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->sendLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->sendLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
voice->audio->pFree(toDelete);
|
voice->audio->pFree(toDelete);
|
||||||
|
@ -631,7 +685,7 @@ static inline void FAudio_INTERNAL_FilterVoice(
|
||||||
filterState[ci][FAudioHighPassFilter] = samples[j * numChannels + ci] - filterState[ci][FAudioLowPassFilter] - (filter->OneOverQ * filterState[ci][FAudioBandPassFilter]);
|
filterState[ci][FAudioHighPassFilter] = samples[j * numChannels + ci] - filterState[ci][FAudioLowPassFilter] - (filter->OneOverQ * filterState[ci][FAudioBandPassFilter]);
|
||||||
filterState[ci][FAudioBandPassFilter] = (filter->Frequency * filterState[ci][FAudioHighPassFilter]) + filterState[ci][FAudioBandPassFilter];
|
filterState[ci][FAudioBandPassFilter] = (filter->Frequency * filterState[ci][FAudioHighPassFilter]) + filterState[ci][FAudioBandPassFilter];
|
||||||
filterState[ci][FAudioNotchFilter] = filterState[ci][FAudioHighPassFilter] + filterState[ci][FAudioLowPassFilter];
|
filterState[ci][FAudioNotchFilter] = filterState[ci][FAudioHighPassFilter] + filterState[ci][FAudioLowPassFilter];
|
||||||
samples[j * numChannels + ci] = filterState[ci][filter->Type] * filter->WetDryMix + samples[j * numChannels + ci] * (1.0 - filter->WetDryMix);
|
samples[j * numChannels + ci] = filterState[ci][filter->Type] * filter->WetDryMix + samples[j * numChannels + ci] * (1.0f - filter->WetDryMix);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_FUNC_EXIT(audio)
|
LOG_FUNC_EXIT(audio)
|
||||||
|
@ -1250,6 +1304,9 @@ static void FAudio_INTERNAL_FlushPendingBuffers(FAudioSourceVoice *voice)
|
||||||
|
|
||||||
if (voice->src.callback != NULL && voice->src.callback->OnBufferEnd != NULL)
|
if (voice->src.callback != NULL && voice->src.callback->OnBufferEnd != NULL)
|
||||||
{
|
{
|
||||||
|
FAudio_PlatformUnlockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_UNLOCK(voice->audio, voice->src.bufferLock)
|
||||||
|
|
||||||
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
FAudio_PlatformUnlockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_UNLOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
@ -1260,6 +1317,9 @@ static void FAudio_INTERNAL_FlushPendingBuffers(FAudioSourceVoice *voice)
|
||||||
|
|
||||||
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
FAudio_PlatformLockMutex(voice->audio->sourceLock);
|
||||||
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
LOG_MUTEX_LOCK(voice->audio, voice->audio->sourceLock)
|
||||||
|
|
||||||
|
FAudio_PlatformLockMutex(voice->src.bufferLock);
|
||||||
|
LOG_MUTEX_LOCK(voice->audio, voice->src.bufferLock)
|
||||||
}
|
}
|
||||||
voice->audio->pFree(entry);
|
voice->audio->pFree(entry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#define FAudio_strlcpy(ptr1, ptr2, size) lstrcpynA(ptr1, ptr2, size)
|
#define FAudio_strlcpy(ptr1, ptr2, size) lstrcpynA(ptr1, ptr2, size)
|
||||||
|
|
||||||
#define FAudio_pow(x, y) pow(x, y)
|
#define FAudio_pow(x, y) pow(x, y)
|
||||||
|
#define FAudio_powf(x, y) powf(x, y)
|
||||||
#define FAudio_log(x) log(x)
|
#define FAudio_log(x) log(x)
|
||||||
#define FAudio_log10(x) log10(x)
|
#define FAudio_log10(x) log10(x)
|
||||||
#define FAudio_sin(x) sin(x)
|
#define FAudio_sin(x) sin(x)
|
||||||
|
@ -138,6 +139,7 @@ extern void FAudio_Log(char const *msg);
|
||||||
#define FAudio_strlcpy(ptr1, ptr2, size) SDL_strlcpy(ptr1, ptr2, size)
|
#define FAudio_strlcpy(ptr1, ptr2, size) SDL_strlcpy(ptr1, ptr2, size)
|
||||||
|
|
||||||
#define FAudio_pow(x, y) SDL_pow(x, y)
|
#define FAudio_pow(x, y) SDL_pow(x, y)
|
||||||
|
#define FAudio_powf(x, y) SDL_powf(x, y)
|
||||||
#define FAudio_log(x) SDL_log(x)
|
#define FAudio_log(x) SDL_log(x)
|
||||||
#define FAudio_log10(x) SDL_log10(x)
|
#define FAudio_log10(x) SDL_log10(x)
|
||||||
#define FAudio_sin(x) SDL_sin(x)
|
#define FAudio_sin(x) SDL_sin(x)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include <audioclient.h>
|
#include <audioclient.h>
|
||||||
#include <mmdeviceapi.h>
|
#include <mmdeviceapi.h>
|
||||||
|
#include <devpkey.h>
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CWMADecMediaObject, 0x2eeb4adf, 0x4578, 0x4d10, 0xbc, 0xa7, 0xbb, 0x95, 0x5f, 0x56, 0x32, 0x0a);
|
DEFINE_GUID(CLSID_CWMADecMediaObject, 0x2eeb4adf, 0x4578, 0x4d10, 0xbc, 0xa7, 0xbb, 0x95, 0x5f, 0x56, 0x32, 0x0a);
|
||||||
DEFINE_MEDIATYPE_GUID(MFAudioFormat_XMAudio2, FAUDIO_FORMAT_XMAUDIO2);
|
DEFINE_MEDIATYPE_GUID(MFAudioFormat_XMAudio2, FAUDIO_FORMAT_XMAUDIO2);
|
||||||
|
@ -180,6 +181,11 @@ static DWORD WINAPI FAudio_AudioClientThread(void *user)
|
||||||
while (WaitForMultipleObjects(2, args->events, FALSE, INFINITE) == WAIT_OBJECT_0)
|
while (WaitForMultipleObjects(2, args->events, FALSE, INFINITE) == WAIT_OBJECT_0)
|
||||||
{
|
{
|
||||||
hr = IAudioClient_GetCurrentPadding(args->client, &padding);
|
hr = IAudioClient_GetCurrentPadding(args->client, &padding);
|
||||||
|
if (hr == AUDCLNT_E_DEVICE_INVALIDATED)
|
||||||
|
{
|
||||||
|
/* Device was removed, just exit */
|
||||||
|
break;
|
||||||
|
}
|
||||||
FAudio_assert(!FAILED(hr) && "Failed to get IAudioClient current padding!");
|
FAudio_assert(!FAILED(hr) && "Failed to get IAudioClient current padding!");
|
||||||
|
|
||||||
hr = FAudio_FillAudioClientBuffer(args, render_client, frames, padding);
|
hr = FAudio_FillAudioClientBuffer(args, render_client, frames, padding);
|
||||||
|
@ -194,6 +200,141 @@ static DWORD WINAPI FAudio_AudioClientThread(void *user)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sets `defaultDeviceIndex` to the default audio device index in
|
||||||
|
* `deviceCollection`.
|
||||||
|
* On failure, `defaultDeviceIndex` is not modified and the latest error is
|
||||||
|
* returned. */
|
||||||
|
static HRESULT FAudio_DefaultDeviceIndex(
|
||||||
|
IMMDeviceCollection *deviceCollection,
|
||||||
|
uint32_t* defaultDeviceIndex
|
||||||
|
) {
|
||||||
|
IMMDevice *device;
|
||||||
|
HRESULT hr;
|
||||||
|
uint32_t i, count;
|
||||||
|
WCHAR *default_guid;
|
||||||
|
WCHAR *device_guid;
|
||||||
|
|
||||||
|
/* Open the default device and get its GUID. */
|
||||||
|
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(
|
||||||
|
device_enumerator,
|
||||||
|
eRender,
|
||||||
|
eConsole,
|
||||||
|
&device
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
hr = IMMDevice_GetId(device, &default_guid);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IMMDevice_Release(device);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Free the default device. */
|
||||||
|
IMMDevice_Release(device);
|
||||||
|
|
||||||
|
hr = IMMDeviceCollection_GetCount(deviceCollection, &count);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
CoTaskMemFree(default_guid);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i += 1)
|
||||||
|
{
|
||||||
|
/* Open the device and get its GUID. */
|
||||||
|
hr = IMMDeviceCollection_Item(deviceCollection, i, &device);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
CoTaskMemFree(default_guid);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
hr = IMMDevice_GetId(device, &device_guid);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
CoTaskMemFree(default_guid);
|
||||||
|
IMMDevice_Release(device);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lstrcmpW(default_guid, device_guid) == 0)
|
||||||
|
{
|
||||||
|
/* Device found. */
|
||||||
|
CoTaskMemFree(default_guid);
|
||||||
|
CoTaskMemFree(device_guid);
|
||||||
|
IMMDevice_Release(device);
|
||||||
|
*defaultDeviceIndex = i;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoTaskMemFree(device_guid);
|
||||||
|
IMMDevice_Release(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This should probably never happen. Just in case, set
|
||||||
|
* `defaultDeviceIndex` to 0 and return S_OK. */
|
||||||
|
CoTaskMemFree(default_guid);
|
||||||
|
*defaultDeviceIndex = 0;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open `device`, corresponding to `deviceIndex`. `deviceIndex` 0 always
|
||||||
|
* corresponds to the default device. XAudio reorders the devices so that the
|
||||||
|
* default device is always at index 0, so we mimick this behavior here by
|
||||||
|
* swapping the devices at indexes 0 and `defaultDeviceIndex`.
|
||||||
|
*/
|
||||||
|
static HRESULT FAudio_OpenDevice(uint32_t deviceIndex, IMMDevice **device)
|
||||||
|
{
|
||||||
|
IMMDeviceCollection *deviceCollection;
|
||||||
|
HRESULT hr;
|
||||||
|
uint32_t defaultDeviceIndex;
|
||||||
|
uint32_t actualIndex;
|
||||||
|
|
||||||
|
*device = NULL;
|
||||||
|
|
||||||
|
hr = IMMDeviceEnumerator_EnumAudioEndpoints(
|
||||||
|
device_enumerator,
|
||||||
|
eRender,
|
||||||
|
DEVICE_STATE_ACTIVE,
|
||||||
|
&deviceCollection
|
||||||
|
);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the default device index. */
|
||||||
|
hr = FAudio_DefaultDeviceIndex(deviceCollection, &defaultDeviceIndex);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IMMDeviceCollection_Release(deviceCollection);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deviceIndex == 0) {
|
||||||
|
/* Default device. */
|
||||||
|
actualIndex = defaultDeviceIndex;
|
||||||
|
} else if (deviceIndex == defaultDeviceIndex) {
|
||||||
|
/* Open the device at index 0 instead of the "correct" one. */
|
||||||
|
actualIndex = 0;
|
||||||
|
} else {
|
||||||
|
/* Otherwise, just open the device. */
|
||||||
|
actualIndex = deviceIndex;
|
||||||
|
|
||||||
|
}
|
||||||
|
hr = IMMDeviceCollection_Item(deviceCollection, actualIndex, device);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
IMMDeviceCollection_Release(deviceCollection);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMMDeviceCollection_Release(deviceCollection);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
void FAudio_PlatformInit(
|
void FAudio_PlatformInit(
|
||||||
FAudio *audio,
|
FAudio *audio,
|
||||||
uint32_t flags,
|
uint32_t flags,
|
||||||
|
@ -223,7 +364,6 @@ void FAudio_PlatformInit(
|
||||||
FAudio_PlatformAddRef();
|
FAudio_PlatformAddRef();
|
||||||
|
|
||||||
*platformDevice = NULL;
|
*platformDevice = NULL;
|
||||||
if (deviceIndex > 0) return;
|
|
||||||
|
|
||||||
args = FAudio_malloc(sizeof(*args));
|
args = FAudio_malloc(sizeof(*args));
|
||||||
FAudio_assert(!!args && "Failed to allocate FAudio thread args!");
|
FAudio_assert(!!args && "Failed to allocate FAudio thread args!");
|
||||||
|
@ -257,13 +397,8 @@ void FAudio_PlatformInit(
|
||||||
data->stopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
data->stopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||||
FAudio_assert(!!data->stopEvent && "Failed to create FAudio thread stop event!");
|
FAudio_assert(!!data->stopEvent && "Failed to create FAudio thread stop event!");
|
||||||
|
|
||||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(
|
hr = FAudio_OpenDevice(deviceIndex, &device);
|
||||||
device_enumerator,
|
FAudio_assert(!FAILED(hr) && "Failed to get audio device!");
|
||||||
eRender,
|
|
||||||
eConsole,
|
|
||||||
&device
|
|
||||||
);
|
|
||||||
FAudio_assert(!FAILED(hr) && "Failed to get default audio endpoint!");
|
|
||||||
|
|
||||||
hr = IMMDevice_Activate(
|
hr = IMMDevice_Activate(
|
||||||
device,
|
device,
|
||||||
|
@ -394,29 +529,35 @@ void FAudio_PlatformRelease()
|
||||||
|
|
||||||
uint32_t FAudio_PlatformGetDeviceCount(void)
|
uint32_t FAudio_PlatformGetDeviceCount(void)
|
||||||
{
|
{
|
||||||
IMMDevice *device;
|
IMMDeviceCollection *device_collection;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
FAudio_PlatformAddRef();
|
FAudio_PlatformAddRef();
|
||||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(
|
|
||||||
|
hr = IMMDeviceEnumerator_EnumAudioEndpoints(
|
||||||
device_enumerator,
|
device_enumerator,
|
||||||
eRender,
|
eRender,
|
||||||
eConsole,
|
DEVICE_STATE_ACTIVE,
|
||||||
&device
|
&device_collection
|
||||||
);
|
);
|
||||||
|
if (FAILED(hr)) {
|
||||||
if (hr == E_NOTFOUND) {
|
|
||||||
FAudio_PlatformRelease();
|
FAudio_PlatformRelease();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAudio_assert(!FAILED(hr) && "Failed to get default audio endpoint!");
|
hr = IMMDeviceCollection_GetCount(device_collection, &count);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
IMMDeviceCollection_Release(device_collection);
|
||||||
|
FAudio_PlatformRelease();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMMDeviceCollection_Release(device_collection);
|
||||||
|
|
||||||
IMMDevice_Release(device);
|
|
||||||
FAudio_PlatformRelease();
|
FAudio_PlatformRelease();
|
||||||
|
|
||||||
return 1;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t FAudio_PlatformGetDeviceDetails(
|
uint32_t FAudio_PlatformGetDeviceDetails(
|
||||||
|
@ -427,31 +568,50 @@ uint32_t FAudio_PlatformGetDeviceDetails(
|
||||||
WAVEFORMATEXTENSIBLE *ext;
|
WAVEFORMATEXTENSIBLE *ext;
|
||||||
IAudioClient *client;
|
IAudioClient *client;
|
||||||
IMMDevice *device;
|
IMMDevice *device;
|
||||||
|
IPropertyStore* properties;
|
||||||
|
PROPVARIANT deviceName;
|
||||||
|
uint32_t count = 0;
|
||||||
uint32_t ret = 0;
|
uint32_t ret = 0;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
WCHAR *str;
|
WCHAR *str;
|
||||||
GUID sub;
|
GUID sub;
|
||||||
|
|
||||||
FAudio_memset(details, 0, sizeof(FAudioDeviceDetails));
|
FAudio_memset(details, 0, sizeof(FAudioDeviceDetails));
|
||||||
if (index > 0) return FAUDIO_E_INVALID_CALL;
|
|
||||||
|
|
||||||
FAudio_PlatformAddRef();
|
FAudio_PlatformAddRef();
|
||||||
|
|
||||||
hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(
|
count = FAudio_PlatformGetDeviceCount();
|
||||||
device_enumerator,
|
if (index >= count)
|
||||||
eRender,
|
{
|
||||||
eConsole,
|
FAudio_PlatformRelease();
|
||||||
&device
|
return FAUDIO_E_INVALID_CALL;
|
||||||
);
|
}
|
||||||
FAudio_assert(!FAILED(hr) && "Failed to get default audio endpoint!");
|
|
||||||
|
|
||||||
details->Role = FAudioGlobalDefaultDevice;
|
hr = FAudio_OpenDevice(index, &device);
|
||||||
|
FAudio_assert(!FAILED(hr) && "Failed to get audio endpoint!");
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
details->Role = FAudioGlobalDefaultDevice;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
details->Role = FAudioNotDefaultDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the Device Display Name */
|
||||||
|
hr = IMMDevice_OpenPropertyStore(device, STGM_READ, &properties);
|
||||||
|
FAudio_assert(!FAILED(hr) && "Failed to open device property store!");
|
||||||
|
hr = IPropertyStore_GetValue(properties, (PROPERTYKEY*)&DEVPKEY_Device_FriendlyName, &deviceName);
|
||||||
|
FAudio_assert(!FAILED(hr) && "Failed to get audio device friendly name!");
|
||||||
|
lstrcpynW((LPWSTR)details->DisplayName, deviceName.pwszVal, ARRAYSIZE(details->DisplayName) - 1);
|
||||||
|
PropVariantClear(&deviceName);
|
||||||
|
IPropertyStore_Release(properties);
|
||||||
|
|
||||||
|
/* Set the Device ID */
|
||||||
hr = IMMDevice_GetId(device, &str);
|
hr = IMMDevice_GetId(device, &str);
|
||||||
FAudio_assert(!FAILED(hr) && "Failed to get audio endpoint id!");
|
FAudio_assert(!FAILED(hr) && "Failed to get audio endpoint id!");
|
||||||
|
lstrcpynW((LPWSTR)details->DeviceID, str, ARRAYSIZE(details->DeviceID) - 1);
|
||||||
lstrcpynW((WCHAR *)details->DeviceID, str, ARRAYSIZE(details->DeviceID) - 1);
|
|
||||||
lstrcpynW((WCHAR *)details->DisplayName, str, ARRAYSIZE(details->DisplayName) - 1);
|
|
||||||
CoTaskMemFree(str);
|
CoTaskMemFree(str);
|
||||||
|
|
||||||
hr = IMMDevice_Activate(
|
hr = IMMDevice_Activate(
|
||||||
|
@ -1053,7 +1213,7 @@ FAUDIOAPI uint32_t XNA_GetSongEnded()
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
FAudioSourceVoice_GetState(songVoice, &state, 0);
|
FAudioSourceVoice_GetState(songVoice, &state, 0);
|
||||||
return state.BuffersQueued == 0;
|
return state.BuffersQueued == 0 && state.SamplesPlayed == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FAUDIOAPI void XNA_EnableVisualization(uint32_t enable)
|
FAUDIOAPI void XNA_EnableVisualization(uint32_t enable)
|
||||||
|
|
|
@ -1382,7 +1382,7 @@ static void skip(vorb *z, int n)
|
||||||
}
|
}
|
||||||
#ifndef STB_VORBIS_NO_STDIO
|
#ifndef STB_VORBIS_NO_STDIO
|
||||||
{
|
{
|
||||||
long x = ftell(z->f);
|
int64_t x = ftell(z->f);
|
||||||
fseek(z->f, x+n, SEEK_SET);
|
fseek(z->f, x+n, SEEK_SET);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue