1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Audio Library Context wrapper
// Copyright (C) 2021 Nguyễn Gia Phong
//
// This file is part of zeal.
//
// Zeal is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Zeal is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with zeal. If not, see <https://www.gnu.org/licenses/>.
usingnamespace @cImport({
@cInclude("AL/alc.h");
@cInclude("AL/alext.h");
});
/// Opaque device handle.
pub const Device = ALCdevice;
/// Opaque context handle.
pub const Context = ALCcontext;
pub const Error = error {
/// Invalid device handle.
InvalidDevice,
/// Invalid context handle.
InvalidContext,
/// Invalid enum parameter passed to an ALC call.
InvalidEnum,
/// Invalid value parameter passed to an ALC call.
InvalidValue,
/// Out of memory.
OutOfMemory,
};
pub const FALSE = ALC_FALSE;
pub const TRUE = ALC_TRUE;
pub const DONT_CARE = ALC_DONT_CATE_SOFT;
/// Context creation key to specify whether to enable HRTF
/// (either `FALSE`, `TRUE` or `DONT_CARE`).
pub const HRTF = ALC_HRTF_SOFT;
/// Create and attach a context to the given device.
pub fn createContext(device: *Device, attrlist: [:0]const i32) Error!*Context {
if (alcCreateContext(device, attrlist.ptr)) |context|
return context;
return switch (alcGetError(device)) {
ALC_INVALID_DEVICE => Error.InvalidDevice,
ALC_INVALID_VALUE => Error.InvalidValue,
else => unreachable,
};
}
/// Make the given context the active process-wide context.
/// Passing NULL clears the active context.
pub fn makeContextCurrent(context: ?*Context) Error!void {
if (alcMakeContextCurrent(context) == TRUE)
return;
if (alcGetError(null) == ALC_INVALID_CONTEXT)
return Error.InvalidContext;
unreachable;
}
/// Remove a context from its device and destroys it.
pub fn destroyContext(context: *Context) Error!void {
alcDestroyContext(context);
if (alcGetError(null) == ALC_INVALID_CONTEXT)
return Error.InvalidContext;
}
/// Return the currently active context.
pub fn getCurrentContext() ?*Context {
return alcGetCurrentContext();
}
/// Return the device that a particular context is attached to.
pub fn getContextsDevice(context: *Context) Error!*Device {
if (alcGetContextsDevice(context)) |device|
return device;
if (alcGetError(null) == ALC_INVALID_CONTEXT)
return Error.InvalidContext;
unreachable;
}
/// Open the named playback device.
pub fn openDevice(name: ?[:0]const u8) Error!*Device {
const name_ptr = if (name == null) null else name.?.ptr;
if (alcOpenDevice(name_ptr)) |device|
return device;
return switch (alcGetError(null)) {
ALC_INVALID_VALUE => Error.InvalidValue,
ALC_OUT_OF_MEMORY => Error.OutOfMemory,
else => unreachable,
};
}
/// Close the given playback device.
pub fn closeDevice(device: *Device) Error!void {
if (alcCloseDevice(device) == TRUE)
return;
if (alcGetError(device) == ALC_INVALID_DEVICE)
return Error.InvalidDevice;
unreachable;
}
pub fn getInt(device: *Device, param: ALCenum) Error!i32 {
var data: i32 = undefined;
alcGetIntegerv(device, param, 1, &data);
return switch (alcGetError(device)) {
ALC_NO_ERROR => data,
ALC_INVALID_VALUE => Error.InvalidValue,
ALC_INVALID_ENUM => Error.InvalidEnum,
ALC_INVALID_DEVICE => Error.InvalidDevice,
ALC_INVALID_CONTEXT => Error.InvalidContext,
else => unreachable,
};
}
|