fmod 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c772ecf5f77aade5c16621fe21270b20abec3078
4
- data.tar.gz: f01973742360bb5ac77e442ce6167f2d60f540f3
3
+ metadata.gz: 7d2902236224e5d663766bcc5b5fb7c48147aa20
4
+ data.tar.gz: a8b3106722a1da66d22ec30902a24bedaacec0ab
5
5
  SHA512:
6
- metadata.gz: 8c8ed671237062f1b82ddff1abb2d1b6db181ce908cb7a16c98679b7ac9b74cdf9c91fb245a7aa42592cfbccf278c8850d6dc42be21a6c81e477e4abd6ba4123
7
- data.tar.gz: 6546ee0eee3da8627a77500d2bd2ee82287f441830749f44fa4a8ef96e61e08dfd2e604fbf1db23f41d47f5ec071e92fd1fb55d925f462e49c95f6cfa2b2bc16
6
+ metadata.gz: 1c651d58f0ae40f3c5f615e9bb0a1435b43f07f8d86f0c8dae6441cf8b704a35bdfa3a74a39b08b2ca9ad50000f278a0582ff8a31a5dda0a704be1826fe9651b
7
+ data.tar.gz: b77425a784f7f48c5687f693f013aab28c48ebd9267664a90b74a43f9c67254534af7ac71479793d135b2a51a70809f7c8cf322e9e35d91dd327c4f6b8d059f3
@@ -0,0 +1,29 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a report to help us improve
4
+
5
+ ---
6
+
7
+ **Describe the bug**
8
+ A clear and concise description of what the bug is.
9
+
10
+ **To Reproduce**
11
+ Steps to reproduce the behavior:
12
+ 1. Go to '...'
13
+ 2. Click on '....'
14
+ 3. Scroll down to '....'
15
+ 4. See error
16
+
17
+ **Expected behavior**
18
+ A clear and concise description of what you expected to happen.
19
+
20
+ **Screenshots**
21
+ If applicable, add screenshots to help explain your problem.
22
+
23
+ **Desktop (please complete the following information):**
24
+ - OS: [e.g. iOS]
25
+ - Version [e.g. 22]
26
+ - FMOD Library Version [e.g. default, 4.01.06]
27
+
28
+ **Additional context**
29
+ Add any other context about the problem here.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest an idea for this project
4
+
5
+ ---
6
+
7
+ **Is your feature request related to a problem? Please describe.**
8
+ A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9
+
10
+ **Describe the solution you'd like**
11
+ A clear and concise description of what you want to happen.
12
+
13
+ **Describe alternatives you've considered**
14
+ A clear and concise description of any alternative solutions or features you've considered.
15
+
16
+ **Additional context**
17
+ Add any other context or screenshots about the feature request here.
@@ -0,0 +1,92 @@
1
+ # Contributing
2
+
3
+ When contributing to this repository, please first discuss the change you wish to make via issue,
4
+ email, or any other method with the owners of this repository before making a change.
5
+
6
+ Please note we have a code of conduct, please follow it in all your interactions with the project.
7
+
8
+ ## Pull Request Process
9
+
10
+ 1. Ensure any install or build dependencies are removed before the end of the layer when doing a
11
+ build.
12
+ 2. Update the README.md with details of changes to the interface, this includes new environment
13
+ variables, exposed ports, useful file locations and container parameters.
14
+ 3. Increase the version numbers in any examples files and the README.md to the new version that this
15
+ Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/).
16
+ 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you
17
+ do not have permission to do that, you may request the second reviewer to merge it for you.
18
+
19
+ ## Code of Conduct
20
+
21
+ ### Our Pledge
22
+
23
+ In the interest of fostering an open and welcoming environment, we as
24
+ contributors and maintainers pledge to making participation in our project and
25
+ our community a harassment-free experience for everyone, regardless of age, body
26
+ size, disability, ethnicity, gender identity and expression, level of experience,
27
+ nationality, personal appearance, race, religion, or sexual identity and
28
+ orientation.
29
+
30
+ ### Our Standards
31
+
32
+ Examples of behavior that contributes to creating a positive environment
33
+ include:
34
+
35
+ * Using welcoming and inclusive language
36
+ * Being respectful of differing viewpoints and experiences
37
+ * Gracefully accepting constructive criticism
38
+ * Focusing on what is best for the community
39
+ * Showing empathy towards other community members
40
+
41
+ Examples of unacceptable behavior by participants include:
42
+
43
+ * The use of sexualized language or imagery and unwelcome sexual attention or
44
+ advances
45
+ * Trolling, insulting/derogatory comments, and personal or political attacks
46
+ * Public or private harassment
47
+ * Publishing others' private information, such as a physical or electronic
48
+ address, without explicit permission
49
+ * Other conduct which could reasonably be considered inappropriate in a
50
+ professional setting
51
+
52
+ ### Our Responsibilities
53
+
54
+ Project maintainers are responsible for clarifying the standards of acceptable
55
+ behavior and are expected to take appropriate and fair corrective action in
56
+ response to any instances of unacceptable behavior.
57
+
58
+ Project maintainers have the right and responsibility to remove, edit, or
59
+ reject comments, commits, code, wiki edits, issues, and other contributions
60
+ that are not aligned to this Code of Conduct, or to ban temporarily or
61
+ permanently any contributor for other behaviors that they deem inappropriate,
62
+ threatening, offensive, or harmful.
63
+
64
+ ### Scope
65
+
66
+ This Code of Conduct applies both within project spaces and in public spaces
67
+ when an individual is representing the project or its community. Examples of
68
+ representing a project or community include using an official project e-mail
69
+ address, posting via an official social media account, or acting as an appointed
70
+ representative at an online or offline event. Representation of a project may be
71
+ further defined and clarified by project maintainers.
72
+
73
+ ### Enforcement
74
+
75
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
76
+ reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
77
+ complaints will be reviewed and investigated and will result in a response that
78
+ is deemed necessary and appropriate to the circumstances. The project team is
79
+ obligated to maintain confidentiality with regard to the reporter of an incident.
80
+ Further details of specific enforcement policies may be posted separately.
81
+
82
+ Project maintainers who do not follow or enforce the Code of Conduct in good
83
+ faith may face temporary or permanent repercussions as determined by other
84
+ members of the project's leadership.
85
+
86
+ ### Attribution
87
+
88
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
89
+ available at [http://contributor-covenant.org/version/1/4][version]
90
+
91
+ [homepage]: http://contributor-covenant.org
92
+ [version]: http://contributor-covenant.org/version/1/4/
@@ -0,0 +1,23 @@
1
+ === 0.9.1 / 2018-07-10
2
+
3
+ * Added Features
4
+ * Expanded methods to FMOD::Core::Structure
5
+ * names - Gets array of field name symbols
6
+ * values - Gets all the structure fields as an array
7
+
8
+ * Bug Fixes
9
+ * Fixed getting Reverb from System object would cause segmentation fault
10
+
11
+ * Documentation
12
+ * Completed for Channel, ChannelGroup, and ChannelControl
13
+ * Various enum classes
14
+ * Current documentation completion is 71%
15
+
16
+ * Misc.
17
+ * Updated gem description (poor formatting)
18
+ * Added templates for pull-requests, bugs, etc.
19
+
20
+
21
+ === 0.9.0 / 2018-07-09
22
+
23
+ * Initial public release
@@ -0,0 +1,17 @@
1
+ ### All Submissions:
2
+
3
+ * [ ] Have you followed the guidelines in our Contributing document?
4
+ * [ ] Have you checked to ensure there aren't other open [Pull Requests](../../pulls) for the same update/change?
5
+
6
+ <!-- You can erase any parts of this template not applicable to your Pull Request. -->
7
+
8
+ ### New Feature Submissions:
9
+
10
+ 1. [ ] Does your submission pass tests?
11
+ 2. [ ] Have you lint your code locally prior to submission?
12
+
13
+ ### Changes to Core Features:
14
+
15
+ * [ ] Have you added an explanation of what your changes do and why you'd like us to include them?
16
+ * [ ] Have you written new tests for your core changes, as applicable?
17
+ * [ ] Have you successfully ran tests with your changes locally?
data/README.md CHANGED
@@ -1,31 +1,32 @@
1
1
  # FMOD
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/fmod.svg)](https://badge.fury.io/rb/fmod) ![Documentation](https://img.shields.io/badge/Documentation-71%25-orange.svg)
3
4
 
4
5
 
5
6
  A full-featured (*complete* Ruby wrapper) of the ultra-powerful FMOD Low-Level API. Uses the built-in Fiddle library (Ruby 2.0+), and has no external gem dependencies, all that is needed is the native FMOD platform-specific native FMOD libraries.
6
7
 
7
8
  Supports a host of audio formats including:
8
- * Audio Interchange File Format (.aiff )
9
- * Advanced Systems Format (.asf)
10
- * Advanced Stream Redirector (.asx)
11
- * Downloadable Sound (.dls)
12
- * Free Loss-less Audio Codec (.flac)
13
- * FMOD Sound Bank (.fsb)
14
- * Impulse Tracker (.it)
15
- * MPEG Audio Layer 3 URL (.m3u)
16
- * Musical Instrument Digital Interface (.mid, .midi)
17
- * Module Format (.mod)
18
- * MPEG Audio Layer 2 (.mp2)
19
- * MPEG Audio Layer 3 (.mp3)
20
- * OGG Vorbis (.ogg)
21
- * Playlist (.pls)
22
- * ScreamTracker 3 Module (.s3m )
23
- * PS2/PSP Format (.vag )
24
- * Waveform Audio File Forma (.wav )
25
- * Windows Media Audio Redirector (.wax )
26
- * Windows Media Audio (.wma )
27
- * Extended Module (.xm )
28
- * Windows Media Audio (Xbox 360) (.xma)
9
+ * Audio Interchange File Format (.aiff )
10
+ * Advanced Systems Format (.asf)
11
+ * Advanced Stream Redirector (.asx)
12
+ * Downloadable Sound (.dls)
13
+ * Free Loss-less Audio Codec (.flac)
14
+ * FMOD Sound Bank (.fsb)
15
+ * Impulse Tracker (.it)
16
+ * MPEG Audio Layer 3 URL (.m3u)
17
+ * Musical Instrument Digital Interface (.mid, .midi)
18
+ * Module Format (.mod)
19
+ * MPEG Audio Layer 2 (.mp2)
20
+ * MPEG Audio Layer 3 (.mp3)
21
+ * OGG Vorbis (.ogg)
22
+ * Playlist (.pls)
23
+ * ScreamTracker 3 Module (.s3m )
24
+ * PS2/PSP Format (.vag )
25
+ * Waveform Audio File Forma (.wav )
26
+ * Windows Media Audio Redirector (.wax )
27
+ * Windows Media Audio (.wma )
28
+ * Extended Module (.xm )
29
+ * Windows Media Audio (Xbox 360) (.xma)
29
30
 
30
31
  FMOD is most widely known for its application in video games for sound effects, as it fully supports 3D sound, and can be found in all popular video game consoles (Sony, Microsoft, and Nintendo), as well as a large number of popular PC and mobile games. Built-in is a large collection of audio effects that can be applied to a sound, including various equalizers, advanced reverb environments, pitch-shifting, frequency, flange, chorus, and many, many more.
31
32
 
@@ -71,7 +72,7 @@ Each get/set method in the FMOD API has been converted to an "attribute" that ca
71
72
 
72
73
  ## Future Releases
73
74
 
74
- As of the first release, only slightly better than 50% of documentation is complete. The scripts are highly technical, and good documentation takes time, but it is actively being updated, and will be completed at the highest priority level. If you are using version `1.0.0`, you will have to rely more heavily upon the included FMOD Low-Level API Reference that is included in the `./extras` folder.
75
+ As of the current release, only slightly better than 71% of documentation is complete. The scripts are highly technical, and good documentation takes time, but it is actively being updated, and will be completed at the highest priority level. If you are using version `1.0.0`, you will have to rely more heavily upon the included FMOD Low-Level API Reference that is included in the `./extras` folder.
75
76
 
76
77
  There is still yet to be a few areas that need completed, and are in active development. Included are the following known issues:
77
78
  * FMOD plugin support (including 3rd party codecs)
@@ -6,38 +6,10 @@ require 'fmod/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'fmod'
8
8
  spec.version = FMOD::VERSION
9
- spec.authors = ['Eric "ForeverZero" Freed']
9
+ spec.authors = ['Eric "ForeverZer0" Freed']
10
10
  spec.email = ['efreed09@gmail.com']
11
11
  spec.summary = %q{Ruby wrapper around the high performance, cross-platform FMOD low-level sound library. You get all the benefits of the FMOD library, but in the object-oriented Ruby way!}
12
- spec.description = %q{A full-featured (complete Ruby wrapper) of the ultra-powerful FMOD Low-Level API. Uses the built-in Fiddle library (Ruby 2.0+), and has no external gem dependencies, all that is needed is the native FMOD platform-specific native FMOD libraries (included).
13
-
14
- FMOD supports a host of audio formats including:
15
-
16
- - Audio Interchange File Format (.aiff )
17
- - Advanced Systems Format (.asf)
18
- - Advanced Stream Redirector (.asx)
19
- - Downloadable Sound (.dls)
20
- - Free Lossless Audio Codec (.flac)
21
- - FMOD Sound Bank (.fsb)
22
- - Impulse Tracker (.it)
23
- - MPEG Audio Layer 3 URL (.m3u)
24
- - Musical Instrument Digital Interface (.mid, .midi)
25
- - Module Format (.mod)
26
- - MPEG Audio Layer 2 (.mp2)
27
- - MPEG Audio Layer 3 (.mp3)
28
- - OGG Vorbis (.ogg)
29
- - Playlist (.pls)
30
- - ScreamTracker 3 Module (.s3m )
31
- - PS2/PSP Format (.vag )
32
- - Waveform Audio File Forma (.wav )
33
- - Windows Media Audio Redirector (.wax )
34
- - Windows Media Audio (.wma )
35
- - Extended Module (.xm )
36
- - Windows Media Audio (Xbox 360) (.xma)
37
-
38
- FMOD is most widely known for its application in video games for sound effects, as it fully supports 3D sound, and can be found in all popular video game consoles (Sony, Microsoft, and Nintendo), as well as a large number of popular PC and mobile games. Built-in is a large collection of audio effects that can be applied to a sound, including various equalizers, advanced reverb environments, pitch-shifting, frequency, flange, chorus, and many, many more.
39
-
40
- The wrapper supports callbacks for various events, such as sync-points in wave files, sound playback ending (either by user or end of data), and various other scenarios. It additionally supports access to raw PCM data directly from the sound card, for creating visualizations or examining the sound in real-time.}
12
+ spec.description = %q{A full-featured (complete Ruby wrapper) of the ultra-powerful FMOD Low-Level API. Uses the built-in Fiddle library (Ruby 2.0+), and has no external gem dependencies, all that is needed is the FMOD platform-specific libraries (included). FMOD supports a host of audio formats including .aiff, .asf, .asx, .dls, .flac, .fsb, .it, .m3u, .mid, .midi, .mod, .mp2, .mp3, .ogg .pls, .s3m , vag, .wav, .wax, .wma, .xm, and.xma.}
41
13
 
42
14
  spec.homepage = 'https://github.com/ForeverZer0/fmod'
43
15
  spec.license = 'MIT'
@@ -3,6 +3,9 @@ require 'fiddle'
3
3
  require 'fiddle/import'
4
4
  require 'rbconfig'
5
5
 
6
+ ##
7
+ # Top-level namespace containing the entirety of the FMOD API.
8
+ # @author Eric "ForeverZer0" Freed
6
9
  module FMOD
7
10
 
8
11
  include Fiddle
@@ -430,7 +433,7 @@ module FMOD
430
433
  #
431
434
  # @param function [Symbol] Symbol name of an FMOD function, without the the
432
435
  # leading "FMOD_" prefix.
433
- # @raise [Error] if the result code returned by FMOD is not {Result::OK}.
436
+ # @raise [Error] if the result code returned by FMOD is not 0.
434
437
  # @return [void]
435
438
  # @see invoke_protect
436
439
  def self.invoke(function, *args)
@@ -1,5 +1,8 @@
1
1
 
2
2
  module FMOD
3
+
4
+ ##
5
+ # Represents a sound-card channel and a interface to sound playback.
3
6
  class Channel < ChannelControl
4
7
 
5
8
  ##
@@ -1,9 +1,183 @@
1
1
 
2
2
  module FMOD
3
+
4
+ ##
5
+ # @abstract
6
+ # The base class for both {Channel} and {ChannelGroup} objects.
3
7
  class ChannelControl < Handle
4
8
 
9
+ ##
10
+ # Emulates an Array-type container of a {ChannelControl}'s DSP chain.
11
+ class DspChain
12
+
13
+ include Enumerable
14
+
15
+ ##
16
+ # Creates a new instance of a {DspChain} for the specified
17
+ # {ChannelControl}.
18
+ #
19
+ # @param channel [ChannelControl] The channel or channel group to create
20
+ # the collection wrapper for.
21
+ def initialize(channel)
22
+ FMOD.type?(channel, ChannelControl)
23
+ @channel = channel
24
+ end
25
+
26
+ ##
27
+ # Retrieves the number of DSPs within the chain. This includes the
28
+ # built-in {FMOD::Effects::Fader} DSP.
29
+ # @return [Integer]
30
+ def count
31
+ buffer = "\0" * Fiddle::SIZEOF_INT
32
+ FMOD.invoke(:ChannelGroup_GetNumDSPs, @channel, buffer)
33
+ buffer.unpack1('l')
34
+ end
35
+
36
+ ##
37
+ # @overload each(&block)
38
+ # If called with a block, passes each DSP in turn before returning self.
39
+ # @yield [dsp] Yields a DSP instance to the block.
40
+ # @yieldparam dsp [Dsp] The DSP instance.
41
+ # @return [self]
42
+ # @overload each
43
+ # Returns an enumerator for the {DspChain} if no block is given.
44
+ # @return [Enumerator]
45
+ def each
46
+ return to_enum(:each) unless block_given?
47
+ (0...count).each { |i| yield self[i] }
48
+ self
49
+ end
50
+
51
+ ##
52
+ # Element reference. Returns the element at index.
53
+ # @param index [Integer] The index into the {DspChain} to retrieve.
54
+ # @return [Dsp|nil] The DSP at the specified index, or +nil+ if index is
55
+ # out of range.
56
+ def [](index)
57
+ return nil unless index.between?(-2, count)
58
+ dsp = "\0" * Fiddle::SIZEOF_INTPTR_T
59
+ FMOD.invoke(:ChannelGroup_GetDSP, @channel, index, dsp)
60
+ Dsp.from_handle(dsp)
61
+ end
62
+
63
+ ##
64
+ # Element assignment. Sets the element at the specified index.
65
+ # @param index [Integer] The index into the {DspChain} to set.
66
+ # @param dsp [Dsp] A DSP instance.
67
+ # @return [Dsp] The given DSP instance.
68
+ def []=(index, dsp)
69
+ FMOD.type?(dsp, Dsp)
70
+ FMOD.invoke(:ChannelGroup_AddDSP, @channel, index, dsp)
71
+ dsp
72
+ end
73
+
74
+ ##
75
+ # Appends or pushes the given object(s) on to the end of this {DspChain}. This
76
+ # expression returns +self+, so several appends may be chained together.
77
+ # @param dsp [Dsp] One or more DSP instance(s).
78
+ # @return [self]
79
+ def add(*dsp)
80
+ dsp.each { |d| self[DspIndex::TAIL] = d }
81
+ self
82
+ end
83
+
84
+ ##
85
+ # Prepends objects to the front of +self+, moving other elements upwards.
86
+ # @param dsp [Dsp] A DSP instance.
87
+ # @return [self]
88
+ def unshift(dsp)
89
+ self[DspIndex::HEAD] = dsp
90
+ self
91
+ end
92
+
93
+ ##
94
+ # Removes the last element from +self+ and returns it, or +nil+ if the
95
+ # {DspChain} is empty.
96
+ # @return [Dsp|nil]
97
+ def pop
98
+ dsp = self[DspIndex::TAIL]
99
+ remove(dsp)
100
+ dsp
101
+ end
102
+
103
+ ##
104
+ # Returns the first element of +self+ and removes it (shifting all other
105
+ # elements down by one). Returns +nil+ if the array is empty.
106
+ # @return [Dsp|nil]
107
+ def shift
108
+ dsp = self[DspIndex::HEAD]
109
+ remove(dsp)
110
+ dsp
111
+ end
112
+
113
+ ##
114
+ # Deletes the specified DSP from this DSP chain. This does not release ot
115
+ # dispose the DSP unit, only removes from this {DspChain}, as a DSP unit
116
+ # can be shared.
117
+ # @param dsp [Dsp] The DSP to remove.
118
+ # @return [self]
119
+ def remove(dsp)
120
+ return unless dsp.is_a?(Dsp)
121
+ FMOD.invoke(:ChannelGroup_RemoveDSP, @channel, dsp)
122
+ self
123
+ end
124
+
125
+ ##
126
+ # Returns the index of the specified DSP.
127
+ # @param dsp [Dsp] The DSP to retrieve the index of.
128
+ # @return [Integer] The index of the DSP.
129
+ def index(dsp)
130
+ FMOD.type?(dsp, Dsp)
131
+ buffer = "\0" * Fiddle::SIZEOF_INT
132
+ FMOD.invoke(:ChannelGroup_GetDSPIndex, @channel, dsp, buffer)
133
+ buffer.unpack1('l')
134
+ end
135
+
136
+ ##
137
+ # Moves a DSP unit that exists in this {DspChain} to a new index.
138
+ # @param dsp [Dsp] The DSP instance to move, must exist within this
139
+ # {DspChain}.
140
+ # @param index [Integer] The new index to place the specified DSP.
141
+ # @return [self]
142
+ def move(dsp, index)
143
+ FMOD.type?(dsp, Dsp)
144
+ FMOD.invoke(:ChannelGroup_SetDSPIndex, @channel, dsp, index)
145
+ self
146
+ end
147
+
148
+ alias_method :size, :count
149
+ alias_method :length, :count
150
+ alias_method :length, :count
151
+ alias_method :delete, :remove
152
+ alias_method :push, :add
153
+ alias_method :<<, :add
154
+
155
+ private_class_method :new
156
+ end
157
+
158
+ ##
159
+ # Represents the start (and/or stop) time relative to the parent channel
160
+ # group DSP clock, with sample accuracy.
161
+ #
162
+ # @attr start [Integer] The DSP clock of the parent channel group to audibly
163
+ # start playing sound at.
164
+ # @attr end [Integer] The DSP clock of the parent channel group to audibly
165
+ # stop playing sound at.
166
+ # @attr stop [Boolean] +true+ to stop according to
167
+ # {ChannelControl.playing?}, otherwise +false+ to remain "active" and a
168
+ # new start delay could start playback again at a later time.
5
169
  ChannelDelay = Struct.new(:start, :end, :stop)
6
170
 
171
+ ##
172
+ # The settings for the 3D distance filter properties.
173
+ #
174
+ # @attr custom [Boolean] The enabled/disabled state of the FMOD distance
175
+ # rolloff calculation. Default is +false+.
176
+ # @attr level [Float] The manual user attenuation, where 1.0 is no
177
+ # attenuation and 0.0 is complete attenuation. Default is 1.0.
178
+ # @attr frequency [Float] The center frequency in Hz for the high-pass
179
+ # filter used to simulate distance attenuation, from 10.0 to 22050.0.
180
+ # Default is 1500.0.
7
181
  DistanceFilter = Struct.new(:custom, :level, :frequency)
8
182
 
9
183
  include Fiddle
@@ -105,50 +279,52 @@ module FMOD
105
279
  # occlusion.
106
280
  float_reader(:audibility, :ChannelGroup_GetAudibility)
107
281
 
282
+ # @!attribute low_pass_gain
283
+ # The dry signal when low-pass filtering is applied.
284
+ # * *Minimum:* 0.0 (silent, full filtering)
285
+ # * *Maximum:* 1.0 (full volume, no filtering)
286
+ # * *Default:* 1.0
287
+ # @return [Float] the linear gain level.
108
288
  float_reader(:low_pass_gain, :ChannelGroup_GetLowPassGain)
109
289
  float_writer(:low_pass_gain=, :ChannelGroup_SetLowPassGain, 0.0, 1.0)
110
290
 
291
+ # @!group 3D Sound
111
292
 
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
-
293
+ ##
294
+ # @!attribute level3D
295
+ # The 3D pan level.
296
+ # * *Minimum:* 0.0 (attenuation is ignored and panning as set by 2D panning
297
+ # functions)
298
+ # * *Maximum:* 1.0 (pan and attenuate according to 3D position)
299
+ # * *Default:* 0.0
300
+ # @return [Float] the 3D pan level.
143
301
  float_reader(:level3D, :ChannelGroup_Get3DLevel)
144
302
  float_writer(:level3D=, :ChannelGroup_Set3DLevel, 0.0, 1.0)
145
303
 
304
+ ##
305
+ # @!attribute spread3D
306
+ # The speaker spread angle.
307
+ # * *Minimum:* 0.0
308
+ # * *Maximum:* 360.0
309
+ # * *Default:* 0.0
310
+ # @return [Float] the spread of a 3D sound in speaker space.
146
311
  float_reader(:spread3D, :ChannelGroup_Get3DSpread)
147
312
  float_writer(:spread3D, :ChannelGroup_Set3DSpread, 0.0, 360.0)
148
313
 
314
+ ##
315
+ # @!attribute doppler3D
316
+ # The doppler scale.
317
+ # * *Minimum:* 0.0 (none)
318
+ # * *Maximum:* 5.0 (exaggerated)
319
+ # * *Default:* 1.0 (normal)
320
+ # @return [Float] the amount by which doppler is scaled.
149
321
  float_reader(:doppler3D, :ChannelGroup_Get3DDopplerLevel)
150
322
  float_writer(:doppler3D=, :ChannelGroup_Set3DDopplerLevel, 0.0, 5.0)
151
323
 
324
+ ##
325
+ # @!attribute direct_occlusion
326
+ # @return [Float] the occlusion factor for the direct path.
327
+
152
328
  def direct_occlusion
153
329
  direct = "\0" * SIZEOF_FLOAT
154
330
  FMOD.invoke(:ChannelGroup_Get3DOcclusion, self, direct, nil)
@@ -162,6 +338,10 @@ module FMOD
162
338
  direct
163
339
  end
164
340
 
341
+ ##
342
+ # @!attribute reverb_occlusion
343
+ # @return [Float] the occlusion factor for the reverb mix.
344
+
165
345
  def reverb_occlusion
166
346
  reverb = "\0" * SIZEOF_FLOAT
167
347
  FMOD.invoke(:ChannelGroup_Get3DOcclusion, self, nil, reverb)
@@ -176,58 +356,9 @@ module FMOD
176
356
  end
177
357
 
178
358
  ##
179
- # Add a volume point to fade from or towards, using a clock offset and 0.0
180
- # to 1.0 volume level.
181
- # @overload add_fade(fade_point)
182
- # @param fade_point [FadePoint] Fade point structure defining the values.
183
- # @overload add_fade(clock, volume)
184
- # @param clock [Integer] DSP clock of the parent channel group to set the
185
- # fade point volume.
186
- # @param volume [Float] Volume level where 0.0 is silent and 1.0 is normal
187
- # volume. Amplification is supported.
188
- # @return [self]
189
- def add_fade(*args)
190
- args = args[0].values if args.size == 1 && args[0].is_a?(FadePoint)
191
- FMOD.invoke(:ChannelGroup_AddFadePoint, self, *args)
192
- self
193
- end
194
-
195
- ##
196
- # Retrieves the number of fade points set within the {ChannelControl}.
197
- # @return [Integer] The number of fade points.
198
- def fade_point_count
199
- count = "\0" * SIZEOF_INT
200
- FMOD.invoke(:ChannelGroup_GetFadePoints, self, count, nil, nil)
201
- count.unpack1('l')
202
- end
203
-
204
- ##
205
- # Retrieve information about fade points stored within a {ChannelControl}.
206
- # @return [Array<FadePoint>] An array of {FadePoint} objects, or an empty
207
- # array if no fade points are present.
208
- def fade_points
209
- count = fade_point_count
210
- return [] if count.zero?
211
- clocks = "\0" * (count * SIZEOF_LONG_LONG)
212
- volumes = "\0" * (count * SIZEOF_FLOAT)
213
- FMOD.invoke(:ChannelGroup_GetFadePoints, self, int_ptr, clocks, volumes)
214
- args = clocks.unpack('Q*').zip(volumes.unpack('f*'))
215
- args.map { |values| FadePoint.new(*values) }
216
- end
217
-
218
- ##
219
- # Remove volume fade points on the time-line. This function will remove
220
- # multiple fade points with a single call if the points lay between the 2
221
- # specified clock values (inclusive).
222
- # @param clock_start [Integer] DSP clock of the parent channel group to
223
- # start removing fade points from.
224
- # @param clock_end [Integer] DSP clock of the parent channel group to start
225
- # removing fade points to.
226
- # @return [self]
227
- def remove_fade_points(clock_start, clock_end)
228
- FMOD.invoke(:ChannelGroup_RemoveFadePoints, self, clock_start, clock_end)
229
- self
230
- end
359
+ # @!attribute position3D
360
+ # @return [Vector] the position used to apply panning, attenuation and
361
+ # doppler.
231
362
 
232
363
  def position3D
233
364
  position = Vector.zero
@@ -241,6 +372,11 @@ module FMOD
241
372
  vector
242
373
  end
243
374
 
375
+ ##
376
+ # @!attribute velocity3D
377
+ # @return [Vector] the velocity used to apply panning, attenuation and
378
+ # doppler.
379
+
244
380
  def velocity3D
245
381
  velocity = Vector.zero
246
382
  FMOD.invoke(:ChannelGroup_Get3DAttributes, self, nil, velocity, nil)
@@ -253,6 +389,10 @@ module FMOD
253
389
  vector
254
390
  end
255
391
 
392
+ ##
393
+ # @!attribute distance_filter
394
+ # @return [DistanceFilter] the behaviour of a 3D distance filter, whether to
395
+ # enable or disable it, and frequency characteristics.
256
396
  def distance_filter
257
397
  args = ["\0" * SIZEOF_INT, "\0" * SIZEOF_FLOAT, "\0" * SIZEOF_FLOAT]
258
398
  FMOD.invoke(:ChannelGroup_Get3DDistanceFilter, self, *args)
@@ -297,61 +437,6 @@ module FMOD
297
437
  rolloff
298
438
  end
299
439
 
300
- ##
301
- # Sets the speaker volume levels for each speaker individually, this is a
302
- # helper to avoid having to set the mix matrix.
303
- #
304
- # Levels can be below 0 to invert a signal and above 1 to amplify the
305
- # signal. Note that increasing the signal level too far may cause audible
306
- # distortion. Speakers specified that don't exist will simply be ignored.
307
- # For more advanced speaker control, including sending the different
308
- # channels of a stereo sound to arbitrary speakers, see {#matrix}.
309
- #
310
- # @note This function overwrites any pan/mix-level by overwriting the
311
- # {ChannelControl}'s matrix.
312
- #
313
- # @param fl [Float] Volume level for the front left speaker of a
314
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
315
- # @param fr [Float] Volume level for the front right speaker of a
316
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
317
- # @param center [Float] Volume level for the center speaker of a
318
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
319
- # @param lfe [Float] Volume level for the sub-woofer speaker of a
320
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
321
- # @param sl [Float] Volume level for the surround left speaker of a
322
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
323
- # @param sr [Float] Volume level for the surround right speaker of a
324
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
325
- # @param bl [Float] Volume level for the back left speaker of a multichannel
326
- # speaker setup, 0.0 (silent), 1.0 (normal volume).
327
- # @param br [Float] Volume level for the back right speaker of a
328
- # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
329
- # @return [self]
330
- def output_mix(fl, fr, center, lfe, sl, sr, bl, br)
331
- FMOD.invoke(:ChannelGroup_SetMixLevelsOutput, self, fl,
332
- fr, center, lfe, sl, sr, bl, br)
333
- self
334
- end
335
-
336
- ##
337
- # Sets the incoming volume level for each channel of a multi-channel sound.
338
- # This is a helper to avoid calling {#matrix}.
339
- #
340
- # A multi-channel sound is a single sound that contains from 1 to 32
341
- # channels of sound data, in an interleaved fashion. If in the extreme case,
342
- # a 32 channel wave file was used, an array of 32 floating point numbers
343
- # denoting their volume levels would be passed in to the levels parameter.
344
- #
345
- # @param levels [Array<Float>] Array of volume levels for each incoming
346
- # channel.
347
- # @return [self]
348
- def input_mix(*levels)
349
- count = levels.size
350
- binary = levels.pack('f*')
351
- FMOD.invoke(:ChannelGroup_SetMixLevelsInput, self, binary, count)
352
- self
353
- end
354
-
355
440
  ##
356
441
  # @!attribute min_distance
357
442
  # @return [Float] Minimum volume distance in "units". (Default: 1.0)
@@ -407,18 +492,145 @@ module FMOD
407
492
  # dont need to. Some people have the confusion that maximum distance is the
408
493
  # point the sound will fade out to zero, this is not the case.
409
494
  #
410
- # @param min [Float] Minimum volume distance in "units".
411
- # * *Default:* 1.0
412
- # @param max [Float] Maximum volume distance in "units".
413
- # * *Default:* 10000.0
495
+ # @param min [Float] Minimum volume distance in "units".
496
+ # * *Default:* 1.0
497
+ # @param max [Float] Maximum volume distance in "units".
498
+ # * *Default:* 10000.0
499
+ #
500
+ # @see min_distance
501
+ # @see max_distance
502
+ # @return [void]
503
+ def min_max_distance(min, max)
504
+ FMOD.invoke(:ChannelGroup_Set3DMinMaxDistance, self, min, max)
505
+ end
506
+
507
+ ##
508
+ # @!attribute cone_orientation
509
+ # @return [Vector] the orientation of the sound projection cone.
510
+
511
+ def cone_orientation
512
+ vector = FMOD::Core::Vector.new
513
+ FMOD.invoke(:ChannelGroup_Get3DConeOrientation, self, vector)
514
+ vector
515
+ end
516
+
517
+ def cone_orientation=(vector)
518
+ FMOD.type?(vector, Vector)
519
+ FMOD.invoke(:ChannelGroup_Set3DConeOrientation, self, vector)
520
+ vector
521
+ end
522
+
523
+ # @!endgroup
524
+
525
+ ##
526
+ # Add a volume point to fade from or towards, using a clock offset and 0.0
527
+ # to 1.0 volume level.
528
+ # @overload add_fade(fade_point)
529
+ # @param fade_point [FadePoint] Fade point structure defining the values.
530
+ # @overload add_fade(clock, volume)
531
+ # @param clock [Integer] DSP clock of the parent channel group to set the
532
+ # fade point volume.
533
+ # @param volume [Float] Volume level where 0.0 is silent and 1.0 is normal
534
+ # volume. Amplification is supported.
535
+ # @return [self]
536
+ def add_fade(*args)
537
+ args = args[0].values if args.size == 1 && args[0].is_a?(FadePoint)
538
+ FMOD.invoke(:ChannelGroup_AddFadePoint, self, *args)
539
+ self
540
+ end
541
+
542
+ ##
543
+ # Retrieves the number of fade points set within the {ChannelControl}.
544
+ # @return [Integer] The number of fade points.
545
+ def fade_point_count
546
+ count = "\0" * SIZEOF_INT
547
+ FMOD.invoke(:ChannelGroup_GetFadePoints, self, count, nil, nil)
548
+ count.unpack1('l')
549
+ end
550
+
551
+ ##
552
+ # Retrieve information about fade points stored within a {ChannelControl}.
553
+ # @return [Array<FadePoint>] An array of {FadePoint} objects, or an empty
554
+ # array if no fade points are present.
555
+ def fade_points
556
+ count = fade_point_count
557
+ return [] if count.zero?
558
+ clocks = "\0" * (count * SIZEOF_LONG_LONG)
559
+ volumes = "\0" * (count * SIZEOF_FLOAT)
560
+ FMOD.invoke(:ChannelGroup_GetFadePoints, self, int_ptr, clocks, volumes)
561
+ args = clocks.unpack('Q*').zip(volumes.unpack('f*'))
562
+ args.map { |values| FadePoint.new(*values) }
563
+ end
564
+
565
+ ##
566
+ # Remove volume fade points on the time-line. This function will remove
567
+ # multiple fade points with a single call if the points lay between the 2
568
+ # specified clock values (inclusive).
569
+ # @param clock_start [Integer] DSP clock of the parent channel group to
570
+ # start removing fade points from.
571
+ # @param clock_end [Integer] DSP clock of the parent channel group to start
572
+ # removing fade points to.
573
+ # @return [self]
574
+ def remove_fade_points(clock_start, clock_end)
575
+ FMOD.invoke(:ChannelGroup_RemoveFadePoints, self, clock_start, clock_end)
576
+ self
577
+ end
578
+
579
+ ##
580
+ # Sets the speaker volume levels for each speaker individually, this is a
581
+ # helper to avoid having to set the mix matrix.
582
+ #
583
+ # Levels can be below 0 to invert a signal and above 1 to amplify the
584
+ # signal. Note that increasing the signal level too far may cause audible
585
+ # distortion. Speakers specified that don't exist will simply be ignored.
586
+ # For more advanced speaker control, including sending the different
587
+ # channels of a stereo sound to arbitrary speakers, see {#matrix}.
588
+ #
589
+ # @note This function overwrites any pan/mix-level by overwriting the
590
+ # {ChannelControl}'s matrix.
591
+ #
592
+ # @param fl [Float] Volume level for the front left speaker of a
593
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
594
+ # @param fr [Float] Volume level for the front right speaker of a
595
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
596
+ # @param center [Float] Volume level for the center speaker of a
597
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
598
+ # @param lfe [Float] Volume level for the sub-woofer speaker of a
599
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
600
+ # @param sl [Float] Volume level for the surround left speaker of a
601
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
602
+ # @param sr [Float] Volume level for the surround right speaker of a
603
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
604
+ # @param bl [Float] Volume level for the back left speaker of a multichannel
605
+ # speaker setup, 0.0 (silent), 1.0 (normal volume).
606
+ # @param br [Float] Volume level for the back right speaker of a
607
+ # multichannel speaker setup, 0.0 (silent), 1.0 (normal volume).
608
+ # @return [self]
609
+ def output_mix(fl, fr, center, lfe, sl, sr, bl, br)
610
+ FMOD.invoke(:ChannelGroup_SetMixLevelsOutput, self, fl,
611
+ fr, center, lfe, sl, sr, bl, br)
612
+ self
613
+ end
614
+
615
+ ##
616
+ # Sets the incoming volume level for each channel of a multi-channel sound.
617
+ # This is a helper to avoid calling {#matrix}.
618
+ #
619
+ # A multi-channel sound is a single sound that contains from 1 to 32
620
+ # channels of sound data, in an interleaved fashion. If in the extreme case,
621
+ # a 32 channel wave file was used, an array of 32 floating point numbers
622
+ # denoting their volume levels would be passed in to the levels parameter.
414
623
  #
415
- # @see min_distance
416
- # @see max_distance
417
- def min_max_distance(min, max)
418
- FMOD.invoke(:ChannelGroup_Set3DMinMaxDistance, self, min, max)
624
+ # @param levels [Array<Float>] Array of volume levels for each incoming
625
+ # channel.
626
+ # @return [self]
627
+ def input_mix(*levels)
628
+ count = levels.size
629
+ binary = levels.pack('f*')
630
+ FMOD.invoke(:ChannelGroup_SetMixLevelsInput, self, binary, count)
631
+ self
419
632
  end
420
633
 
421
-
422
634
  ##
423
635
  # @!attribute matrix
424
636
  # A 2D pan matrix that maps input channels (columns) to output speakers
@@ -466,72 +678,197 @@ module FMOD
466
678
  out_count, in_count, 0)
