WASAPI: pass the latency test

See #2
This commit is contained in:
Andrew Kelley 2015-09-03 10:26:45 -07:00
parent 1381cf21d3
commit f422fcddf3
2 changed files with 35 additions and 4 deletions

View file

@ -1167,6 +1167,14 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) {
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
} }
} }
REFERENCE_TIME max_latency_ref_time;
if (FAILED(hr = IAudioClient_GetStreamLatency(osw->audio_client, &max_latency_ref_time))) {
return SoundIoErrorOpeningDevice;
}
double max_latency_sec = from_reference_time(max_latency_ref_time);
osw->min_padding_frames = (max_latency_sec * outstream->sample_rate) + 0.5;
if (FAILED(hr = IAudioClient_GetBufferSize(osw->audio_client, &osw->buffer_frame_count))) { if (FAILED(hr = IAudioClient_GetBufferSize(osw->audio_client, &osw->buffer_frame_count))) {
return SoundIoErrorOpeningDevice; return SoundIoErrorOpeningDevice;
} }
@ -1232,7 +1240,8 @@ void outstream_shared_run(SoundIoOutStreamPrivate *os) {
outstream->error_callback(outstream, SoundIoErrorStreaming); outstream->error_callback(outstream, SoundIoErrorStreaming);
return; return;
} }
outstream->write_callback(outstream, 0, osw->writable_frame_count); int frame_count_min = max(0, (int)osw->min_padding_frames - (int)frames_used);
outstream->write_callback(outstream, frame_count_min, osw->writable_frame_count);
if (FAILED(hr = IAudioClient_Start(osw->audio_client))) { if (FAILED(hr = IAudioClient_Start(osw->audio_client))) {
outstream->error_callback(outstream, SoundIoErrorStreaming); outstream->error_callback(outstream, SoundIoErrorStreaming);
@ -1295,7 +1304,8 @@ void outstream_shared_run(SoundIoOutStreamPrivate *os) {
if (osw->writable_frame_count > 0) { if (osw->writable_frame_count > 0) {
if (frames_used == 0 && !reset_buffer) if (frames_used == 0 && !reset_buffer)
outstream->underflow_callback(outstream); outstream->underflow_callback(outstream);
outstream->write_callback(outstream, 0, osw->writable_frame_count); int frame_count_min = max(0, (int)osw->min_padding_frames - (int)frames_used);
outstream->write_callback(outstream, frame_count_min, osw->writable_frame_count);
} }
} }
} }
@ -1526,7 +1536,17 @@ static int outstream_clear_buffer_wasapi(struct SoundIoPrivate *si, struct Sound
static int outstream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, static int outstream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os,
double *out_latency) double *out_latency)
{ {
soundio_panic("TODO"); SoundIoOutStream *outstream = &os->pub;
SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi;
HRESULT hr;
UINT32 frames_used;
if (FAILED(hr = IAudioClient_GetCurrentPadding(osw->audio_client, &frames_used))) {
return SoundIoErrorStreaming;
}
*out_latency = frames_used / (double)outstream->sample_rate;
return 0;
} }
static void instream_thread_deinit(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { static void instream_thread_deinit(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {
@ -1929,7 +1949,17 @@ static int instream_end_read_wasapi(struct SoundIoPrivate *si, struct SoundIoInS
static int instream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, static int instream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is,
double *out_latency) double *out_latency)
{ {
soundio_panic("TODO"); SoundIoInStream *instream = &is->pub;
SoundIoInStreamWasapi *isw = &is->backend_data.wasapi;
HRESULT hr;
UINT32 frames_used;
if (FAILED(hr = IAudioClient_GetCurrentPadding(isw->audio_client, &frames_used))) {
return SoundIoErrorStreaming;
}
*out_latency = frames_used / (double)instream->sample_rate;
return 0;
} }

View file

@ -75,6 +75,7 @@ struct SoundIoOutStreamWasapi {
bool open_complete; bool open_complete;
int open_err; int open_err;
bool started; bool started;
UINT32 min_padding_frames;
SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS];
}; };