audio: Don't trust audio drivers to drain pending audio.
This tends to be a frequent spot where drivers hang, and the waits were often unreliable in any case. Instead, our audio thread now alerts the driver that we're done streaming audio (which currently XAudio2 uses to alert the system not to warn about the impending underflow) and then SDL_Delay()'s for a duration that's reasonable to drain the DMA buffers before closing the device.
parent
551cdc8dec
commit
f6a280ab7f
|
@ -191,11 +191,6 @@ SDL_AudioGetDeviceBuf_Default(_THIS)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
SDL_AudioWaitDone_Default(_THIS)
|
|
||||||
{ /* no-op. */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
|
SDL_AudioCaptureFromDevice_Default(_THIS, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
|
@ -207,6 +202,11 @@ SDL_AudioFlushCapture_Default(_THIS)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
SDL_AudioPrepareToClose_Default(_THIS)
|
||||||
|
{ /* no-op. */
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SDL_AudioCloseDevice_Default(_THIS)
|
SDL_AudioCloseDevice_Default(_THIS)
|
||||||
{ /* no-op. */
|
{ /* no-op. */
|
||||||
|
@ -292,9 +292,9 @@ finish_audio_entry_points_init(void)
|
||||||
FILL_STUB(PlayDevice);
|
FILL_STUB(PlayDevice);
|
||||||
FILL_STUB(GetPendingBytes);
|
FILL_STUB(GetPendingBytes);
|
||||||
FILL_STUB(GetDeviceBuf);
|
FILL_STUB(GetDeviceBuf);
|
||||||
FILL_STUB(WaitDone);
|
|
||||||
FILL_STUB(CaptureFromDevice);
|
FILL_STUB(CaptureFromDevice);
|
||||||
FILL_STUB(FlushCapture);
|
FILL_STUB(FlushCapture);
|
||||||
|
FILL_STUB(PrepareToClose);
|
||||||
FILL_STUB(CloseDevice);
|
FILL_STUB(CloseDevice);
|
||||||
FILL_STUB(LockDevice);
|
FILL_STUB(LockDevice);
|
||||||
FILL_STUB(UnlockDevice);
|
FILL_STUB(UnlockDevice);
|
||||||
|
@ -715,6 +715,9 @@ SDL_FinalizeAudioDevice(SDL_AudioDevice *device)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SDL_AtomicSet(&device->shutdown, 1); /* just in case. */
|
||||||
|
SDL_AtomicSet(&device->enabled, 0);
|
||||||
|
|
||||||
/* lock/unlock here so we don't race if the audio thread saw the shutdown
|
/* lock/unlock here so we don't race if the audio thread saw the shutdown
|
||||||
var without locking, and the thread that requested shutdown is now
|
var without locking, and the thread that requested shutdown is now
|
||||||
trying to unlock the mutex while we destroy it. Threading is hard. */
|
trying to unlock the mutex while we destroy it. Threading is hard. */
|
||||||
|
@ -811,9 +814,10 @@ SDL_RunAudio(void *devicep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_audio.impl.PrepareToClose(device);
|
||||||
|
|
||||||
/* Wait for the audio to drain. */
|
/* Wait for the audio to drain. */
|
||||||
/* !!! FIXME: can we rename this WaitDrain? */
|
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
|
||||||
current_audio.impl.WaitDone(device);
|
|
||||||
|
|
||||||
SDL_FinalizeAudioDevice(device);
|
SDL_FinalizeAudioDevice(device);
|
||||||
|
|
||||||
|
@ -1153,7 +1157,7 @@ close_audio_device(SDL_AudioDevice * device)
|
||||||
|
|
||||||
if (!device->iscapture) {
|
if (!device->iscapture) {
|
||||||
const SDL_AudioSpec *spec = &device->spec;
|
const SDL_AudioSpec *spec = &device->spec;
|
||||||
delay = ((spec.samples * 1000) / spec.freq) * 2;
|
delay = ((spec->samples * 1000) / spec->freq) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock to make sure an audio callback doesn't fire after we return.
|
/* Lock to make sure an audio callback doesn't fire after we return.
|
||||||
|
|
|
@ -79,9 +79,9 @@ typedef struct SDL_AudioDriverImpl
|
||||||
void (*PlayDevice) (_THIS);
|
void (*PlayDevice) (_THIS);
|
||||||
int (*GetPendingBytes) (_THIS);
|
int (*GetPendingBytes) (_THIS);
|
||||||
Uint8 *(*GetDeviceBuf) (_THIS);
|
Uint8 *(*GetDeviceBuf) (_THIS);
|
||||||
void (*WaitDone) (_THIS);
|
|
||||||
int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
|
int (*CaptureFromDevice) (_THIS, void *buffer, int buflen);
|
||||||
void (*FlushCapture) (_THIS);
|
void (*FlushCapture) (_THIS);
|
||||||
|
void (*PrepareToClose) (_THIS); /**< Called between run and draining wait for playback devices */
|
||||||
void (*CloseDevice) (_THIS);
|
void (*CloseDevice) (_THIS);
|
||||||
void (*LockDevice) (_THIS);
|
void (*LockDevice) (_THIS);
|
||||||
void (*UnlockDevice) (_THIS);
|
void (*UnlockDevice) (_THIS);
|
||||||
|
|
|
@ -185,13 +185,6 @@ ARTS_PlayDevice(_THIS)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
ARTS_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
/* !!! FIXME: camp here until buffer drains... SDL_Delay(???); */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Uint8 *
|
static Uint8 *
|
||||||
ARTS_GetDeviceBuf(_THIS)
|
ARTS_GetDeviceBuf(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -356,7 +349,6 @@ ARTS_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->WaitDevice = ARTS_WaitDevice;
|
impl->WaitDevice = ARTS_WaitDevice;
|
||||||
impl->GetDeviceBuf = ARTS_GetDeviceBuf;
|
impl->GetDeviceBuf = ARTS_GetDeviceBuf;
|
||||||
impl->CloseDevice = ARTS_CloseDevice;
|
impl->CloseDevice = ARTS_CloseDevice;
|
||||||
impl->WaitDone = ARTS_WaitDone;
|
|
||||||
impl->Deinitialize = ARTS_Deinitialize;
|
impl->Deinitialize = ARTS_Deinitialize;
|
||||||
impl->OnlyHasDefaultOutputDevice = 1;
|
impl->OnlyHasDefaultOutputDevice = 1;
|
||||||
|
|
||||||
|
|
|
@ -307,22 +307,6 @@ DSOUND_GetDeviceBuf(_THIS)
|
||||||
return (this->hidden->locked_buf);
|
return (this->hidden->locked_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
DSOUND_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
Uint8 *stream = DSOUND_GetDeviceBuf(this);
|
|
||||||
|
|
||||||
/* Wait for the playing chunk to finish */
|
|
||||||
if (stream != NULL) {
|
|
||||||
SDL_memset(stream, this->spec.silence, this->spec.size);
|
|
||||||
DSOUND_PlayDevice(this);
|
|
||||||
}
|
|
||||||
DSOUND_WaitDevice(this);
|
|
||||||
|
|
||||||
/* Stop the looping sound buffer */
|
|
||||||
IDirectSoundBuffer_Stop(this->hidden->mixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
|
@ -600,7 +584,6 @@ DSOUND_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->OpenDevice = DSOUND_OpenDevice;
|
impl->OpenDevice = DSOUND_OpenDevice;
|
||||||
impl->PlayDevice = DSOUND_PlayDevice;
|
impl->PlayDevice = DSOUND_PlayDevice;
|
||||||
impl->WaitDevice = DSOUND_WaitDevice;
|
impl->WaitDevice = DSOUND_WaitDevice;
|
||||||
impl->WaitDone = DSOUND_WaitDone;
|
|
||||||
impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
|
impl->GetDeviceBuf = DSOUND_GetDeviceBuf;
|
||||||
impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
|
impl->CaptureFromDevice = DSOUND_CaptureFromDevice;
|
||||||
impl->FlushCapture = DSOUND_FlushCapture;
|
impl->FlushCapture = DSOUND_FlushCapture;
|
||||||
|
|
|
@ -151,13 +151,6 @@ SDL_FS_PlayDevice(_THIS)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
SDL_FS_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
this->hidden->stream->Wait(this->hidden->stream,
|
|
||||||
this->hidden->mixsamples * FUSION_BUFFERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Uint8 *
|
static Uint8 *
|
||||||
SDL_FS_GetDeviceBuf(_THIS)
|
SDL_FS_GetDeviceBuf(_THIS)
|
||||||
|
@ -319,7 +312,6 @@ SDL_FS_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->WaitDevice = SDL_FS_WaitDevice;
|
impl->WaitDevice = SDL_FS_WaitDevice;
|
||||||
impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
|
impl->GetDeviceBuf = SDL_FS_GetDeviceBuf;
|
||||||
impl->CloseDevice = SDL_FS_CloseDevice;
|
impl->CloseDevice = SDL_FS_CloseDevice;
|
||||||
impl->WaitDone = SDL_FS_WaitDone;
|
|
||||||
impl->Deinitialize = SDL_FS_Deinitialize;
|
impl->Deinitialize = SDL_FS_Deinitialize;
|
||||||
impl->OnlyHasDefaultOutputDevice = 1;
|
impl->OnlyHasDefaultOutputDevice = 1;
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,6 @@ PSPAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->PlayDevice = PSPAUDIO_PlayDevice;
|
impl->PlayDevice = PSPAUDIO_PlayDevice;
|
||||||
impl->WaitDevice = PSPAUDIO_WaitDevice;
|
impl->WaitDevice = PSPAUDIO_WaitDevice;
|
||||||
impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf;
|
impl->GetDeviceBuf = PSPAUDIO_GetDeviceBuf;
|
||||||
impl->WaitDone = PSPAUDIO_WaitDevice;
|
|
||||||
impl->CloseDevice = PSPAUDIO_CloseDevice;
|
impl->CloseDevice = PSPAUDIO_CloseDevice;
|
||||||
impl->ThreadInit = PSPAUDIO_ThreadInit;
|
impl->ThreadInit = PSPAUDIO_ThreadInit;
|
||||||
|
|
||||||
|
|
|
@ -368,28 +368,6 @@ PULSEAUDIO_PlayDevice(_THIS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
PULSEAUDIO_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
if (SDL_AtomicGet(&this->enabled)) {
|
|
||||||
struct SDL_PrivateAudioData *h = this->hidden;
|
|
||||||
pa_operation *o = PULSEAUDIO_pa_stream_drain(h->stream, stream_operation_complete_no_op, NULL);
|
|
||||||
if (o) {
|
|
||||||
while (PULSEAUDIO_pa_operation_get_state(o) != PA_OPERATION_DONE) {
|
|
||||||
if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
|
|
||||||
PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
|
|
||||||
PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {
|
|
||||||
PULSEAUDIO_pa_operation_cancel(o);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PULSEAUDIO_pa_operation_unref(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Uint8 *
|
static Uint8 *
|
||||||
PULSEAUDIO_GetDeviceBuf(_THIS)
|
PULSEAUDIO_GetDeviceBuf(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -776,7 +754,6 @@ PULSEAUDIO_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->WaitDevice = PULSEAUDIO_WaitDevice;
|
impl->WaitDevice = PULSEAUDIO_WaitDevice;
|
||||||
impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf;
|
impl->GetDeviceBuf = PULSEAUDIO_GetDeviceBuf;
|
||||||
impl->CloseDevice = PULSEAUDIO_CloseDevice;
|
impl->CloseDevice = PULSEAUDIO_CloseDevice;
|
||||||
impl->WaitDone = PULSEAUDIO_WaitDone;
|
|
||||||
impl->Deinitialize = PULSEAUDIO_Deinitialize;
|
impl->Deinitialize = PULSEAUDIO_Deinitialize;
|
||||||
impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice;
|
impl->CaptureFromDevice = PULSEAUDIO_CaptureFromDevice;
|
||||||
impl->FlushCapture = PULSEAUDIO_FlushCapture;
|
impl->FlushCapture = PULSEAUDIO_FlushCapture;
|
||||||
|
|
|
@ -708,24 +708,6 @@ QSA_DetectDevices(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
QSA_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
if (!this->hidden->iscapture) {
|
|
||||||
if (this->hidden->audio_handle != NULL) {
|
|
||||||
/* Wait till last fragment is played and stop channel */
|
|
||||||
snd_pcm_plugin_flush(this->hidden->audio_handle,
|
|
||||||
SND_PCM_CHANNEL_PLAYBACK);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this->hidden->audio_handle != NULL) {
|
|
||||||
/* Discard all unread data and stop channel */
|
|
||||||
snd_pcm_plugin_flush(this->hidden->audio_handle,
|
|
||||||
SND_PCM_CHANNEL_CAPTURE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
QSA_Deinitialize(void)
|
QSA_Deinitialize(void)
|
||||||
{
|
{
|
||||||
|
@ -759,7 +741,6 @@ QSA_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->PlayDevice = QSA_PlayDevice;
|
impl->PlayDevice = QSA_PlayDevice;
|
||||||
impl->GetDeviceBuf = QSA_GetDeviceBuf;
|
impl->GetDeviceBuf = QSA_GetDeviceBuf;
|
||||||
impl->CloseDevice = QSA_CloseDevice;
|
impl->CloseDevice = QSA_CloseDevice;
|
||||||
impl->WaitDone = QSA_WaitDone;
|
|
||||||
impl->Deinitialize = QSA_Deinitialize;
|
impl->Deinitialize = QSA_Deinitialize;
|
||||||
impl->LockDevice = NULL;
|
impl->LockDevice = NULL;
|
||||||
impl->UnlockDevice = NULL;
|
impl->UnlockDevice = NULL;
|
||||||
|
|
|
@ -170,16 +170,11 @@ SNDIO_GetDeviceBuf(_THIS)
|
||||||
return this->hidden->mixbuf;
|
return this->hidden->mixbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
SNDIO_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
SNDIO_sio_stop(this->hidden->dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
SNDIO_CloseDevice(_THIS)
|
SNDIO_CloseDevice(_THIS)
|
||||||
{
|
{
|
||||||
if ( this->hidden->dev != NULL ) {
|
if ( this->hidden->dev != NULL ) {
|
||||||
|
SNDIO_sio_stop(this->hidden->dev);
|
||||||
SNDIO_sio_close(this->hidden->dev);
|
SNDIO_sio_close(this->hidden->dev);
|
||||||
}
|
}
|
||||||
SDL_free(this->hidden->mixbuf);
|
SDL_free(this->hidden->mixbuf);
|
||||||
|
@ -304,7 +299,6 @@ SNDIO_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->WaitDevice = SNDIO_WaitDevice;
|
impl->WaitDevice = SNDIO_WaitDevice;
|
||||||
impl->PlayDevice = SNDIO_PlayDevice;
|
impl->PlayDevice = SNDIO_PlayDevice;
|
||||||
impl->GetDeviceBuf = SNDIO_GetDeviceBuf;
|
impl->GetDeviceBuf = SNDIO_GetDeviceBuf;
|
||||||
impl->WaitDone = SNDIO_WaitDone;
|
|
||||||
impl->CloseDevice = SNDIO_CloseDevice;
|
impl->CloseDevice = SNDIO_CloseDevice;
|
||||||
impl->Deinitialize = SNDIO_Deinitialize;
|
impl->Deinitialize = SNDIO_Deinitialize;
|
||||||
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: sndio can handle multiple devices. */
|
impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: sndio can handle multiple devices. */
|
||||||
|
|
|
@ -135,24 +135,6 @@ WINMM_PlayDevice(_THIS)
|
||||||
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
this->hidden->next_buffer = (this->hidden->next_buffer + 1) % NUM_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
WINMM_WaitDone(_THIS)
|
|
||||||
{
|
|
||||||
int i, left;
|
|
||||||
|
|
||||||
do {
|
|
||||||
left = NUM_BUFFERS;
|
|
||||||
for (i = 0; i < NUM_BUFFERS; ++i) {
|
|
||||||
if (this->hidden->wavebuf[i].dwFlags & WHDR_DONE) {
|
|
||||||
--left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (left > 0) {
|
|
||||||
SDL_Delay(100);
|
|
||||||
}
|
|
||||||
} while (left > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
WINMM_CaptureFromDevice(_THIS, void *buffer, int buflen)
|
||||||
{
|
{
|
||||||
|
@ -422,7 +404,6 @@ WINMM_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->OpenDevice = WINMM_OpenDevice;
|
impl->OpenDevice = WINMM_OpenDevice;
|
||||||
impl->PlayDevice = WINMM_PlayDevice;
|
impl->PlayDevice = WINMM_PlayDevice;
|
||||||
impl->WaitDevice = WINMM_WaitDevice;
|
impl->WaitDevice = WINMM_WaitDevice;
|
||||||
impl->WaitDone = WINMM_WaitDone;
|
|
||||||
impl->GetDeviceBuf = WINMM_GetDeviceBuf;
|
impl->GetDeviceBuf = WINMM_GetDeviceBuf;
|
||||||
impl->CaptureFromDevice = WINMM_CaptureFromDevice;
|
impl->CaptureFromDevice = WINMM_CaptureFromDevice;
|
||||||
impl->FlushCapture = WINMM_FlushCapture;
|
impl->FlushCapture = WINMM_FlushCapture;
|
||||||
|
|
|
@ -232,28 +232,14 @@ XAUDIO2_WaitDevice(_THIS)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
XAUDIO2_WaitDone(_THIS)
|
XAUDIO2_PrepareToClose(_THIS)
|
||||||
{
|
{
|
||||||
IXAudio2SourceVoice *source = this->hidden->source;
|
IXAudio2SourceVoice *source = this->hidden->source;
|
||||||
XAUDIO2_VOICE_STATE state;
|
if (source) {
|
||||||
SDL_assert(!SDL_AtomicGet(&this->enabled)); /* flag that stops playing. */
|
IXAudio2SourceVoice_Discontinuity(source);
|
||||||
IXAudio2SourceVoice_Discontinuity(source);
|
|
||||||
#if SDL_XAUDIO2_WIN8
|
|
||||||
IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
|
|
||||||
#else
|
|
||||||
IXAudio2SourceVoice_GetState(source, &state);
|
|
||||||
#endif
|
|
||||||
while (state.BuffersQueued > 0) {
|
|
||||||
SDL_SemWait(this->hidden->semaphore);
|
|
||||||
#if SDL_XAUDIO2_WIN8
|
|
||||||
IXAudio2SourceVoice_GetState(source, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
|
|
||||||
#else
|
|
||||||
IXAudio2SourceVoice_GetState(source, &state);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
XAUDIO2_CloseDevice(_THIS)
|
XAUDIO2_CloseDevice(_THIS)
|
||||||
{
|
{
|
||||||
|
@ -489,7 +475,7 @@ XAUDIO2_Init(SDL_AudioDriverImpl * impl)
|
||||||
impl->OpenDevice = XAUDIO2_OpenDevice;
|
impl->OpenDevice = XAUDIO2_OpenDevice;
|
||||||
impl->PlayDevice = XAUDIO2_PlayDevice;
|
impl->PlayDevice = XAUDIO2_PlayDevice;
|
||||||
impl->WaitDevice = XAUDIO2_WaitDevice;
|
impl->WaitDevice = XAUDIO2_WaitDevice;
|
||||||
impl->WaitDone = XAUDIO2_WaitDone;
|
impl->PrepareToClose = XAUDIO2_PrepareToClose;
|
||||||
impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
|
impl->GetDeviceBuf = XAUDIO2_GetDeviceBuf;
|
||||||
impl->CloseDevice = XAUDIO2_CloseDevice;
|
impl->CloseDevice = XAUDIO2_CloseDevice;
|
||||||
impl->Deinitialize = XAUDIO2_Deinitialize;
|
impl->Deinitialize = XAUDIO2_Deinitialize;
|
||||||
|
|
Loading…
Reference in New Issue