467
679
  end
468
680
 
469
-
681
+ ##
682
+ # Sets the pan level, this is a helper to avoid setting the {#matrix}.
683
+ #
684
+ # Mono sounds are panned from left to right using constant power panning
685
+ # (non-linear fade). This means when pan = 0.0, the balance for the sound in
686
+ # each speaker is 71% left and 71% right, not 50% left and 50% right. This
687
+ # gives (audibly) smoother pans.
688
+ #
689
+ # Stereo sounds heave each left/right value faded up and down according to
690
+ # the specified pan position. This means when pan is 0.0, the balance for
691
+ # the sound in each speaker is 100% left and 100% right. When pan is -1.0,
692
+ # only the left channel of the stereo sound is audible, when pan is 1.0,
693
+ # only the right channel of the stereo sound is audible.
694
+ #
695
+ # @param pan [Float] The desired pan level.
696
+ # * *Minimum:* -1.0 (left)
697
+ # * *Maximum:* 1.0 (right)
698
+ # * *Default:* 0.0 (center)
699
+ #
700
+ # @return [self]
470
701
  def pan(pan)
471
702
  FMOD.invoke(:ChannelGroup_SetPan, self, pan.clamp(-1.0, 1.0))
472
703
  self
473
704
  end
474
705
 
706
+ ##
707
+ # Stops the channel (or all channels in the channel group) from playing.
708
+ #
709
+ # Makes it available for re-use by the priority system.
710
+ #
711
+ # @return [void]
475
712
  def stop
