sysaudio:wasapi: wait for audio client to be ready
This commit is contained in:
parent
a3d23b199d
commit
dc3f4b4c00
2 changed files with 52 additions and 11 deletions
|
|
@ -472,6 +472,7 @@ pub const Context = struct {
|
|||
|
||||
hr = audio_client.?.Initialize(
|
||||
.SHARED,
|
||||
win32.AUDCLNT_STREAMFLAGS_EVENTCALLBACK |
|
||||
win32.AUDCLNT_STREAMFLAGS_NOPERSIST,
|
||||
0,
|
||||
0,
|
||||
|
|
@ -526,6 +527,18 @@ pub const Context = struct {
|
|||
else => return error.OpeningDevice,
|
||||
}
|
||||
|
||||
var ready_event = win32.CreateEventA(null, 0, 0, null) orelse return error.SystemResources;
|
||||
hr = audio_client.?.SetEventHandle(ready_event);
|
||||
switch (hr) {
|
||||
win32.S_OK => {},
|
||||
win32.E_INVALIDARG => unreachable,
|
||||
win32.AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED => unreachable,
|
||||
win32.AUDCLNT_E_NOT_INITIALIZED => unreachable,
|
||||
win32.AUDCLNT_E_DEVICE_INVALIDATED => return error.OpeningDevice,
|
||||
win32.AUDCLNT_E_SERVICE_NOT_RUNNING => return error.OpeningDevice,
|
||||
else => return error.OpeningDevice,
|
||||
}
|
||||
|
||||
return .{
|
||||
.wasapi = .{
|
||||
.thread = undefined,
|
||||
|
|
@ -538,6 +551,7 @@ pub const Context = struct {
|
|||
.simple_volume = simple_volume,
|
||||
.imm_device = imm_device,
|
||||
.render_client = render_client,
|
||||
.ready_event = ready_event,
|
||||
.is_paused = false,
|
||||
.vol = 1.0,
|
||||
.aborted = .{ .value = false },
|
||||
|
|
@ -595,6 +609,7 @@ pub const Player = struct {
|
|||
imm_device: ?*win32.IMMDevice,
|
||||
audio_client: ?*win32.IAudioClient,
|
||||
render_client: ?*win32.IAudioRenderClient,
|
||||
ready_event: win32.HANDLE,
|
||||
aborted: std.atomic.Atomic(bool),
|
||||
is_paused: bool,
|
||||
vol: f32,
|
||||
|
|
@ -634,8 +649,10 @@ pub const Player = struct {
|
|||
}
|
||||
|
||||
while (!self.aborted.load(.Unordered)) {
|
||||
var frames_buf: u32 = 0;
|
||||
hr = self.audio_client.?.GetBufferSize(&frames_buf);
|
||||
_ = win32.WaitForSingleObject(self.ready_event, win32.INFINITE);
|
||||
|
||||
var buf_frames: u32 = 0;
|
||||
hr = self.audio_client.?.GetBufferSize(&buf_frames);
|
||||
switch (hr) {
|
||||
win32.S_OK => {},
|
||||
win32.E_POINTER => unreachable,
|
||||
|
|
@ -645,8 +662,8 @@ pub const Player = struct {
|
|||
else => unreachable,
|
||||
}
|
||||
|
||||
var frames_used: u32 = 0;
|
||||
hr = self.audio_client.?.GetCurrentPadding(&frames_used);
|
||||
var padding_frames: u32 = 0;
|
||||
hr = self.audio_client.?.GetCurrentPadding(&padding_frames);
|
||||
switch (hr) {
|
||||
win32.S_OK => {},
|
||||
win32.E_POINTER => unreachable,
|
||||
|
|
@ -655,10 +672,10 @@ pub const Player = struct {
|
|||
win32.AUDCLNT_E_SERVICE_NOT_RUNNING => return,
|
||||
else => unreachable,
|
||||
}
|
||||
const writable_frame_count = frames_buf - frames_used;
|
||||
if (writable_frame_count > 0) {
|
||||
const frames = buf_frames - padding_frames;
|
||||
if (frames > 0) {
|
||||
var data: [*]u8 = undefined;
|
||||
hr = self.render_client.?.GetBuffer(writable_frame_count, @ptrCast(?*?*u8, &data));
|
||||
hr = self.render_client.?.GetBuffer(frames, @ptrCast(?*?*u8, &data));
|
||||
switch (hr) {
|
||||
win32.S_OK => {},
|
||||
win32.E_POINTER => unreachable,
|
||||
|
|
@ -676,8 +693,9 @@ pub const Player = struct {
|
|||
ch.*.ptr = data + self.format().frameSize(i);
|
||||
}
|
||||
|
||||
self.writeFn(parent, writable_frame_count);
|
||||
hr = self.render_client.?.ReleaseBuffer(writable_frame_count, 0);
|
||||
self.writeFn(parent, frames);
|
||||
|
||||
hr = self.render_client.?.ReleaseBuffer(frames, 0);
|
||||
switch (hr) {
|
||||
win32.S_OK => {},
|
||||
win32.E_INVALIDARG => unreachable,
|
||||
|
|
|
|||
|
|
@ -217,6 +217,22 @@ pub extern "ole32" fn CoCreateInstance(
|
|||
riid: *const Guid,
|
||||
ppv: ?*?*anyopaque,
|
||||
) callconv(WINAPI) HRESULT;
|
||||
pub extern "kernel32" fn CreateEventA(
|
||||
lpEventAttributes: ?*SECURITY_ATTRIBUTES,
|
||||
bManualReset: BOOL,
|
||||
bInitialState: BOOL,
|
||||
lpName: ?[*:0]const u8,
|
||||
) callconv(WINAPI) ?HANDLE;
|
||||
pub extern "kernel32" fn WaitForSingleObject(
|
||||
hHandle: ?HANDLE,
|
||||
dwMilliseconds: u32,
|
||||
) callconv(WINAPI) u32;
|
||||
pub const INFINITE = 4294967295;
|
||||
pub const SECURITY_ATTRIBUTES = extern struct {
|
||||
nLength: u32,
|
||||
lpSecurityDescriptor: ?*anyopaque,
|
||||
bInheritHandle: BOOL,
|
||||
};
|
||||
pub const IID_IUnknown = &Guid.initString("00000000-0000-0000-c000-000000000046");
|
||||
pub const IUnknown = extern struct {
|
||||
pub const VTable = extern struct {
|
||||
|
|
@ -1576,7 +1592,14 @@ pub const IMMEndpoint = extern struct {
|
|||
}
|
||||
pub usingnamespace MethodMixin(@This());
|
||||
};
|
||||
pub const AUDCLNT_STREAMFLAGS_CROSSPROCESS = 65536;
|
||||
pub const AUDCLNT_STREAMFLAGS_LOOPBACK = 131072;
|
||||
pub const AUDCLNT_STREAMFLAGS_EVENTCALLBACK = 262144;
|
||||
pub const AUDCLNT_STREAMFLAGS_NOPERSIST = 524288;
|
||||
pub const AUDCLNT_STREAMFLAGS_RATEADJUST = 1048576;
|
||||
pub const AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY = 134217728;
|
||||
pub const AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM = 2147483648;
|
||||
pub const AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED = 268435456;
|
||||
pub const PKEY_Device_FriendlyName = PROPERTYKEY{ .fmtid = Guid.initString("a45c254e-df1c-4efd-8020-67d146a850e0"), .pid = 14 };
|
||||
pub const CLSID_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = &Guid.initString("00000003-0000-0010-8000-00aa00389b71");
|
||||
pub const SPEAKER_FRONT_LEFT = 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue