fmod 0.9.0

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.
Files changed (105) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +2 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +5 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +96 -0
  9. data/Rakefile +1 -0
  10. data/bin/console +28 -0
  11. data/bin/setup +8 -0
  12. data/ext/fmod.dll +0 -0
  13. data/ext/fmod64.dll +0 -0
  14. data/ext/libfmod.dylib +0 -0
  15. data/ext/llbfmod.zip +0 -0
  16. data/extras/FMOD Studio Programmers API for Windows.chm +0 -0
  17. data/fmod.gemspec +58 -0
  18. data/lib/fmod.rb +564 -0
  19. data/lib/fmod/channel.rb +151 -0
  20. data/lib/fmod/channel_control.rb +821 -0
  21. data/lib/fmod/channel_group.rb +61 -0
  22. data/lib/fmod/core.rb +35 -0
  23. data/lib/fmod/core/bool_description.rb +18 -0
  24. data/lib/fmod/core/channel_mask.rb +24 -0
  25. data/lib/fmod/core/data_description.rb +14 -0
  26. data/lib/fmod/core/driver.rb +59 -0
  27. data/lib/fmod/core/dsp_description.rb +7 -0
  28. data/lib/fmod/core/dsp_index.rb +9 -0
  29. data/lib/fmod/core/dsp_type.rb +43 -0
  30. data/lib/fmod/core/extensions.rb +28 -0
  31. data/lib/fmod/core/file_system.rb +86 -0
  32. data/lib/fmod/core/filter_type.rb +19 -0
  33. data/lib/fmod/core/float_description.rb +16 -0
  34. data/lib/fmod/core/guid.rb +50 -0
  35. data/lib/fmod/core/init_flags.rb +19 -0
  36. data/lib/fmod/core/integer_description.rb +26 -0
  37. data/lib/fmod/core/mode.rb +36 -0
  38. data/lib/fmod/core/output_type.rb +30 -0
  39. data/lib/fmod/core/parameter_info.rb +41 -0
  40. data/lib/fmod/core/parameter_type.rb +10 -0
  41. data/lib/fmod/core/result.rb +88 -0
  42. data/lib/fmod/core/reverb.rb +217 -0
  43. data/lib/fmod/core/sound_ex_info.rb +7 -0
  44. data/lib/fmod/core/sound_format.rb +30 -0
  45. data/lib/fmod/core/sound_group_behavior.rb +9 -0
  46. data/lib/fmod/core/sound_type.rb +80 -0
  47. data/lib/fmod/core/speaker_index.rb +18 -0
  48. data/lib/fmod/core/speaker_mode.rb +16 -0
  49. data/lib/fmod/core/spectrum_data.rb +12 -0
  50. data/lib/fmod/core/structure.rb +23 -0
  51. data/lib/fmod/core/structures.rb +41 -0
  52. data/lib/fmod/core/tag.rb +51 -0
  53. data/lib/fmod/core/tag_data_type.rb +14 -0
  54. data/lib/fmod/core/time_unit.rb +40 -0
  55. data/lib/fmod/core/vector.rb +42 -0
  56. data/lib/fmod/core/window_type.rb +12 -0
  57. data/lib/fmod/dsp.rb +510 -0
  58. data/lib/fmod/dsp_connection.rb +113 -0
  59. data/lib/fmod/effects.rb +38 -0
  60. data/lib/fmod/effects/channel_mix.rb +101 -0
  61. data/lib/fmod/effects/chorus.rb +30 -0
  62. data/lib/fmod/effects/compressor.rb +52 -0
  63. data/lib/fmod/effects/convolution_reverb.rb +31 -0
  64. data/lib/fmod/effects/delay.rb +44 -0
  65. data/lib/fmod/effects/distortion.rb +16 -0
  66. data/lib/fmod/effects/dsps.rb +10 -0
  67. data/lib/fmod/effects/echo.rb +37 -0
  68. data/lib/fmod/effects/envelope_follower.rb +31 -0
  69. data/lib/fmod/effects/fader.rb +16 -0
  70. data/lib/fmod/effects/fft.rb +38 -0
  71. data/lib/fmod/effects/flange.rb +37 -0
  72. data/lib/fmod/effects/high_pass.rb +24 -0
  73. data/lib/fmod/effects/high_pass_simple.rb +25 -0
  74. data/lib/fmod/effects/it_echo.rb +56 -0
  75. data/lib/fmod/effects/it_lowpass.rb +36 -0
  76. data/lib/fmod/effects/ladspa_plugin.rb +14 -0
  77. data/lib/fmod/effects/limiter.rb +32 -0
  78. data/lib/fmod/effects/loudness_meter.rb +19 -0
  79. data/lib/fmod/effects/low_pass.rb +25 -0
  80. data/lib/fmod/effects/low_pass_simple.rb +26 -0
  81. data/lib/fmod/effects/mixer.rb +11 -0
  82. data/lib/fmod/effects/multiband_eq.rb +153 -0
  83. data/lib/fmod/effects/normalize.rb +47 -0
  84. data/lib/fmod/effects/object_pan.rb +62 -0
  85. data/lib/fmod/effects/oscillator.rb +52 -0
  86. data/lib/fmod/effects/pan.rb +166 -0
  87. data/lib/fmod/effects/param_eq.rb +36 -0
  88. data/lib/fmod/effects/pitch_shift.rb +47 -0
  89. data/lib/fmod/effects/return.rb +18 -0
  90. data/lib/fmod/effects/send.rb +21 -0
  91. data/lib/fmod/effects/sfx_reverb.rb +87 -0
  92. data/lib/fmod/effects/three_eq.rb +41 -0
  93. data/lib/fmod/effects/transceiver.rb +57 -0
  94. data/lib/fmod/effects/tremolo.rb +67 -0
  95. data/lib/fmod/effects/vst_plugin.rb +12 -0
  96. data/lib/fmod/effects/winamp_plugin.rb +12 -0
  97. data/lib/fmod/error.rb +108 -0
  98. data/lib/fmod/geometry.rb +380 -0
  99. data/lib/fmod/handle.rb +129 -0
  100. data/lib/fmod/reverb3D.rb +98 -0
  101. data/lib/fmod/sound.rb +810 -0
  102. data/lib/fmod/sound_group.rb +54 -0
  103. data/lib/fmod/system.rb +1242 -0
  104. data/lib/fmod/version.rb +3 -0
  105. metadata +220 -0