476
713
  FMOD.invoke(:ChannelGroup_Stop, self)
477
- self
478
714
  end
479
715
 
716
+ ##
717
+ # Sets the paused state.
718
+ #
719
+ # @return [self]
720
+ # @see resume
721
+ # @see paused?
480
722
  def pause
481
723
  FMOD.invoke(:ChannelGroup_SetPaused, self, 1)
482
724
  self
483
725
  end
484
726
 
727
+ ##
728
+ # Resumes playback from a paused state.
729
+ #
730
+ # @return [self]
731
+ # @see pause
732
+ # @see paused?
485
733
  def resume
486
734
  FMOD.invoke(:ChannelGroup_SetPaused, self, 0)
487
735
  self
488
736
  end
489
737
 
738
+ ##
739
+ # Sets the mute state effectively silencing it or returning it to its normal
740
+ # volume.
741
+ #
742
+ # @return [self]
743
+ # @see unmute
744
+ # @see muted?
490
745
  def mute
491
746
  FMOD.invoke(:ChannelGroup_SetMute, self, 1)
747
+ self
492
748
  end
493
749
 
750
+ ##
751
+ # Resumes the volume from a muted state.
752
+ #
753
+ # @return [self]
754
+ # @see mute
755
+ # @see muted?
494
756
  def unmute
