-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathlib_audio.lua
More file actions
181 lines (152 loc) · 8.2 KB
/
Copy pathlib_audio.lua
File metadata and controls
181 lines (152 loc) · 8.2 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
__source 'lua/lua_audio_event.cpp'
require './common/internal_import'
ffi.cdef [[
typedef struct {
void* host_;
void* nativeEvent_;
void* nativeChannel_;
mat4x4 transform_;
vec3 velocity_;
float volume;
float pitch;
float cameraInteriorMultiplier;
float cameraExteriorMultiplier;
float cameraTrackMultiplier;
int channelID_;
bool inAutoLoopMode;
bool reverbResponse_;
} audioevent;
]]
local __audioEventKeepAlive = {}
local __audioEventRelease = function (e) __util.native('lj_audioevent_gc', e) end
ac.AudioEvent = setmetatable({
fromFile = function(params, reverbResponse)
local created = __util.native('lj_audioevent_new', 0, params, reverbResponse and true or false, params.group and params.group.channelID_ or 0)
created = ffi.gc(created, __audioEventRelease)
__audioEventKeepAlive[#__audioEventKeepAlive + 1] = created
return created
end,
group = function(params, reverbResponse)
local created = __util.native('lj_audioevent_new', 1, params, reverbResponse and true or false, params.group and params.group.channelID_ or 0)
created = ffi.gc(created, __audioEventRelease)
__audioEventKeepAlive[#__audioEventKeepAlive + 1] = created
return created
end
}, {
__call = function(_, params, reverbResponse, useOcclusion)
local created = __util.native('lj_audioevent_new', -1, params, reverbResponse and true or false, useOcclusion and true or false)
created = ffi.gc(created, __audioEventRelease)
__audioEventKeepAlive[#__audioEventKeepAlive + 1] = created
return created
end
})
---Audio event is a audio emitter which uses a certain event from one of loaded FMOD soundbanks.
---@class ac.AudioEvent
---@field volume number @Audio volume, from 0 to 1 (can go above too, but clipping might occur). Default value: 1.
---@field pitch number @Audio pitch. Default value: 1.
---@field cameraInteriorMultiplier number @Multiplier for audio volume with interior camera. Default value: 0.25.
---@field cameraExteriorMultiplier number @Multiplier for audio volume with exterior (chase or free, for example) camera. Default value: 1.
---@field cameraTrackMultiplier number @Multiplier for audio volume with track camera (those replay cameras with low FOV). Default value: 1.
---@field inAutoLoopMode number @If set to `true`, aduio event would automatically start when in range of camera and volume is above 0. Default value: `false`.
---@explicit-constructor ac.AudioEvent
ffi.metatype('audioevent', { __index = {
---Sets audio event orientation.
---@param pos vec3 @Position. If you’re working on a car script, position is relative to car position.
---@param dir vec3|nil @Direction. If missing, forwards vector is used.
---@param up vec3|nil @Vector directed up for full 3D orientation.
---@param vel vec3|nil @Velocity of audio source. If missing, sound is stationary. If you’re working on a car script, velocity is relative to car velocity.
---@return ac.AudioEvent @Returns self for easy chaining.
setPosition = function (s, pos, dir, up, vel)
ffi.C.lj_audioevent_set_pos(s, __util.ensure_vec3(pos), __util.ensure_vec3_nil(dir), __util.ensure_vec3_nil(up), __util.ensure_vec3(vel))
return s
end,
---@hidden
linkTo = function (s, sceneReference)
return __util.native('lj_audioevent_linkto', s, sceneReference)
end,
---Override used volume channel. Use carefully.
---@param channel ac.AudioChannel? @Set to `nil` to reset to default.
---@return self
setVolumeChannel = function (s, channel)
return __util.native('lj_audioevent_linkvolume', s, channel)
end,
---Deprecated, now all events are alive until `:dispose()` is called.
---@deprecated
keepAlive = function () end,
---Set value of an audio event parameter.
---@param name string
---@param value number
---@return ac.AudioEvent @Returns self for easy chaining.
setParam = function (s, name, value) ffi.C.lj_audioevent_set_param(s, __util.str(name), tonumber(value) or 0) return s end,
---Set minimum distance at which attenuation starts.
---@param value number
---@return ac.AudioEvent @Returns self for easy chaining.
setDistanceMin = function (s, value) ffi.C.lj_audioevent_set_distance_min(s, tonumber(value) or 1) return s end,
---Set maximum distance at which attenuation ends.
---@param value number
---@return ac.AudioEvent @Returns self for easy chaining.
setDistanceMax = function (s, value) ffi.C.lj_audioevent_set_distance_max(s, tonumber(value) or 10) return s end,
---Set 3D cone settings.
---@param inside number? @Default value: 360.
---@param outside number? @Default value: 360.
---@param outsideVolume number? @Default value: 1.
---@return ac.AudioEvent @Returns self for easy chaining.
setConeSettings = function (s, inside, outside, outsideVolume) ffi.C.lj_audioevent_set_cone_settings(s, tonumber(inside) or 360, tonumber(outside) or 360, tonumber(outsideVolume) or 1) return s end,
---Set DSP parameter.
---@param dsp integer @0-based index of DSP.
---@param key integer @0-based index of DSP parameter.
---@param value number
---@return ac.AudioEvent @Returns self for easy chaining.
setDSPParameter = function (s, dsp, key, value) ffi.C.lj_audioevent_set_dsp_param(s, tonumber(dsp) or 0, tonumber(key) or 0, tonumber(value) or 0) return s end,
---Returns `true` if event is loaded successfully. If event does not load, make sure soundbank is loaded first, and that event name is correct. If event is loaded
---from a file and finished playing, also returns `false`.
---@return boolean
isValid = ffi.C.lj_audioevent_is_valid,
---Returns `true` if audio event is playing.
---@return boolean
isPlaying = ffi.C.lj_audioevent_is_playing,
---Returns `true` if audio event is paused.
---@return boolean
isPaused = ffi.C.lj_audioevent_is_paused,
---Return `true` if audio event is within hearing range of current listener. Could be a good way to pause some expensive processing
---for distant audio events. Although in general comparing distance with a threshold on Lua side with vectors might be faster (without
---going Lua→CSP→FMOD and back).
---@return boolean
isWithinRange = function (s) ffi.C.lj_audioevent_is_within_range(s) return s end,
resume = function (s) ffi.C.lj_audioevent_resume(s) return s end,
---If condition is `true`, start an audio event if it’s stopped, resume it if it’s paused. If condition is false, stop audio event.
---@param condition boolean
---@return ac.AudioEvent @Returns self for easy chaining.
resumeIf = function (s, condition) ffi.C.lj_audioevent_resume_if(s, condition) return s end,
---Stop audio event.
---@return ac.AudioEvent @Returns self for easy chaining.
stop = function (s) ffi.C.lj_audioevent_stop(s) return s end,
---Start audio event.
---@return ac.AudioEvent @Returns self for easy chaining.
start = function (s) ffi.C.lj_audioevent_start(s) return s end,
---Set timeline position.
---@param time number @Time in seconds.
---@return ac.AudioEvent @Returns self for easy chaining.
seek = function (s, time) ffi.C.lj_audioevent_seek(s, time) return s end,
---Get current timeline position in seconds.
---@return number @Returns `-1` if actual position is not available.
getTimelinePosition = function (s) return ffi.C.lj_audioevent_timelineposition(s) end,
---Get total duration in seconds for an audio event loaded from a file.
---@return number @Returns `-1` if actual duration is not available.
getDuration = function (s) return ffi.C.lj_audioevent_duration(s) end,
---If you need to move audio event often, accessing its matrix directly might be the best way. But you have to be extra careful in
---making sure matrix is always normalized (vectors `side`, `up` and `look` should be othrogonal with lengths of 1), otherwise
---audio might sound strange, with rapid changes in volume.
---@return mat4x4
getTransformationRaw = function (s) return s.transform_ end,
---Stop and remove audio event.
dispose = function (s) table.removeItem(__audioEventKeepAlive, s) ffi.C.lj_audioevent_dispose(s) end,
---@param i integer
---@param dir 'input'|'output'|'both'|nil
---@return number, number, number, number
getDSPMetering = function (s, i, dir)
return __util.native('ac.AudioEvent.getDSPMetering', s, i, dir)
end,
}})
__definitions()
return ac.AudioEvent