fmod 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/HISTORY.txt +23 -1
- data/README.md +1 -3
- data/Rakefile +2 -1
- data/bin/console +1 -0
- data/fmod.gemspec +1 -2
- data/lib/fmod/channel_control.rb +47 -0
- data/lib/fmod/core.rb +1 -0
- data/lib/fmod/core/bool_description.rb +9 -4
- data/lib/fmod/core/channel_mask.rb +61 -0
- data/lib/fmod/core/data_description.rb +44 -0
- data/lib/fmod/core/dsp_description.rb +172 -1
- data/lib/fmod/core/dsp_index.rb +13 -0
- data/lib/fmod/core/dsp_type.rb +154 -0
- data/lib/fmod/core/extensions.rb +19 -0
- data/lib/fmod/core/file_system.rb +1 -0
- data/lib/fmod/core/filter_type.rb +62 -0
- data/lib/fmod/core/float_description.rb +38 -0
- data/lib/fmod/core/guid.rb +27 -0
- data/lib/fmod/core/init_flags.rb +66 -0
- data/lib/fmod/core/integer_description.rb +22 -2
- data/lib/fmod/core/output_type.rb +81 -2
- data/lib/fmod/core/parameter_info.rb +36 -0
- data/lib/fmod/core/parameter_type.rb +15 -0
- data/lib/fmod/core/reverb.rb +113 -2
- data/lib/fmod/core/reverb_index.rb +105 -0
- data/lib/fmod/core/sound_ex_info.rb +4 -0
- data/lib/fmod/core/sound_group_behavior.rb +14 -0
- data/lib/fmod/core/sound_type.rb +1 -0
- data/lib/fmod/core/spectrum_data.rb +35 -0
- data/lib/fmod/core/structures.rb +10 -4
- data/lib/fmod/core/tag.rb +72 -11
- data/lib/fmod/core/tag_data_type.rb +30 -0
- data/lib/fmod/core/tag_type.rb +55 -0
- data/lib/fmod/core/time_unit.rb +3 -0
- data/lib/fmod/core/vector.rb +40 -3
- data/lib/fmod/core/window_type.rb +46 -0
- data/lib/fmod/dsp.rb +427 -98
- data/lib/fmod/dsp_connection.rb +3 -0
- data/lib/fmod/effects.rb +51 -37
- data/lib/fmod/error.rb +3 -0
- data/lib/fmod/geometry.rb +7 -0
- data/lib/fmod/handle.rb +82 -0
- data/lib/fmod/reverb3D.rb +25 -26
- data/lib/fmod/sound.rb +21 -1
- data/lib/fmod/sound_group.rb +79 -3
- data/lib/fmod/system.rb +301 -154
- data/lib/fmod/version.rb +4 -1
- metadata +6 -3
@@ -1,11 +1,57 @@
|
|
1
1
|
module FMOD
|
2
2
|
module Core
|
3
|
+
|
4
|
+
##
|
5
|
+
# List of windowing methods for the {Effects::FFT} unit. Used in spectrum
|
6
|
+
# analysis to reduce leakage / transient signals interfering with the
|
7
|
+
# analysis.
|
8
|
+
#
|
9
|
+
# This is a problem with analysis of continuous signals that only have a
|
10
|
+
# small portion of the signal sample (the FFT window size).
|
11
|
+
#
|
12
|
+
# Windowing the signal with a curve or triangle tapers the sides of the FFT
|
13
|
+
# window to help alleviate this problem.
|
14
|
+
#
|
15
|
+
# Cyclic signals such as a sine wave that repeat their cycle in a multiple
|
16
|
+
# of the window size do not need windowing. I.e. If the sine wave repeats
|
17
|
+
# every 1024, 512, 256 etc samples and the FMOD FFT window is 1024, then the
|
18
|
+
# signal would not need windowing.
|
19
|
+
#
|
20
|
+
# Not windowing is the same as :rectangle, which is the default.
|
21
|
+
#
|
22
|
+
# If the cycle of the signal (ie the sine wave) is not a multiple of the
|
23
|
+
# window size, it will cause frequency abnormalities, so a different
|
24
|
+
# windowing method is needed.
|
3
25
|
module WindowType
|
26
|
+
|
27
|
+
##
|
28
|
+
# Rectangle.
|
29
|
+
# w[n] = 1.0
|
4
30
|
RECT = 0
|
31
|
+
|
32
|
+
##
|
33
|
+
# Triangle.
|
34
|
+
# w[n] = TRI(2n/N)
|
5
35
|
TRIANGLE = 1
|
36
|
+
|
37
|
+
##
|
38
|
+
# Hamming.
|
39
|
+
# w[n] = 0.54 - (0.46 * COS(n/N) )
|
6
40
|
HAMMING = 2
|
41
|
+
|
42
|
+
##
|
43
|
+
# Hanning.
|
44
|
+
# w[n] = 0.5 * (1.0 - COS(n/N) )
|
7
45
|
HANNING = 3
|
46
|
+
|
47
|
+
##
|
48
|
+
# Blackman.
|
49
|
+
# w[n] = 0.42 - (0.5 * COS(n/N) ) + (0.08 * COS(2.0 * n/N) )
|
8
50
|
BLACKMAN = 4
|
51
|
+
|
52
|
+
##
|
53
|
+
# Blackman-Harris.
|
54
|
+
# w[n] = 0.35875 - (0.48829 * COS(1.0 * n/N)) + (0.14128 * COS(2.0 * n/N)) - (0.01168 * COS(3.0 * n/N))
|
9
55
|
BLACKMAN_HARRIS = 5
|
10
56
|
end
|
11
57
|
end
|
data/lib/fmod/dsp.rb
CHANGED
@@ -1,17 +1,84 @@
|
|
1
1
|
module FMOD
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# The dry signal path is silent by default, because DSP effects transform
|
8
|
-
# the input and pass the newly processed result to the output. It does not
|
9
|
-
# add to the input.
|
3
|
+
|
4
|
+
##
|
5
|
+
# Represents a digital signal processor. This allows for monitoring and
|
6
|
+
# applying effects to the sound in real-time.
|
10
7
|
class Dsp < Handle
|
11
8
|
|
9
|
+
##
|
10
|
+
# Describes mix levels that allow the user to scale the affect of a DSP
|
11
|
+
# effect, through control of the "wet" mix, which is the post-processed
|
12
|
+
# signal and the "dry" which is the pre-processed signal.
|
13
|
+
#
|
14
|
+
# @attr pre_wet [Float] A floating point value from 0.0 to 1.0, describing a
|
15
|
+
# linear scale of the "wet" (pre-processed signal) mix of the effect.
|
16
|
+
# Default is 1.0. Scale can be lower than 0.0 (negating) and higher than
|
17
|
+
# 1.0 (amplifying).
|
18
|
+
# @attr post_wet [Float] A floating point value from 0.0 to 1.0, describing
|
19
|
+
# a linear scale of the "'wet' "(post-processed signal) mix of the effect.
|
20
|
+
# Default is 1.0. Scale can be lower than 0.0 (negating) and higher than
|
21
|
+
# 1.0 (amplifying).
|
22
|
+
# @attr dry [Float] A floating point value from 0.0 to 1.0, describing a
|
23
|
+
# linear scale of the "dry" (pre-processed signal) mix of the effect.
|
24
|
+
# Default is 0.0. Scale can be lower than 0.0 and higher than 1.0
|
25
|
+
# (amplifying).
|
26
|
+
WetDryMix = Struct.new(:pre_wet, :post_wet, :dry)
|
27
|
+
|
28
|
+
##
|
29
|
+
# Defines the signal format of a dsp unit so that the signal is processed
|
30
|
+
# on the speakers specified, as well as the number of channels in the unit
|
31
|
+
# that a read callback will process, and the output signal of the unit.
|
32
|
+
#
|
33
|
+
# Setting the number of channels on a unit will force a down or up mix to
|
34
|
+
# that channel count before processing the DSP read callback. This count is
|
35
|
+
# then sent to the outputs of the unit.
|
36
|
+
#
|
37
|
+
# The speaker mode is informational, when the mask describes what bits are
|
38
|
+
# active, and the channel count describes how many channels are in a buffer,
|
39
|
+
# speaker mode describes where the channels originated from. For example if
|
40
|
+
# the channel count is 2 then this could describe for the DSP if the
|
41
|
+
# original signal started from a stereo signal or a 5.1 signal.
|
42
|
+
#
|
43
|
+
# It could also describe the signal as all monaural, for example if the
|
44
|
+
# channel count was 16 and the speaker mode was {SpeakerMode::MONO}.
|
45
|
+
#
|
46
|
+
# @attr mask [Integer] A series of bits specified by {ChannelMask} to
|
47
|
+
# determine which speakers are represented by the channels in the signal.
|
48
|
+
# @attr count [Integer] The number of channels to be processed on this unit
|
49
|
+
# and sent to the outputs connected to it. Maximum of
|
50
|
+
# {FMOD::MAX_CHANNEL_WIDTH}.
|
51
|
+
# @attr speaker_mode [Integer] The source speaker mode where the signal came
|
52
|
+
# from.
|
53
|
+
#
|
54
|
+
# @see ChannelMask
|
55
|
+
# @see SpeakerMode
|
12
56
|
ChannelFormat = Struct.new(:mask, :count, :speaker_mode)
|
13
57
|
|
58
|
+
##
|
59
|
+
# Contains information about the current DSP unit, including name, version,
|
60
|
+
# default channels and width and height of configuration dialog box if it
|
61
|
+
# exists.
|
62
|
+
#
|
63
|
+
# @attr name [String] The name of the unit.
|
64
|
+
# @attr version [String] The version number of the DSP unit.
|
65
|
+
# @attr channels [Integer] The number of channels the unit was initialized
|
66
|
+
# with. 0 means the plugin will process whatever number of channels is
|
67
|
+
# currently in the network. >0 would be mostly used if the unit is a unit
|
68
|
+
# that only generates sound, or is not flexible enough to take any number
|
69
|
+
# of input channels.
|
70
|
+
# @attr width [Integer] The width of an optional configuration dialog box
|
71
|
+
# that can be displayed with {Dsp.show_dialog}. 0 means the dialog is not
|
72
|
+
# present.
|
73
|
+
# @attr height [Integer] The height of an optional configuration dialog box
|
74
|
+
# that can be displayed with {Dsp.show_dialog}. 0 means the dialog is not
|
75
|
+
# present.
|
14
76
|
DspInfo = Struct.new(:name, :version, :channels, :width, :height) do
|
77
|
+
|
78
|
+
# @!method config?
|
79
|
+
# @return [Boolean] a flag indicating if DSP unit has an optional
|
80
|
+
# configuration dialog that can be displayed.
|
81
|
+
# @note None of the built-in DSP units contain a dialog.
|
15
82
|
def config?
|
16
83
|
width > 0 && height > 0
|
17
84
|
end
|
@@ -65,6 +132,20 @@ module FMOD
|
|
65
132
|
raise TypeError, "#{type} is not a Integer or Class."
|
66
133
|
end
|
67
134
|
|
135
|
+
##
|
136
|
+
# Plays a sound object on a particular channel and {ChannelGroup}.
|
137
|
+
#
|
138
|
+
# When a sound is played, it will use the sound's default frequency and
|
139
|
+
# priority.
|
140
|
+
#
|
141
|
+
# @param group [ChannelGroup] The {ChannelGroup} become a member of. This is
|
142
|
+
# more efficient than using {Channel.group}, as it does it during the
|
143
|
+
# channel setup, rather than connecting to the master channel group, then
|
144
|
+
# later disconnecting and connecting to the new {ChannelGroup} when
|
145
|
+
# specified. Specify +nil+ to ignore (use master {ChannelGroup}).
|
146
|
+
#
|
147
|
+
# @return [Channel] the newly playing channel.
|
148
|
+
# @see System.play_dsp
|
68
149
|
def play(group = nil)
|
69
150
|
parent.play_dsp(self, group, false)
|
70
151
|
end
|
@@ -185,6 +266,17 @@ module FMOD
|
|
185
266
|
"#{version[0, 4].to_i}.#{version[4, 4].to_i}"
|
186
267
|
end
|
187
268
|
|
269
|
+
# @attribute wet_dry_mix
|
270
|
+
# Allows the user to scale the affect of a DSP effect, through control of
|
271
|
+
# the "wet" mix, which is the post-processed signal and the "dry" which is
|
272
|
+
# the pre-processed signal.
|
273
|
+
#
|
274
|
+
# The dry signal path is silent by default, because DSP effects transform
|
275
|
+
# the input and pass the newly processed result to the output. It does not
|
276
|
+
# add to the input.
|
277
|
+
#
|
278
|
+
# @return [WetDryMix] the current mix.
|
279
|
+
# @see WetDryMix
|
188
280
|
def wet_dry_mix
|
189
281
|
args = ["\0" * SIZEOF_FLOAT, "\0" * SIZEOF_FLOAT, "\0" * SIZEOF_FLOAT]
|
190
282
|
FMOD.invoke(:DSP_GetWetDryMix, self, *args)
|
@@ -226,14 +318,10 @@ module FMOD
|
|
226
318
|
self
|
227
319
|
end
|
228
320
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
321
|
+
# @!attribute channel_format
|
322
|
+
# @return [ChannelFormat] The signal format of a DSP unit so that the signal
|
323
|
+
# is processed on the speakers specified.
|
324
|
+
# @see ChannelFormat
|
237
325
|
def channel_format
|
238
326
|
args = ["\0" * SIZEOF_INT, "\0" * SIZEOF_INT, "\0" * SIZEOF_INT]
|
239
327
|
FMOD.invoke(:DSP_GetChannelFormat, self, *args)
|
@@ -247,16 +335,10 @@ module FMOD
|
|
247
335
|
format
|
248
336
|
end
|
249
337
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
255
|
-
|
256
|
-
def to_s
|
257
|
-
"#{name} v.#{version}"
|
258
|
-
end
|
259
|
-
|
338
|
+
##
|
339
|
+
# @return [DspInfo] the information about the current DSP unit, including
|
340
|
+
# name, version, default channels and width and height of configuration
|
341
|
+
# dialog box if it exists.
|
260
342
|
def info
|
261
343
|
name, vs = "\0" * 32, "\0" * SIZEOF_INT
|
262
344
|
args = ["\0" * SIZEOF_INT, "\0" * SIZEOF_INT, "\0" * SIZEOF_INT]
|
@@ -267,67 +349,152 @@ module FMOD
|
|
267
349
|
DspInfo.new(name.delete("\0"), version, *args)
|
268
350
|
end
|
269
351
|
|
352
|
+
##
|
353
|
+
# Calls the DSP unit's reset function, which will clear internal buffers and
|
354
|
+
# reset the unit back to an initial state.
|
355
|
+
#
|
356
|
+
# Calling this function is useful if the DSP unit relies on a history to
|
357
|
+
# process itself (ie an echo filter).
|
358
|
+
#
|
359
|
+
# If you disconnected the unit and reconnected it to a different part of the
|
360
|
+
# network with a different sound, you would want to call this to reset the
|
361
|
+
# units state (ie clear and reset the echo filter) so that you dont get left
|
362
|
+
# over artifacts from the place it used to be connected.
|
363
|
+
#
|
364
|
+
# @return [void]
|
270
365
|
def reset
|
271
366
|
FMOD.invoke(:DSP_Reset, self)
|
272
367
|
end
|
273
368
|
|
369
|
+
##
|
370
|
+
# @!attribute [r] parent
|
371
|
+
# @return [System] the parent {System} object that was used to create this
|
372
|
+
# object.
|
274
373
|
def parent
|
275
374
|
FMOD.invoke(:DSP_GetSystemObject, self, system = int_ptr)
|
276
375
|
System.new(system)
|
277
376
|
end
|
278
377
|
|
378
|
+
##
|
379
|
+
# Display or hide a DSP unit configuration dialog box inside the target
|
380
|
+
# window.
|
381
|
+
#
|
382
|
+
# @param hwnd [Pointer] Target HWND in windows to display configuration
|
383
|
+
# dialog.
|
384
|
+
# @param show [Boolean] +true+ to display the window within the parent
|
385
|
+
# window, otherwise +false+ to remove it.
|
386
|
+
#
|
387
|
+
# @return [void]
|
279
388
|
def show_dialog(hwnd, show = true)
|
280
389
|
FMOD.invoke(:DSP_ShowConfigDialog, self, hwnd, show.to_i)
|
281
390
|
end
|
282
391
|
|
392
|
+
##
|
393
|
+
# Retrieve information about a specified parameter within the DSP unit.
|
394
|
+
#
|
395
|
+
# @param index [Integer] Parameter index for this unit.
|
396
|
+
#
|
397
|
+
# @return [ParameterInfo, nil] the information about the specified parameter
|
398
|
+
# or +nil+ if the index was out of range.
|
399
|
+
def param_info(index)
|
400
|
+
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
401
|
+
FMOD.invoke(:DSP_GetParameterInfo, self, index, info = int_ptr)
|
402
|
+
ParameterInfo.new(info.unpack1('J'))
|
403
|
+
end
|
404
|
+
|
405
|
+
##
|
406
|
+
# Helper function to disconnect either all inputs or all outputs of a DSP
|
407
|
+
# unit.
|
408
|
+
#
|
409
|
+
# @param inputs [Boolean] +true+ to disconnect all inputs to this DSP unit,
|
410
|
+
# otherwise +false+ to leave input connections alone.
|
411
|
+
# @param outputs [Boolean] +true+ to disconnect all outputs to this DSP
|
412
|
+
# unit, otherwise +false+ to leave output connections alone.
|
413
|
+
#
|
414
|
+
# @return [void]
|
283
415
|
def disconnect(inputs, outputs)
|
284
416
|
FMOD.invoke(:DSP_DisconnectAll, self, inputs.to_i, outputs.to_i)
|
285
417
|
end
|
286
418
|
|
419
|
+
##
|
420
|
+
# Disconnect the DSP unit from the specified input.
|
421
|
+
#
|
422
|
+
# @param dsp [Dsp] The input unit that this unit is to be disconnected from.
|
423
|
+
# @param connection [DspConnection] If there is more than one connection
|
424
|
+
# between 2 dDSP units, this can be used to define which of the
|
425
|
+
# connections should be disconnected.
|
426
|
+
#
|
427
|
+
# @note If you have a handle to the connection pointer that binds these 2
|
428
|
+
# DSP units, then it will become invalid. The connection is then sent back
|
429
|
+
# to a freelist to be re-used again by a later addInput command.
|
430
|
+
#
|
431
|
+
# @return [void]
|
287
432
|
def disconnect_from(dsp, connection = nil)
|
288
433
|
FMOD.type?(dsp, Dsp) unless dsp.nil?
|
289
434
|
FMOD.type?(connection, DspConnection) unless connection.nil?
|
290
435
|
FMOD.invoke(:DSP_DisconnectFrom, self, dsp, connection)
|
291
436
|
end
|
292
437
|
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
mask, count, mode = channel_format.values
|
300
|
-
end
|
301
|
-
args = ["\0" * SIZEOF_INT, "\0" * SIZEOF_INT, "\0" * SIZEOF_INT]
|
302
|
-
FMOD.invoke(:DSP_GetOutputChannelFormat, mask, count, mode, *args)
|
303
|
-
args.map! { |arg| arg.unpack1('L') }
|
304
|
-
ChannelFormat.new(*args)
|
305
|
-
end
|
306
|
-
|
438
|
+
##
|
439
|
+
# Retrieves a DSP unit which is acting as an input to this unit.
|
440
|
+
#
|
441
|
+
# @param index [Integer] Index of the input unit to retrieve.
|
442
|
+
#
|
443
|
+
# @return [Dsp] the input unit.
|
307
444
|
def input(index)
|
308
445
|
input = int_ptr
|
309
446
|
FMOD.invoke(:DSP_GetInput, self, index, input, nil)
|
310
447
|
Dsp.from_handle(input)
|
311
448
|
end
|
312
449
|
|
450
|
+
##
|
451
|
+
# Retrieves a DSP unit which is acting as an output to this unit.
|
452
|
+
#
|
453
|
+
# @param index [Integer] Index of the output unit to retrieve.
|
454
|
+
#
|
455
|
+
# @return [Dsp] the output unit.
|
313
456
|
def output(index)
|
314
457
|
output = int_ptr
|
315
458
|
FMOD.invoke(:DSP_GetOutput, self, index, output, nil)
|
316
459
|
Dsp.from_handle(output)
|
317
460
|
end
|
318
461
|
|
462
|
+
##
|
463
|
+
# Retrieves the connection which to a DSP acting as an input to this unit.
|
464
|
+
#
|
465
|
+
# @param index [Integer] Index of the input unit to retrieve the connection.
|
466
|
+
#
|
467
|
+
# @return [DspConnection] the input unit connection.
|
319
468
|
def input_connection(index)
|
320
469
|
connection = int_ptr
|
321
470
|
FMOD.invoke(:DSP_GetInput, self, index, nil, connection)
|
322
471
|
DspConnection.new(connection)
|
323
472
|
end
|
324
473
|
|
474
|
+
##
|
475
|
+
# Retrieves the connection which to a DSP acting as an output to this unit.
|
476
|
+
#
|
477
|
+
# @param index [Integer] Index of the output unit to retrieve the connection.
|
478
|
+
#
|
479
|
+
# @return [DspConnection] the output unit connection.
|
325
480
|
def output_connection(index)
|
326
481
|
connection = int_ptr
|
327
482
|
FMOD.invoke(:DSP_GetOutput, self, index, nil, connection)
|
328
483
|
DspConnection.new(connection)
|
329
484
|
end
|
330
485
|
|
486
|
+
##
|
487
|
+
# Adds the specified DSP unit as an input of the DSP object.
|
488
|
+
#
|
489
|
+
# @param dsp [Dsp] The DSP unit to add as an input of the current unit.
|
490
|
+
# @param type [Integer] The type of connection between the 2 units. The
|
491
|
+
# following are valid values.
|
492
|
+
# * {DspConnection::STANDARD}
|
493
|
+
# * {DspConnection::SIDECHAIN}
|
494
|
+
# * {DspConnection::SEND}
|
495
|
+
# * {DspConnection::SEND_SIDECHAIN}
|
496
|
+
#
|
497
|
+
# @return [DspConnection] the connection between the 2 units.
|
331
498
|
def add_input(dsp, type)
|
332
499
|
FMOD.type?(dsp, Dsp)
|
333
500
|
connection = int_ptr
|
@@ -335,33 +502,81 @@ module FMOD
|
|
335
502
|
DspConnection.new(connection)
|
336
503
|
end
|
337
504
|
|
505
|
+
##
|
506
|
+
# Call the DSP process function to retrieve the output signal format for a
|
507
|
+
# DSP based on input values.
|
508
|
+
#
|
509
|
+
# A DSP unit may be an up mixer or down mixer for example. In this case if
|
510
|
+
# you specified 6 in for a down-mixer, it may provide you with 2 out for
|
511
|
+
# example.
|
512
|
+
#
|
513
|
+
# Generally the input values will be reproduced for the output values, but
|
514
|
+
# some DSP units will want to alter the output format.
|
515
|
+
#
|
516
|
+
# @overload output_format(format)
|
517
|
+
# @param format [ChannelFormat] Structure describing the incoming channel
|
518
|
+
# format.
|
519
|
+
# @overload output_format(mask, count, speaker_mode)
|
520
|
+
# @param mask [Integer] Channel bit-mask representing the speakers enabled
|
521
|
+
# for the incoming signal.
|
522
|
+
# @param count [Integer] Number of channels for the incoming signal.
|
523
|
+
# @param speaker_mode [Integer] Speaker mode for the incoming signal.
|
524
|
+
#
|
525
|
+
# @return [ChannelFormat] the output signal format.
|
526
|
+
def output_format(*args)
|
527
|
+
if args.size == 3 && args.all? { |arg| arg.is_a?(Integer) }
|
528
|
+
mask, count, mode = args
|
529
|
+
elsif args.size == 1 && FMOD.type?(args[0], ChannelFormat)
|
530
|
+
mask, count, mode = args[0].values
|
531
|
+
else
|
532
|
+
mask, count, mode = channel_format.values
|
533
|
+
end
|
534
|
+
args = ["\0" * SIZEOF_INT, "\0" * SIZEOF_INT, "\0" * SIZEOF_INT]
|
535
|
+
FMOD.invoke(:DSP_GetOutputChannelFormat, mask, count, mode, *args)
|
536
|
+
args.map! { |arg| arg.unpack1('L') }
|
537
|
+
ChannelFormat.new(*args)
|
538
|
+
end
|
539
|
+
|
540
|
+
##
|
541
|
+
# @return [Boolean] a flag indicating if input metering for the DSP it is
|
542
|
+
# enabled or not.
|
338
543
|
def input_metering?
|
339
544
|
enabled = "\0" * SIZEOF_INT
|
340
545
|
FMOD.invoke(:DSP_GetMeteringEnabled, self, enabled, nil)
|
341
546
|
enabled.unpack1('l') != 0
|
342
547
|
end
|
343
548
|
|
549
|
+
##
|
550
|
+
# @return [Boolean] a flag indicating if output metering for the DSP it is
|
551
|
+
# enabled or not.
|
344
552
|
def output_metering?
|
345
553
|
enabled = "\0" * SIZEOF_INT
|
346
554
|
FMOD.invoke(:DSP_GetMeteringEnabled, self, nil, enabled)
|
347
555
|
enabled.unpack1('l') != 0
|
348
556
|
end
|
349
557
|
|
558
|
+
##
|
559
|
+
# Enable metering for a DSP unit.
|
560
|
+
#
|
561
|
+
# @param input [Boolean] Enable metering for the input signal
|
562
|
+
# (pre-processing). Specify +true+ to turn on input level metering,
|
563
|
+
# +false+ to turn it off.
|
564
|
+
# @param output [Boolean] Enable metering for the output signal
|
565
|
+
# (post-processing). Specify +true+ to turn on output level metering,
|
566
|
+
# +false+ to turn it off.
|
567
|
+
#
|
568
|
+
# @return [void]
|
350
569
|
def enable_metering(input, output)
|
351
570
|
FMOD.invoke(:DSP_SetMeteringEnabled, self, input ? 1 :0, output.to_i)
|
352
571
|
end
|
353
572
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
else raise RangeError, 'Unknown data type.'
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
573
|
+
##
|
574
|
+
# Retrieves the unit's float parameter by index.
|
575
|
+
#
|
576
|
+
# @param index [Integer] Parameter index for this unit.
|
577
|
+
#
|
578
|
+
# @return [Float, nil] the parameter specified, or +nil+ if index is out
|
579
|
+
# of range.
|
365
580
|
def get_float(index)
|
366
581
|
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
367
582
|
buffer = "\0" * SIZEOF_FLOAT
|
@@ -369,6 +584,13 @@ module FMOD
|
|
369
584
|
buffer.unpack1('f')
|
370
585
|
end
|
371
586
|
|
587
|
+
##
|
588
|
+
# Retrieves the unit's integer parameter by index.
|
589
|
+
#
|
590
|
+
# @param index [Integer] Parameter index for this unit.
|
591
|
+
#
|
592
|
+
# @return [Integer, nil] the parameter specified, or +nil+ if index is out
|
593
|
+
# of range.
|
372
594
|
def get_integer(index)
|
373
595
|
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
374
596
|
buffer = "\0" * SIZEOF_INT
|
@@ -376,6 +598,13 @@ module FMOD
|
|
376
598
|
buffer.unpack1('l')
|
377
599
|
end
|
378
600
|
|
601
|
+
##
|
602
|
+
# Retrieves the unit's boolean parameter by index.
|
603
|
+
#
|
604
|
+
# @param index [Integer] Parameter index for this unit.
|
605
|
+
#
|
606
|
+
# @return [Boolean, nil] the parameter specified, or +nil+ if index is out
|
607
|
+
# of range.
|
379
608
|
def get_bool(index)
|
380
609
|
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
381
610
|
buffer = "\0" * SIZEOF_INT
|
@@ -383,6 +612,13 @@ module FMOD
|
|
383
612
|
buffer.unpack1('l') != 0
|
384
613
|
end
|
385
614
|
|
615
|
+
##
|
616
|
+
# Retrieves the unit's data parameter by index.
|
617
|
+
#
|
618
|
+
# @param index [Integer] Parameter index for this unit.
|
619
|
+
#
|
620
|
+
# @return [Pointer, nil] the parameter specified, or +nil+ if index is out
|
621
|
+
# of range.
|
386
622
|
def get_data(index)
|
387
623
|
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
388
624
|
pointer = int_ptr
|
@@ -391,35 +627,52 @@ module FMOD
|
|
391
627
|
Pointer.new(pointer.unpack('J'), size.unpack1('l'))
|
392
628
|
end
|
393
629
|
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
else raise TypeError, "#{value} is not a valid DSP parameter type."
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
630
|
+
##
|
631
|
+
# Sets the unit's float parameter by index.
|
632
|
+
#
|
633
|
+
# @param index [Integer] Parameter index for this unit.
|
634
|
+
# @param value [Float] The value to set.
|
635
|
+
#
|
636
|
+
# @return [self]
|
405
637
|
def set_float(index, value)
|
406
638
|
return unless FMOD.valid_range?(index, 0, parameter_count, false)
|
407
639
|
FMOD.invoke(:DSP_SetParameterFloat, self, index, value)
|
408
640
|
self
|
409
641
|
end
|
410
642
|
|
643
|
+
##
|
644
|
+
# Sets the unit's integer parameter by index.
|
645
|
+
#
|
646
|
+
# @param index [Integer] Parameter index for this unit.
|
647
|
+
# @param value [Integer] The value to set.
|
648
|
+
#
|
649
|
+
# @return [self]
|
411
650
|
def set_integer(index, value)
|
412
651
|
return unless FMOD.valid_range?(index, 0, parameter_count, false)
|
413
652
|
FMOD.invoke(:DSP_SetParameterInt, self, index, value)
|
414
653
|
self
|
415
654
|
end
|
416
655
|
|
656
|
+
##
|
657
|
+
# Sets the unit's boolean parameter by index.
|
658
|
+
#
|
659
|
+
# @param index [Integer] Parameter index for this unit.
|
660
|
+
# @param value [Boolean] The value to set.
|
661
|
+
#
|
662
|
+
# @return [self]
|
417
663
|
def set_bool(index, value)
|
418
664
|
return unless FMOD.valid_range?(index, 0, parameter_count, false)
|
419
665
|
FMOD.invoke(:DSP_SetParameterBool, self, index, value.to_i)
|
420
666
|
self
|
421
667
|
end
|
422
668
|
|
669
|
+
##
|
670
|
+
# Sets the unit's data parameter by index.
|
671
|
+
#
|
672
|
+
# @param index [Integer] Parameter index for this unit.
|
673
|
+
# @param value [Pointer, String] The value to set.
|
674
|
+
#
|
675
|
+
# @return [self]
|
423
676
|
def set_data(index, value)
|
424
677
|
return unless FMOD.valid_range?(index, 0, parameter_count, false)
|
425
678
|
unless FMOD.type?(value, String, false)
|
@@ -430,11 +683,73 @@ module FMOD
|
|
430
683
|
self
|
431
684
|
end
|
432
685
|
|
686
|
+
##
|
687
|
+
# Get parameter by index.
|
688
|
+
#
|
689
|
+
# @param index [Integer] Parameter index for this unit.
|
690
|
+
#
|
691
|
+
# @return [Object] the value of the parameter at the specified index.
|
692
|
+
def [](index)
|
693
|
+
return nil unless FMOD.valid_range?(index, 0, parameter_count, false)
|
694
|
+
case param_info(index).type
|
695
|
+
when ParameterType::FLOAT then get_float(index)
|
696
|
+
when ParameterType::INT then get_integer(index)
|
697
|
+
when ParameterType::BOOL then get_integer(index)
|
698
|
+
when ParameterType::DATA then get_data(index)
|
699
|
+
else raise RangeError, 'Unknown data type.'
|
700
|
+
end
|
701
|
+
end
|
433
702
|
|
434
|
-
|
703
|
+
##
|
704
|
+
# Sets parameter by index.
|
705
|
+
#
|
706
|
+
# @param index [Integer] Parameter index for this unit.
|
707
|
+
# @param value [Float, Integer, Boolean, Pointer, String] The value to set.
|
708
|
+
#
|
709
|
+
# @note The value must be of the correct type for the specified parameter,
|
710
|
+
# no implicit conversions will be performed, i.e. passing an integer to a
|
711
|
+
# float parameter will fail, as it is not the correct type. It is up to
|
712
|
+
# the user to perform any conversions ahead before passing to this method.
|
713
|
+
#
|
714
|
+
# @return [Object] the value of the parameter at the specified index.
|
715
|
+
def []=(index, value)
|
716
|
+
return unless FMOD.valid_range?(index, 0, parameter_count, false)
|
717
|
+
case value
|
718
|
+
when Float then set_float(index, value)
|
719
|
+
when Integer then set_integer(index, value)
|
720
|
+
when TrueClass, FalseClass, NilClass then set_bool(index, value)
|
721
|
+
when String, Pointer then set_data(index, value)
|
722
|
+
else raise TypeError, "#{value} is not a valid DSP parameter type."
|
723
|
+
end
|
724
|
+
end
|
435
725
|
|
436
|
-
|
726
|
+
##
|
727
|
+
# @return [String] the string representation of the DSP unit.
|
728
|
+
def to_s
|
729
|
+
"#{name} v.#{version}"
|
730
|
+
end
|
731
|
+
|
732
|
+
class << self
|
437
733
|
|
734
|
+
##
|
735
|
+
# Dynamically creates a method for getting and/or setting a named float
|
736
|
+
# parameter of a DSP unit.
|
737
|
+
#
|
738
|
+
# @param index [Integer] The parameter index.
|
739
|
+
# @param name [Symbol] The name of the attribute to define.
|
740
|
+
# @param options [Hash] The options hash.
|
741
|
+
#
|
742
|
+
# @option options [Boolean] :readonly (false) Flag indicating if a setter
|
743
|
+
# function will be defined or not.
|
744
|
+
# @option options [Boolean] :write_only (false) Flag indicating if a
|
745
|
+
# getter will be defined or not.
|
746
|
+
# @option options [Float] :min (nil) If defined will clamp any given value
|
747
|
+
# to the specified minimum value.
|
748
|
+
# @option options [Float] :max (nil) If defined will clamp any given value
|
749
|
+
# to the specified maximum value.
|
750
|
+
#
|
751
|
+
# @return [void]
|
752
|
+
# @api private
|
438
753
|
def float_param(index, name, **options)
|
439
754
|
define_method(name) { get_float(index) } unless options[:write_only]
|
440
755
|
unless options[:readonly]
|
@@ -446,6 +761,25 @@ module FMOD
|
|
446
761
|
end
|
447
762
|
end
|
448
763
|
|
764
|
+
##
|
765
|
+
# Dynamically creates a method for getting and/or setting a named integer
|
766
|
+
# parameter of a DSP unit.
|
767
|
+
#
|
768
|
+
# @param index [Integer] The parameter index.
|
769
|
+
# @param name [Symbol] The name of the attribute to define.
|
770
|
+
# @param options [Hash] The options hash.
|
771
|
+
#
|
772
|
+
# @option options [Boolean] :readonly (false) Flag indicating if a setter
|
773
|
+
# function will be defined or not.
|
774
|
+
# @option options [Boolean] :write_only (false) Flag indicating if a
|
775
|
+
# getter will be defined or not.
|
776
|
+
# @option options [Integer] :min (nil) If defined will clamp any given
|
777
|
+
# value to the specified minimum value.
|
778
|
+
# @option options [Integer] :max (nil) If defined will clamp any given
|
779
|
+
# value to the specified maximum value.
|
780
|
+
#
|
781
|
+
# @return [void]
|
782
|
+
# @api private
|
449
783
|
def integer_param(index, name, **options)
|
450
784
|
define_method(name) { get_integer(index) } unless options[:write_only]
|
451
785
|
unless options[:readonly]
|
@@ -457,6 +791,21 @@ module FMOD
|
|
457
791
|
end
|
458
792
|
end
|
459
793
|
|
794
|
+
##
|
795
|
+
# Dynamically creates a method for getting and/or setting a named boolean
|
796
|
+
# parameter of a DSP unit.
|
797
|
+
#
|
798
|
+
# @param index [Integer] The parameter index.
|
799
|
+
# @param name [Symbol] The name of the attribute to define.
|
800
|
+
# @param options [Hash] The options hash.
|
801
|
+
#
|
802
|
+
# @option options [Boolean] :readonly (false) Flag indicating if a setter
|
803
|
+
# function will be defined or not.
|
804
|
+
# @option options [Boolean] :write_only (false) Flag indicating if a
|
805
|
+
# getter will be defined or not.
|
806
|
+
#
|
807
|
+
# @return [void]
|
808
|
+
# @api private
|
460
809
|
def bool_param(index, name, **options)
|
461
810
|
define_method(name) { get_bool(index) } unless options[:write_only]
|
462
811
|
unless options[:readonly]
|
@@ -464,6 +813,21 @@ module FMOD
|
|
464
813
|
end
|
465
814
|
end
|
466
815
|
|
816
|
+
##
|
817
|
+
# Dynamically creates a method for getting and/or setting a named data
|
818
|
+
# parameter of a DSP unit.
|
819
|
+
#
|
820
|
+
# @param index [Integer] The parameter index.
|
821
|
+
# @param name [Symbol] The name of the attribute to define.
|
822
|
+
# @param options [Hash] The options hash.
|
823
|
+
#
|
824
|
+
# @option options [Boolean] :readonly (false) Flag indicating if a setter
|
825
|
+
# function will be defined or not.
|
826
|
+
# @option options [Boolean] :write_only (false) Flag indicating if a
|
827
|
+
# getter will be defined or not.
|
828
|
+
#
|
829
|
+
# @return [void]
|
830
|
+
# @api private
|
467
831
|
def data_param(index, name, **options)
|
468
832
|
define_method(name) { get_data(index) } unless options[:write_only]
|
469
833
|
unless options[:readonly]
|
@@ -471,40 +835,5 @@ module FMOD
|
|
471
835
|
end
|
472
836
|
end
|
473
837
|
end
|
474
|
-
# def self.float_param(index, name, **options)
|
475
|
-
# define_method(name) { get_float(index) } unless options[:write_only]
|
476
|
-
# unless options[:readonly]
|
477
|
-
# define_method("#{name}=") do |value|
|
478
|
-
# value = options[:min] if options[:min] && value < options[:min]
|
479
|
-
# value = options[:max] if options[:max] && value > options[:max]
|
480
|
-
# set_float(index, value)
|
481
|
-
# end
|
482
|
-
# end
|
483
|
-
# end
|
484
|
-
#
|
485
|
-
# def self.integer_param(index, name, **options)
|
486
|
-
# define_method(name) { get_integer(index) } unless options[:write_only]
|
487
|
-
# unless options[:readonly]
|
488
|
-
# define_method("#{name}=") do |value|
|
489
|
-
# value = options[:min] if options[:min] && value < options[:min]
|
490
|
-
# value = options[:max] if options[:max] && value > options[:max]
|
491
|
-
# set_float(index, value)
|
492
|
-
# end
|
493
|
-
# end
|
494
|
-
# end
|
495
|
-
#
|
496
|
-
# def self.bool_param(index, name, **options)
|
497
|
-
# define_method(name) { get_bool(index) } unless options[:write_only]
|
498
|
-
# unless options[:readonly]
|
499
|
-
# define_method("#{name}=") { |value| set_bool(index, value) }
|
500
|
-
# end
|
501
|
-
# end
|
502
|
-
#
|
503
|
-
# def self.data_param(index, name, **options)
|
504
|
-
# define_method(name) { get_data(index) } unless options[:write_only]
|
505
|
-
# unless options[:readonly]
|
506
|
-
# define_method("#{name}=") { |value| set_data(index, value) }
|
507
|
-
# end
|
508
|
-
# end
|
509
838
|
end
|
510
839
|
end
|