495
757
  FMOD.invoke(:ChannelGroup_SetMute, self, 0)
758
+ self
496
759
  end
497
760
 
761
+ ##
762
+ # @!attribute dsps
763
+ # @return [DspChain] the DSP chain of the {ChannelControl}, containing the
764
+ # effects currently applied.
498
765
  def dsps
499
766
  DspChain.send(:new, self)
500
767
  end
501
768
 
769
+ ##
770
+ # @!attribute [r] parent
771
+ # @return [System] the parent {System} object that was used to create this
772
+ # object.
502
773
  def parent
503
774
  FMOD.invoke(:ChannelGroup_GetSystemObject, self, system = int_ptr)
504
775
  System.new(system)
505
776
  end
506
777
 
778
+ ##
779
+ # Add a short 64 sample volume ramp to the specified time in the future
780
+ # using fade points.
781
+ #
782
+ # @param clock [Integer] DSP clock of the parent channel group when the
783
+ # volume will be ramped to.
784
+ # @param volume [Float] Volume level where 0 is silent and 1.0 is normal
785
+ # volume. Amplification is supported.
786
+ #
787
+ # @return [void]
507
788
  def fade_ramp(clock, volume)
508
789
  FMOD.invoke(:ChannelGroup_SetFadePointRamp, self, clock, volume)
