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 +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
- data/CONTRIBUTING.md +92 -0
- data/HISTORY.txt +23 -0
- data/PULL_REQUEST_TEMPLATE.md +17 -0
- data/README.md +23 -22
- data/fmod.gemspec +2 -30
- data/lib/fmod.rb +4 -1
- data/lib/fmod/channel.rb +3 -0
- data/lib/fmod/channel_control.rb +511 -311
- data/lib/fmod/channel_group.rb +67 -3
- data/lib/fmod/core.rb +43 -34
- data/lib/fmod/core/mode.rb +138 -0
- data/lib/fmod/core/result.rb +284 -0
- data/lib/fmod/core/sound_format.rb +8 -0
- data/lib/fmod/core/sound_type.rb +1 -0
- data/lib/fmod/core/speaker_index.rb +39 -0
- data/lib/fmod/core/speaker_mode.rb +38 -0
- data/lib/fmod/core/structure.rb +28 -1
- data/lib/fmod/system.rb +2 -2
- data/lib/fmod/version.rb +1 -1
- metadata +13 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d2902236224e5d663766bcc5b5fb7c48147aa20
|
4
|
+
data.tar.gz: a8b3106722a1da66d22ec30902a24bedaacec0ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/CONTRIBUTING.md
ADDED
@@ -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/
|
data/HISTORY.txt
ADDED
@@ -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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
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)
|
data/fmod.gemspec
CHANGED
@@ -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 "
|
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
|
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'
|
data/lib/fmod.rb
CHANGED
@@ -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
|
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)
|
data/lib/fmod/channel.rb
CHANGED
data/lib/fmod/channel_control.rb
CHANGED
@@ -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
|
-
#
|
180
|
-
# to
|
181
|
-
#
|
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
|
-
# @
|
416
|
-
#
|
417
|
-
|
418
|
-
|
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
|
|