@@ -0,0 +1,61 @@
1
+
2
+ module FMOD
3
+ class ChannelGroup < ChannelControl
4
+
5
+ include Fiddle
6
+ include Enumerable
7
+
8
+ integer_reader(:subgroup_count, :ChannelGroup_GetNumGroups)
9
+ integer_reader(:channel_count, :ChannelGroup_GetNumChannels)
10
+
11
+ def name
12
+ buffer = "\0" * 512
13
+ FMOD.invoke(:ChannelGroup_GetName, self, buffer, 512)
14
+ buffer.delete("\0")
15
+ end
16
+
17
+ def subgroup(index)
18
+ FMOD.valid_range?(index, 0, subgroup_count - 1)
19
+ FMOD.invoke(:ChannelGroup_GetGroup, self, index, group = int_ptr)
20
+ ChannelGroup.new(group)
21
+ end
22
+
23
+ def parent_group
24
+ FMOD.invoke(:ChannelGroup_GetParentGroup, self, group = int_ptr)
25
+ group.null? ? nil : ChannelGroup.new(group)
26
+ end
27
+
28
+ def [](index)
29
+ FMOD.valid_range?(index, 0, channel_count - 1)
30
+ FMOD.invoke(:ChannelGroup_GetChannel, self, index, channel = int_ptr)
31
+ Channel.new(channel)
32
+ end
33
+
34
+ def each
35
+ return to_enum(:each) unless block_given?
36
+ (0...channel_count).each { |i| yield self[i] }
37
+ self
38
+ end
39
+
40
+ def <<(channel_control)
41
+ return add_channel(channel_control) if channel_control.is_a?(Channel)
42
+ return add_group(channel_control) if channel_control.is_a?(ChannelGroup)
43
+ raise TypeError, "#{channel_control} is not a #{ChannelControl}."
44
+ end
45
+
46
+ def add_channel(channel)
47
+ FMOD.type?(channel, Channel)
48
+ channel.group = self
49
+ channel
50
+ end
51
+
52
+ def add_group(group, propagate_clock = true)
53
+ FMOD.type?(group, ChannelGroup)
54
+ FMOD.invoke(:ChannelGroup_AddGroup, self, group,
55
+ propagate_clock.to_i, connection = int_ptr)
56
+ DspConnection.new(connection)
57
+ end
58
+
59
+ alias_method :channel, :[]
60
+ end
61
+ end
@@ -0,0 +1,35 @@
1
+
2
+ require_relative './core/structure'
3
+ require_relative './core/structures'
4
+ require_relative './core/bool_description'
5
+ require_relative './core/channel_mask'
6
+ require_relative './core/data_description'
7
+ require_relative './core/driver'
8
+ require_relative './core/dsp_description'
9
+ require_relative './core/dsp_index'
10
+ require_relative './core/dsp_type'
11
+ require_relative './core/extensions'
12
+ require_relative './core/file_system'
13
+ require_relative './core/filter_type'
14
+ require_relative './core/float_description'
15
+ require_relative './core/guid'
16
+ require_relative './core/init_flags'
17
+ require_relative './core/integer_description'
18
+ require_relative './core/mode'
19
+ require_relative './core/output_type'
20
+ require_relative './core/parameter_info'
21
+ require_relative './core/parameter_type'
22
+ require_relative './core/result'
23
+ require_relative './core/reverb'
24
+ require_relative './core/sound_ex_info'
25
+ require_relative './core/sound_format'
26
+ require_relative './core/sound_group_behavior'
27
+ require_relative './core/sound_type'
28
+ require_relative './core/speaker_index'
29
+ require_relative './core/speaker_mode'
30
+ require_relative './core/spectrum_data'
31
+ require_relative './core/tag'
32
+ require_relative './core/tag_data_type'
33
+ require_relative './core/time_unit'
34
+ require_relative './core/vector'
35
+ require_relative './core/window_type'
@@ -0,0 +1,18 @@
1
+ module FMOD
2
+ module Core
3
+ class BoolDescription < Structure
4
+
5
+ def initialize(address = nil)
6
+ super(address, [TYPE_INT, TYPE_VOIDP], [:default, :names])
7
+ end
8
+
9
+ def default
10
+ self[:default] != 0
11
+ end
12
+
13
+ def names
14
+ %w(true false)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ module FMOD
2
+ module Core
3
+ module ChannelMask
4
+ FRONT_LEFT = 0x00000001
5
+ FRONT_RIGHT = 0x00000002
6
+ FRONT_CENTER = 0x00000004
7
+ LOW_FREQUENCY = 0x00000008
8
+ SURROUND_LEFT = 0x00000010
9
+ SURROUND_RIGHT = 0x00000020
10
+ BACK_LEFT = 0x00000040
11
+ BACK_RIGHT = 0x00000080
12
+ BACK_CENTER = 0x00000100
13
+ MONO = FRONT_LEFT
14
+ STEREO = FRONT_LEFT | FRONT_RIGHT
15
+ LRC = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER
16
+ QUAD = FRONT_LEFT | FRONT_RIGHT | SURROUND_LEFT | SURROUND_RIGHT
17
+ SURROUND = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT
18
+ FIVE_POINT_ONE = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT
19
+ FIVE_POINT_ONE_REARS = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | BACK_LEFT | BACK_RIGHT
20
+ SEVEN_POINT_ZERO = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT
21
+ SEVEN_POINT_ONE = FRONT_LEFT | FRONT_RIGHT | FRONT_CENTER | LOW_FREQUENCY | SURROUND_LEFT | SURROUND_RIGHT | BACK_LEFT | BACK_RIGHT
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module FMOD
2
+ module Core
3
+ class DataDescription < Structure
4
+
5
+ def initialize(address = nil)
6
+ super(address, [TYPE_INT], [:data_type])
7
+ end
8
+
9
+ def data_type
10
+ self[:data_type]
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,59 @@
1
+ module FMOD
2
+ module Core
3
+
4
+ ##
5
+ # Identification information about a sound device.
6
+ class Driver
7
+
8
+ private_class_method :new
9
+
10
+ ##
11
+ # @return [Integer] the enumerated driver ID.
12
+ attr_reader :id
13
+
14
+ ##
15
+ # @return [String] the name of the device encoded in a UTF-8 string.
16
+ attr_reader :name
17
+
18
+ ##
19
+ # @return [Guid] the GUID that uniquely identifies the device.
20
+ attr_reader :guid
21
+
22
+ ##
23
+ # @return [Integer] the sample rate this device operates at.
24
+ attr_reader :rate
25
+
26
+ ##
27
+ # @return [Integer] the speaker setup this device is currently using.
28
+ # @see SpeakerMode
29
+ attr_reader :speaker_mode
30
+
31
+ ##
32
+ # @return [Integer] the number of channels in the current speaker setup.
33
+ attr_reader :channels
34
+
35
+ ##
36
+ # @return [Integer] flags that provide additional information about the
37
+ # driver.
38
+ attr_reader :state
39
+
40
+ ##
41
+ # @param args [Array] Array of binary data.
42
+ # @api private
43
+ def initialize(args)
44
+ @id = args.shift
45
+ # noinspection RubyResolve
46
+ @name = args.shift.delete("\0").force_encoding(Encoding::UTF_8)
47
+ args.shift
48
+ @guid = args.shift
49
+ @rate, @speaker_mode, @channels, @state = args.join.unpack('l*')
50
+ end
51
+
52
+ ##
53
+ # @return [Boolean] +true+ if this a record driver, otherwise +false+.
54
+ def record_driver?
55
+ !@state.nil?
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,7 @@
1
+ module FMOD
2
+ module Core
3
+ class DspDescription < Structure
4
+ # TODO
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module FMOD
2
+ module Core
3
+ module DspIndex
4
+ HEAD = -1
5
+ FADER = -2
6
+ TAIL = -3
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ module FMOD
2
+ module Core
3
+ module DspType
4
+ UNKNOWN = 0
5
+ MIXER = 1
6
+ OSCILLATOR = 2
7
+ LOW_PASS = 3
8
+ IT_LOW_PASS = 4
9
+ HIGH_PASS = 5
10
+ ECHO = 6
11
+ FADER = 7
12
+ FLANGE = 8
13
+ DISTORTION = 9
14
+ NORMALIZE = 10
15
+ LIMITER = 11
16
+ PARAM_EQ = 12
17
+ PITCH_SHIFT = 13
18
+ CHORUS = 14
19
+ VST_PLUGIN = 15
20
+ WINAMP_PLUGIN = 16
21
+ IT_ECHO = 17
22
+ COMPRESSOR = 18
23
+ SFX_REVERB = 19
24
+ LOW_PASS_SIMPLE = 20
25
+ DELAY = 21
26
+ TREMOLO = 22
27
+ LADSPA_PLUGIN = 23
28
+ SEND = 24
29
+ RETURN = 25
30
+ HIGH_PASS_SIMPLE = 26
31
+ PAN = 27
32
+ THREE_EQ = 28
33
+ FFT = 29
34
+ LOUDNESS_METER = 30
35
+ ENVELOPE_FOLLOWER = 31
36
+ CONVOLUTION_REVERB = 32
37
+ CHANNEL_MIX = 33
38
+ TRANSCEIVER = 34
39
+ OBJECT_PAN = 35
40
+ MULTIBAND_EQ = 36
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,28 @@
1
+
2
+ class Numeric
3
+
4
+ def clamp(min, max)
5
+ [min, self, max].sort[1]
6
+ end
7
+ end
8
+
9
+ class String
10
+
11
+ unless method_defined?(:unpack1)
12
+ def unpack1(format)
13
+ unpack(format).first
14
+ end
15
+ end
16
+ end
17
+
18
+ class TrueClass
19
+ def to_i
20
+ 1
21
+ end
22
+ end
23
+
24
+ class FalseClass
25
+ def to_i
26
+ 0
27
+ end
28
+ end
@@ -0,0 +1,86 @@
1
+ module FMOD
2
+ module Core
3
+ class FileSystem
4
+
5
+ include Fiddle
6
+
7
+ # TODO: Upsets the stack, causing a segfault with STD_CALL.
8
+
9
+ def initialize(system)
10
+ @callbacks = []
11
+ @cbs = [open_cb, close_cb, seek_cb, close_cb]
12
+ FMOD.invoke(:System_AttachFileSystem, system, *@cbs)
13
+ end
14
+
15
+ def on_open(proc = nil, &block)
16
+ set_callback(0, &(block_given? ? block : proc))
17
+ end
18
+
19
+ def on_close(proc = nil, &block)
20
+ set_callback(1, &(block_given? ? block : proc))
21
+ end
22
+
23
+ def on_read(proc = nil, &block)
24
+ set_callback(2, &(block_given? ? block : proc))
25
+ end
26
+
27
+ def on_seek(proc = nil, &block)
28
+ set_callback(3, &(block_given? ? block : proc))
29
+ end
30
+
31
+ private
32
+
33
+ def set_callback(index, &block)
34
+ raise LocalJumpError, "No block given." unless block_given?
35
+ @callbacks[index] = block
36
+ end
37
+
38
+ def open_cb
39
+ sig = Array.new(4, TYPE_VOIDP)
40
+ abi = FMOD::ABI
41
+ Closure::BlockCaller.new(TYPE_INT, sig, abi) do |name, size, ptr, user|
42
+ if @callbacks[0]
43
+ size = size.to_s(SIZEOF_INT).unpack1('L')
44
+ @callbacks[0].call(name, size, ptr, user)
45
+ end
46
+ Result::OK
47
+ end
48
+ end
49
+
50
+ def close_cb
51
+ sig = [TYPE_VOIDP, TYPE_VOIDP]
52
+ abi = FMOD::ABI
53
+ Closure::BlockCaller.new(TYPE_INT, sig, abi) do |handle, user_data|
54
+ @callbacks[1].call(handle, user_data) if @callbacks[1]
55
+ Result::OK
56
+ end
57
+ end
58
+
59
+ def read_cb
60
+ sig = Array.new(5, TYPE_VOIDP)
61
+ abi = FMOD::ABI
62
+ Closure::BlockCaller.new(TYPE_INT, sig, abi) do |handle, buffer, size, read, user|
63
+ if @callbacks[2]
64
+ @callbacks[2].call(handle, buffer, size, read, user)
65
+ end
66
+ Result::OK
67
+ end
68
+ end
69
+
70
+ def seek_cb
71
+ sig = Array.new(3, TYPE_VOIDP)
72
+ abi = FMOD::ABI
73
+ Closure::BlockCaller.new(TYPE_INT, sig, abi) do |handle, position, user|
74
+ if @callbacks[3]
75
+ @callbacks[3].call(handle, position, user)
76
+ end
77
+ Result::OK
78
+ end
79
+ end
80
+ end
81
+
82
+ # TODO: Remove after fixing
83
+ private_constant :FileSystem
84
+
85
+ end
86
+ end
@@ -0,0 +1,19 @@
1
+ module FMOD
2
+ module Core
3
+ module FilterType
4
+ DISABLED = 0
5
+ LOW_PASS_12DB = 1
6
+ LOW_PASS_24DB = 2
7
+ LOW_PASS_48DB = 3
8
+ HIGH_PASS_12DB = 4
9
+ HIGH_PASS_24DB = 5
10
+ HIGH_PASS_48DB = 6
11
+ LOW_SHELF = 7
12
+ HIGH_SHELF = 8
13
+ PEAKING = 9
14
+ BANDPASS = 10
15
+ NOTCH = 11
16
+ ALL_PASS = 12
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module FMOD
2
+ module Core
3
+ class FloatDescription < Structure
4
+
5
+ def initialize(address = nil)
6
+ types = [TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_INT]
7
+ members = [:min, :max, :default, :mapping]
8
+ super(address, types, members)
9
+ end
10
+
11
+ [:min, :max, :default, :mapping].each do |symbol|
12
+ define_method(symbol) { self[symbol] }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,50 @@
1
+
2
+
3
+ module FMOD
4
+ module Core
5
+ class Guid < Structure
6
+
7
+ def initialize(address = nil)
8
+ types = [TYPE_INT, TYPE_SHORT, TYPE_SHORT, [TYPE_CHAR, 8]]
9
+ members = [:data1, :data2, :data3, :data4]
10
+ super(address, types, members)
11
+ end
12
+
13
+ def data1
14
+ [self[:data1]].pack('l').unpack1('L')
15
+ end
16
+
17
+ def data2
18
+ [self[:data2]].pack('s').unpack1('S')
19
+ end
20
+
21
+ def data3
22
+ [self[:data3]].pack('s').unpack1('S')
23
+ end
24
+
25
+ def data4
26
+ self[:data4].pack('c*').unpack('C*')
27
+ end
28
+
29
+ def eql?(obj)
30
+ if obj.is_a?(Guid)
31
+ return false unless data1 == obj.data1
32
+ return false unless data2 == obj.data2
33
+ return false unless data3 == obj.data3
34
+ return data4 == obj.data4
35
+ end
36
+ to_s.tr('-', '').casecmp(obj.to_s.tr('-', '')).zero?
37
+ end
38
+
39
+ def ==(obj)
40
+ eql?(obj)
41
+ end
42
+
43
+ def to_s
44
+ d4 = data4
45
+ last = d4[2, 6].map { |byte| "%02X" % byte }.join
46
+ "%08X-%04X-%04X-%02X%02X-#{last}" % [data1, data2, data3, d4[0], d4[1]]
47
+ end
48
+ end
49
+ end
50
+ end