509
790
  end
510
791
 
792
+ ##
793
+ # Retrieves the DSP clock value which count up by the number of samples per
794
+ # second in the software mixer, i.e. if the default sample rate is 48KHz,
795
+ # the DSP clock increments by 48000 per second.
796
+ #
797
+ # @return [Integer] the current clock value.
511
798
  def dsp_clock
512
799
  buffer = "\0" * SIZEOF_LONG_LONG
513
800
  FMOD.invoke(:ChannelGroup_GetDSPClock, self, buffer, nil)
514
801
  buffer.unpack1('Q')
515
802
  end
516
803
 
804
+ ##
805
+ # Retrieves the DSP clock value which count up by the number of samples per
806
+ # second in the software mixer, i.e. if the default sample rate is 48KHz,
807
+ # the DSP clock increments by 48000 per second.
808
+ #
809
+ # @return [Integer] the current parent clock value.
517
810
  def parent_clock
518
811
  buffer = "\0" * SIZEOF_LONG_LONG
519
812
  FMOD.invoke(:ChannelGroup_GetDSPClock, self, nil, buffer)
520
813
  buffer.unpack1('Q')
521
814
  end
522
815
 
816
+ ##
817
+ # Retrieves the wet level (or send level) for a particular reverb instance.
818
+ #
819
+ # @param index [Integer] Index of the particular reverb instance to target.
820
+ #
821
+ # @return [Float] the send level for the signal to the reverb, from 0 (none)
822
+ # to 1.0 (full).
823
+ # @see set_reverb_level
523
824
  def get_reverb_level(index)
