Improved handling of buffer playback

This commit is contained in:
Mike H 2018-02-16 18:29:06 +00:00 committed by GitHub
parent c53beed7f2
commit 7b4af3a136
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -12,6 +12,8 @@
static Service g_audoutSrv; static Service g_audoutSrv;
static Service g_audoutIAudioOut; static Service g_audoutIAudioOut;
static Handle g_audoutBufferEventHandle = INVALID_HANDLE;
static u32 g_sampleRate = 0; static u32 g_sampleRate = 0;
static u32 g_channelCount = 0; static u32 g_channelCount = 0;
static PcmFormat g_pcmFormat = PcmFormat_Invalid; static PcmFormat g_pcmFormat = PcmFormat_Invalid;
@ -32,9 +34,14 @@ Result audoutInitialize(void)
char DeviceNameIn[DEVICE_NAME_LENGTH] = {0}; char DeviceNameIn[DEVICE_NAME_LENGTH] = {0};
char DeviceNameOut[DEVICE_NAME_LENGTH] = {0}; char DeviceNameOut[DEVICE_NAME_LENGTH] = {0};
// Open audio output device
rc = audoutOpenAudioOut(DeviceNameIn, DeviceNameOut, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, &g_sampleRate, &g_channelCount, &g_pcmFormat, &g_deviceState); rc = audoutOpenAudioOut(DeviceNameIn, DeviceNameOut, DEFAULT_SAMPLE_RATE, DEFAULT_CHANNEL_COUNT, &g_sampleRate, &g_channelCount, &g_pcmFormat, &g_deviceState);
} }
// Register global handle for buffer events
if (R_SUCCEEDED(rc))
rc = audoutRegisterBufferEvent(&g_audoutBufferEventHandle);
if (R_FAILED(rc)) if (R_FAILED(rc))
audoutExit(); audoutExit();
@ -43,6 +50,11 @@ Result audoutInitialize(void)
void audoutExit(void) void audoutExit(void)
{ {
if (g_audoutBufferEventHandle != INVALID_HANDLE) {
svcCloseHandle(g_audoutBufferEventHandle);
g_audoutBufferEventHandle = INVALID_HANDLE;
}
g_sampleRate = 0; g_sampleRate = 0;
g_channelCount = 0; g_channelCount = 0;
g_pcmFormat = PcmFormat_Invalid; g_pcmFormat = PcmFormat_Invalid;
@ -68,35 +80,27 @@ AudioOutState audoutGetDeviceState(void) {
return g_deviceState; return g_deviceState;
} }
bool audoutPlayBuffer(Handle *event, AudioOutBuffer *source, AudioOutBuffer *released, u64 duration) { void audoutPlayBuffer(AudioOutBuffer *source, AudioOutBuffer *released) {
bool timeout = false; // Try to push the supplied buffer to the audio output device
u64 time_now = svcGetSystemTick(); Result do_append = audoutAppendAudioOutBuffer(source);
while ((svcGetSystemTick() - time_now) < duration) if (R_SUCCEEDED(do_append))
{ {
Result do_wait = svcWaitSynchronizationSingle(*event, U64_MAX); // Wait on the buffer event handle
Result do_wait = svcWaitSynchronizationSingle(g_audoutBufferEventHandle, U64_MAX);
if (R_SUCCEEDED(do_wait)) if (R_SUCCEEDED(do_wait))
{ {
svcResetSignal(*event); svcResetSignal(g_audoutBufferEventHandle);
u32 released_count = 0; u32 released_count = 0;
Result do_release = audoutGetReleasedAudioOutBuffer(released, &released_count); Result do_release = audoutGetReleasedAudioOutBuffer(released, &released_count);
// Ensure that all buffers are released and return the last one only
while (R_SUCCEEDED(do_release) && (released_count > 0)) while (R_SUCCEEDED(do_release) && (released_count > 0))
{
do_release = audoutGetReleasedAudioOutBuffer(released, &released_count); do_release = audoutGetReleasedAudioOutBuffer(released, &released_count);
audoutAppendAudioOutBuffer(source);
}
}
else
{
timeout = true;
break;
} }
} }
return timeout;
} }
Result audoutListAudioOuts(char *DeviceNames, u32 *DeviceNamesCount) { Result audoutListAudioOuts(char *DeviceNames, u32 *DeviceNamesCount) {