524
825
  wet = "\0" * SIZEOF_FLOAT
525
826
  FMOD.invoke(:ChannelGroup_GetReverbProperties, self, index, wet)
526
827
  wet.unpack1('f')
527
828
  end
528
829
 
830
+ ##
831
+ # Sets the wet level (or send level) of a particular reverb instance.
832
+ #
833
+ # A Channel is automatically connected to all existing reverb instances due
834
+ # to the default wet level of 1.0. A ChannelGroup however will not send to
835
+ # any reverb by default requiring an explicit call to this function.
836
+ #
837
+ # A ChannelGroup reverb is optimal for the case where you want to send 1
838
+ # mixed signal to the reverb, rather than a lot of individual channel reverb
839
+ # sends. It is advisable to do this to reduce CPU if you have many Channels
840
+ # inside a ChannelGroup.
841
+ #
842
+ # Keep in mind when setting a wet level for a ChannelGroup, any Channels
843
+ # under that ChannelGroup will still have their existing sends to the
844
+ # reverb. To avoid this doubling up you should explicitly set the Channel
845
+ # wet levels to 0.0.
846
+ #
847
+ # @param index [Integer] Index of the particular reverb instance to target.
848
+ #
849
+ # @return [void]
850
+ # @see get_reverb_level
529
851
  def set_reverb_level(index, wet_level)
530
852
  wet = wet_level.clamp(0.0, 1.0)
531
853
  FMOD.invoke(:ChannelGroup_SetReverbProperties, self, index, wet)
532
- wet
533
854
  end
534
855
 
856
+ ##
857
+ # @!attribute delay
858
+ # The start (and/or stop) time relative to the parent channel group DSP
859
+ # clock, with sample accuracy.
860
+ #
861
+ # Every channel and channel group has its own DSP Clock. A channel or
862
+ # channel group can be delayed relatively against its parent, with sample
863
+ # accurate positioning. To delay a sound, use the 'parent' channel group DSP
864
+ # clock to reference against when passing values into this function.
865
+ #
866
+ # If a parent channel group changes its pitch, the start and stop times will
867
+ # still be correct as the parent clock is rate adjusted by that pitch.
868
+ #
869
+ # @return [ChannelDelay] the delay.
870
+ # @see set_delay
871
+
535
872
  def delay
536
873
  clock_start = "\0" * SIZEOF_LONG_LONG
537
874
  clock_end = "\0" * SIZEOF_LONG_LONG
@@ -547,24 +884,34 @@ module FMOD
547
884
  delay
548
885
  end
549
886
 
887
+ ##
888
+ # The start (and/or stop) time relative to the parent channel group DSP
889
+ # clock, with sample accuracy.
890
+ #
891
+ # Every channel and channel group has its own DSP Clock. A channel or
892
+ # channel group can be delayed relatively against its parent, with sample
893
+ # accurate positioning. To delay a sound, use the 'parent' channel group DSP
894
+ # clock to reference against when passing values into this function.
895
+ #
896
+ # If a parent channel group changes its pitch, the start and stop times will
897
+ # still be correct as the parent clock is rate adjusted by that pitch.
898
+ #
899
+ # @param clock_start [Integer] DSP clock of the parent channel group to
900
+ # audibly start playing sound at, a value of 0 indicates no delay.
901
+ # @param clock_end [Integer] DSP clock of the parent channel group to
902
+ # audibly stop playing sound at, a value of 0 indicates no delay.
903
+ # @param stop [Boolean] +true+ to stop according to {#playing?}, otherwise
904
+ # +false+ to remain "active" and a new start delay could start playback
905
+ # again at a later time.
906
+ #
907
+ # @return [self]
908
+ # @see delay
550
909
  def set_delay(clock_start, clock_end, stop)
551
910
  stop = stop.to_i
552
911
  FMOD.invoke(:ChannelGroup_SetDelay, self, clock_start, clock_end, stop)
553
912
  self
554
913
  end
555
914
 
556
- def cone_orientation
557
- vector = FMOD::Core::Vector.new
558
- FMOD.invoke(:ChannelGroup_Get3DConeOrientation, self, vector)
559
- vector
560
- end
561
-
562
- def cone_orientation=(vector)
563
- FMOD.type?(vector, Vector)
564
- FMOD.invoke(:ChannelGroup_Set3DConeOrientation, self, vector)
565
- vector
566
- end
567
-
568
915
  # @!group Callbacks
569
916
 
570
917
  ##
@@ -633,6 +980,8 @@ module FMOD
633
980
 
634
981
  # @!endgroup
635
982
 
983
+ ##
984
+ # @api private
636
985
  def initialize(address = nil)
637
986
  super
638
987
  @callbacks = {}
@@ -666,155 +1015,6 @@ module FMOD
666
1015
  @callbacks[index] << block
667
1016
  self
668
1017
  end
669
-
670
- ##
671
- # Emulates an Array-type container of a {ChannelControl}'s DSP chain.
672
- class DspChain
673
-
674
- include Enumerable
675
-
676
- ##
677
- # Creates a new instance of a {DspChain} for the specified
678
- # {ChannelControl}.
679
- #
680
- # @param channel [ChannelControl] The channel or channel group to create
681
- # the collection wrapper for.
682
- def initialize(channel)
683
- FMOD.type?(channel, ChannelControl)
684
- @channel = channel
685
- end
686
-
687
- ##
688
- # Retrieves the number of DSPs within the chain. This includes the
689
- # built-in {FMOD::Effects::Fader} DSP.
690
- # @return [Integer]
691
- def count
692
- buffer = "\0" * Fiddle::SIZEOF_INT
693
- FMOD.invoke(:ChannelGroup_GetNumDSPs, @channel, buffer)
694
- buffer.unpack1('l')
695
- end
696
-
697
- ##
698
- # @overload each(&block)
699
- # If called with a block, passes each DSP in turn before returning self.
700
- # @yield [dsp] Yields a DSP instance to the block.
701
- # @yieldparam dsp [Dsp] The DSP instance.
702
- # @return [self]
703
- # @overload each
704
- # Returns an enumerator for the {DspChain} if no block is given.
705
- # @return [Enumerator]
706
- def each
707
- return to_enum(:each) unless block_given?
708
- (0...count).each { |i| yield self[i] }
709
- self
710
- end
711
-
712
- ##
713
- # Element reference. Returns the element at index.
714
- # @param index [Integer] The index into the {DspChain} to retrieve.
715
- # @return [Dsp|nil] The DSP at the specified index, or +nil+ if index is
716
- # out of range.
717
- def [](index)
718
- return nil unless index.between?(-2, count)
719
- dsp = "\0" * Fiddle::SIZEOF_INTPTR_T
720
- FMOD.invoke(:ChannelGroup_GetDSP, @channel, index, dsp)
721
- Dsp.from_handle(dsp)
722
- end
723
-
724
- ##
725
- # Element assignment. Sets the element at the specified index.
726
- # @param index [Integer] The index into the {DspChain} to set.
727
- # @param dsp [Dsp] A DSP instance.
728
- # @return [Dsp] The given DSP instance.
729
- def []=(index, dsp)
730
- FMOD.type?(dsp, Dsp)
731
- FMOD.invoke(:ChannelGroup_AddDSP, @channel, index, dsp)
732
- dsp
733
- end
734
-
735
- ##
736
- # Appends or pushes the given object(s) on to the end of this {DspChain}. This
737
- # expression returns +self+, so several appends may be chained together.
738
- # @param dsp [Dsp] One or more DSP instance(s).
739
- # @return [self]
740
- def add(*dsp)
741
- dsp.each { |d| self[DspIndex::TAIL] = d }
742
- self
743
- end
744
-
745
- ##
746
- # Prepends objects to the front of +self+, moving other elements upwards.
747
- # @param dsp [Dsp] A DSP instance.
748
- # @return [self]
749
- def unshift(dsp)
750
- self[DspIndex::HEAD] = dsp
751
- self
752
- end
753
-
754
- ##
755
- # Removes the last element from +self+ and returns it, or +nil+ if the
756
- # {DspChain} is empty.
757
- # @return [Dsp|nil]
758
- def pop
759
- dsp = self[DspIndex::TAIL]
760
- remove(dsp)
761
- dsp
762
- end
763
-
764
- ##
765
- # Returns the first element of +self+ and removes it (shifting all other
766
- # elements down by one). Returns +nil+ if the array is empty.
767
- # @return [Dsp|nil]
768
- def shift
769
- dsp = self[DspIndex::HEAD]
770
- remove(dsp)
771
- dsp
772
- end
773
-
774
- ##
775
- # Deletes the specified DSP from this DSP chain. This does not release ot
776
- # dispose the DSP unit, only removes from this {DspChain}, as a DSP unit
777
- # can be shared.
778
- # @param dsp [Dsp] The DSP to remove.
779
- # @return [self]
780
- def remove(dsp)
781
- return unless dsp.is_a?(Dsp)
782
- FMOD.invoke(:ChannelGroup_RemoveDSP, @channel, dsp)
783
- self
784
- end
785
-
786
- ##
787
- # Returns the index of the specified DSP.
788
- # @param dsp [Dsp] The DSP to retrieve the index of.
789
- # @return [Integer] The index of the DSP.
790
- def index(dsp)
791
- FMOD.type?(dsp, Dsp)
792
- buffer = "\0" * Fiddle::SIZEOF_INT
793
- FMOD.invoke(:ChannelGroup_GetDSPIndex, @channel, dsp, buffer)
794
- buffer.unpack1('l')
795
- end
796
-
797
- ##
798
- # Moves a DSP unit that exists in this {DspChain} to a new index.
799
- # @param dsp [Dsp] The DSP instance to move, must exist within this
800
- # {DspChain}.
801
- # @param index [Integer] The new index to place the specified DSP.
802
- # @return [self]
803
- def move(dsp, index)
804
- FMOD.type?(dsp, Dsp)
805
- FMOD.invoke(:ChannelGroup_SetDSPIndex, @channel, dsp, index)
806
- self
807
- end
808
-
809
- alias_method :size, :count
810
- alias_method :length, :count
811
- alias_method :length, :count
812
- alias_method :delete, :remove
813
- alias_method :push, :add
814
- alias_method :<<, :add
815
-
816
- private_class_method :new
817
- end
818
1018
  end
819
1019
  end
820
1020