fmod-ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +41 -0
- data/Gemfile +4 -0
- data/README.md +51 -0
- data/Rakefile +2 -0
- data/fmod-ruby.gemspec +19 -0
- data/lib/fmod.rb +27 -0
- data/lib/fmod/channel.rb +55 -0
- data/lib/fmod/constants.rb +80 -0
- data/lib/fmod/enums.rb +136 -0
- data/lib/fmod/functions.rb +77 -0
- data/lib/fmod/pointer_helper.rb +8 -0
- data/lib/fmod/sound.rb +37 -0
- data/lib/fmod/system.rb +53 -0
- data/lib/fmod/version.rb +3 -0
- data/scratch.rb +49 -0
- metadata +71 -0
data/.gitignore
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
*.gem
|
2
|
+
.bundle
|
3
|
+
Gemfile.lock
|
4
|
+
pkg/*
|
5
|
+
# rcov generated
|
6
|
+
coverage
|
7
|
+
|
8
|
+
# rdoc generated
|
9
|
+
rdoc
|
10
|
+
|
11
|
+
# yard generated
|
12
|
+
doc
|
13
|
+
.yardoc
|
14
|
+
|
15
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
16
|
+
#
|
17
|
+
# * Create a file at ~/.gitignore
|
18
|
+
# * Include files you want ignored
|
19
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
20
|
+
#
|
21
|
+
# After doing this, these files will be ignored in all your git projects,
|
22
|
+
# saving you from having to 'pollute' every project you touch with them
|
23
|
+
#
|
24
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
25
|
+
#
|
26
|
+
# For MacOS:
|
27
|
+
#
|
28
|
+
#.DS_Store
|
29
|
+
#
|
30
|
+
# For TextMate
|
31
|
+
#*.tmproj
|
32
|
+
#tmtags
|
33
|
+
#
|
34
|
+
# For emacs:
|
35
|
+
#*~
|
36
|
+
#\#*
|
37
|
+
#.\#*
|
38
|
+
#
|
39
|
+
# For vim:
|
40
|
+
#*.swp
|
41
|
+
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
<!-- Efficient, realtime audio for Ruby
|
2
|
+
==================================
|
3
|
+
|
4
|
+
Ruby is too slow to do realtime audio, but C is not. The best way to give Ruby robust audio capabilities is to use a native C/C++ library. The primary problem then is which library to choose and how to wire it into Ruby.
|
5
|
+
|
6
|
+
So how do you choose an audio library? Aside from writing one from scratch, there are a number of widely used preexisting C/C++ audio libraries. At the lowest level, there are projects like PortAudio which handle direct interfacing with the hardware only, requiring a programmer to feed it a stream of numbers representing a waveform. At the highest level, projects like CLAM, CSL, FMOD and others provide a full framework complete with voice management, sound file playback, and even synthesis. In these frameworks, the low level number pushing is well abstracted, leaving the programmer with a coarse interface to predefined functionality.
|
7
|
+
|
8
|
+
This Ruby library has chosen a high level framework as a basis for realtime audio. While it certainly is possible to get Ruby to push waveform representations to a low level API like PortAudio, doing so 44100 times a second is not playing to Ruby's strengths. By using a high level library, we trade flexible synthesis for a limited set of fast, efficient audio routines.
|
9
|
+
|
10
|
+
To get Ruby to use external native libraries, there are a few ways to go about it. You can write a C external, use the DL library available in the Ruby standard distribution, or you can use FFI. Having tried all three methods of interfacing with C, FFI is a clear winner. It is efficient, predictable, effortlessly cross platform, and decently well documented.
|
11
|
+
|
12
|
+
Ruby has been sorely lacking an audio framework, and an FMOD wrapper is a great place to start. This library is ultimately meant to be the basis of audio DSLs written in Ruby. -->
|
13
|
+
|
14
|
+
FMOD for Ruby
|
15
|
+
-------------
|
16
|
+
|
17
|
+
*ruby-fmod* wraps the excellent [FMOD](http://www.fmod.org) C/C++ libraries using the equally excellent [FFI](http://github.com/ffi/ffi).
|
18
|
+
|
19
|
+
It is far from finished, but all the basic techniques for interfacing Ruby with the FMOD library are outlined. If you want to contribute to this project, please get in touch.
|
20
|
+
|
21
|
+
FMOD?
|
22
|
+
=====
|
23
|
+
|
24
|
+
"FMOD is a programming library and toolkit for the creation and playback of interactive audio. It supports all leading operating systems and game platforms." And now Ruby too. FMOD supports all sorts of audio file playback, surround sound and multichannel, as well as effects, VST plugins, 3D sound, and wavetable synthesis.
|
25
|
+
|
26
|
+
FMOD is not free, nor is it open source, but it does have a very [liberal license](http://www.fmod.org/index.php/sales). While commercial use is quite expensive, it is free to use in your non-commercial projects.
|
27
|
+
|
28
|
+
Installation
|
29
|
+
============
|
30
|
+
|
31
|
+
To use this Ruby library, you must have the FMOD on you machine. [Go get it](http://www.fmod.org/index.php/download). At the moment, only Mac OS X is supported, but adding Linux or Windows is likely as easy as pointing to the library locations.
|
32
|
+
|
33
|
+
That being said:
|
34
|
+
|
35
|
+
gem install fmod-ruby
|
36
|
+
|
37
|
+
or, in a Gemfile
|
38
|
+
|
39
|
+
gem "fmod-ruby", :require => "fmod"
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
Usage
|
44
|
+
=====
|
45
|
+
|
46
|
+
require "fmod"
|
47
|
+
|
48
|
+
FMOD.init
|
49
|
+
sound = FMOD::Sound.new(file)
|
50
|
+
sound.play
|
51
|
+
|
data/Rakefile
ADDED
data/fmod-ruby.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/fmod/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["ronen barzel"]
|
6
|
+
gem.email = ["ronen@barzel.org"]
|
7
|
+
gem.description = %q{Wrapper for the FMOD audio library}
|
8
|
+
gem.summary = %q{Wrapper for the FMOD audio library}
|
9
|
+
gem.homepage = "https://github.com/ronen/fmod-ruby"
|
10
|
+
|
11
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
gem.files = `git ls-files`.split("\n")
|
13
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
gem.name = "fmod-ruby"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Fmod::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency("ffi")
|
19
|
+
end
|
data/lib/fmod.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
require 'fmod/version'
|
4
|
+
|
5
|
+
require 'fmod/constants'
|
6
|
+
require 'fmod/enums'
|
7
|
+
require 'fmod/functions'
|
8
|
+
|
9
|
+
require 'fmod/system'
|
10
|
+
require 'fmod/sound'
|
11
|
+
require 'fmod/channel'
|
12
|
+
|
13
|
+
module FMOD
|
14
|
+
def self.init
|
15
|
+
@system = System.new
|
16
|
+
end
|
17
|
+
|
18
|
+
# Ruby version of the system
|
19
|
+
def self.system
|
20
|
+
@system
|
21
|
+
end
|
22
|
+
|
23
|
+
# This pointer is used by many of the sound functions
|
24
|
+
def self.system_pointer
|
25
|
+
@system.pointer
|
26
|
+
end
|
27
|
+
end
|
data/lib/fmod/channel.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
module FMOD
|
2
|
+
class Channel
|
3
|
+
include Functions
|
4
|
+
# pointer to the channel instance
|
5
|
+
attr_reader :pointer
|
6
|
+
|
7
|
+
# TODO: Need to find a way to reliably destroy this pointer
|
8
|
+
def initialize(options = {})
|
9
|
+
@system_pointer = FMOD.system.pointer
|
10
|
+
@pointer = FFI::MemoryPointer.new(:pointer)
|
11
|
+
end
|
12
|
+
|
13
|
+
# result = FMOD_Channel_IsPlaying(channel, &playing);
|
14
|
+
def playing?
|
15
|
+
FFI::MemoryPointer.new(:int) do |ptr|
|
16
|
+
error_check FMOD_Channel_IsPlaying(@pointer.read_pointer, ptr)
|
17
|
+
return playing_ptr.read_int == 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def pause
|
22
|
+
error_check FMOD_Channel_SetPaused(@pointer.read_pointer, ((paused?) ? 0 : 1))
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def paused?
|
27
|
+
FFI::MemoryPointer.new(:int) do |ptr|
|
28
|
+
error_check FMOD_Channel_GetPaused(@pointer.read_pointer, ptr)
|
29
|
+
return ptr.read_int == 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_position(int = 0)
|
34
|
+
error_check FMOD_Channel_SetPosition(@pointer.read_pointer, int, FMOD_TIMEUNIT_MS)
|
35
|
+
end
|
36
|
+
|
37
|
+
def pan=(float)
|
38
|
+
float = 1.0 if float > 1.0
|
39
|
+
float = 0.0 if float < 0.0
|
40
|
+
error_check FMOD_Channel_SetPan(@pointer.read_pointer, float)
|
41
|
+
end
|
42
|
+
|
43
|
+
def frequency
|
44
|
+
FFI::MemoryPointer.new(:float) do |ptr|
|
45
|
+
error_check FMOD_Channel_GetFrequency(@pointer.read_pointer, ptr)
|
46
|
+
return ptr.read_float
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def frequency=(float)
|
51
|
+
error_check FMOD_Channel_SetFrequency(@pointer.read_pointer, float)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module FMOD
|
2
|
+
module Constants
|
3
|
+
# FMOD_INITFLAGS
|
4
|
+
FMOD_INIT_NORMAL = 0x00000000
|
5
|
+
FMOD_INIT_STREAM_FROM_UPDATE = 0x00000001
|
6
|
+
FMOD_INIT_3D_RIGHTHANDED = 0x00000002
|
7
|
+
FMOD_INIT_SOFTWARE_DISABLE = 0x00000004
|
8
|
+
FMOD_INIT_SOFTWARE_OCCLUSION = 0x00000008
|
9
|
+
FMOD_INIT_SOFTWARE_HRTF = 0x00000010
|
10
|
+
FMOD_INIT_SOFTWARE_REVERB_LOWMEM = 0x00000040
|
11
|
+
FMOD_INIT_ENABLE_PROFILE = 0x00000020
|
12
|
+
FMOD_INIT_VOL0_BECOMES_VIRTUAL = 0x00000080
|
13
|
+
FMOD_INIT_WASAPI_EXCLUSIVE = 0x00000100
|
14
|
+
FMOD_INIT_DSOUND_HRTFNONE = 0x00000200
|
15
|
+
FMOD_INIT_DSOUND_HRTFLIGHT = 0x00000400
|
16
|
+
FMOD_INIT_DSOUND_HRTFFULL = 0x00000800
|
17
|
+
FMOD_INIT_PS2_DISABLECORE0REVERB = 0x00010000
|
18
|
+
FMOD_INIT_PS2_DISABLECORE1REVERB = 0x00020000
|
19
|
+
FMOD_INIT_PS2_DONTUSESCRATCHPAD = 0x00040000
|
20
|
+
FMOD_INIT_PS2_SWAPDMACHANNELS = 0x00080000
|
21
|
+
FMOD_INIT_PS3_PREFERDTS = 0x00800000
|
22
|
+
FMOD_INIT_PS3_FORCE2CHLPCM = 0x01000000
|
23
|
+
FMOD_INIT_XBOX_REMOVEHEADROOM = 0x00100000
|
24
|
+
FMOD_INIT_SYSTEM_MUSICMUTENOTPAUSE = 0x00200000
|
25
|
+
FMOD_INIT_SYNCMIXERWITHUPDATE = 0x00400000
|
26
|
+
FMOD_INIT_DTS_NEURALSURROUND = 0x02000000
|
27
|
+
FMOD_INIT_GEOMETRY_USECLOSEST = 0x04000000
|
28
|
+
FMOD_INIT_DISABLE_MYEARS = 0x08000000
|
29
|
+
|
30
|
+
# FMOD_MODE
|
31
|
+
FMOD_DEFAULT = 0x00000000
|
32
|
+
FMOD_LOOP_OFF = 0x00000001
|
33
|
+
FMOD_LOOP_NORMAL = 0x00000002
|
34
|
+
FMOD_LOOP_BIDI = 0x00000004
|
35
|
+
FMOD_2D = 0x00000008
|
36
|
+
FMOD_3D = 0x00000010
|
37
|
+
FMOD_HARDWARE = 0x00000020
|
38
|
+
FMOD_SOFTWARE = 0x00000040
|
39
|
+
FMOD_CREATESTREAM = 0x00000080
|
40
|
+
FMOD_CREATESAMPLE = 0x00000100
|
41
|
+
FMOD_CREATECOMPRESSEDSAMPLE = 0x00000200
|
42
|
+
FMOD_OPENUSER = 0x00000400
|
43
|
+
FMOD_OPENMEMORY = 0x00000800
|
44
|
+
FMOD_OPENMEMORY_POINT = 0x10000000
|
45
|
+
FMOD_OPENRAW = 0x00001000
|
46
|
+
FMOD_OPENONLY = 0x00002000
|
47
|
+
FMOD_ACCURATETIME = 0x00004000
|
48
|
+
FMOD_MPEGSEARCH = 0x00008000
|
49
|
+
FMOD_NONBLOCKING = 0x00010000
|
50
|
+
FMOD_UNIQUE = 0x00020000
|
51
|
+
FMOD_3D_HEADRELATIVE = 0x00040000
|
52
|
+
FMOD_3D_WORLDRELATIVE = 0x00080000
|
53
|
+
FMOD_3D_LOGROLLOFF = 0x00100000
|
54
|
+
FMOD_3D_LINEARROLLOFF = 0x00200000
|
55
|
+
FMOD_3D_CUSTOMROLLOFF = 0x04000000
|
56
|
+
FMOD_3D_IGNOREGEOMETRY = 0x40000000
|
57
|
+
FMOD_CDDA_FORCEASPI = 0x00400000
|
58
|
+
FMOD_CDDA_JITTERCORRECT = 0x00800000
|
59
|
+
FMOD_UNICODE = 0x01000000
|
60
|
+
FMOD_IGNORETAGS = 0x02000000
|
61
|
+
FMOD_LOWMEM = 0x08000000
|
62
|
+
FMOD_LOADSECONDARYRAM = 0x20000000
|
63
|
+
FMOD_VIRTUAL_PLAYFROMSTART = 0x80000000
|
64
|
+
|
65
|
+
# FMOD_TIMEUNIT
|
66
|
+
FMOD_TIMEUNIT_MS = 0x00000001
|
67
|
+
FMOD_TIMEUNIT_PCM = 0x00000002
|
68
|
+
FMOD_TIMEUNIT_PCMBYTES = 0x00000004
|
69
|
+
FMOD_TIMEUNIT_RAWBYTES = 0x00000008
|
70
|
+
FMOD_TIMEUNIT_MODORDER = 0x00000100
|
71
|
+
FMOD_TIMEUNIT_MODROW = 0x00000200
|
72
|
+
FMOD_TIMEUNIT_MODPATTERN = 0x00000400
|
73
|
+
FMOD_TIMEUNIT_SENTENCE_MS = 0x00010000
|
74
|
+
FMOD_TIMEUNIT_SENTENCE_PCM = 0x00020000
|
75
|
+
FMOD_TIMEUNIT_SENTENCE_PCMBYTES = 0x00040000
|
76
|
+
FMOD_TIMEUNIT_SENTENCE = 0x00080000
|
77
|
+
FMOD_TIMEUNIT_SENTENCE_SUBSOUND = 0x00100000
|
78
|
+
FMOD_TIMEUNIT_BUFFERED = 0x10000000
|
79
|
+
end
|
80
|
+
end
|
data/lib/fmod/enums.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module FMOD
|
2
|
+
module Enums
|
3
|
+
extend FFI::Library
|
4
|
+
|
5
|
+
FMOD_CHANNELINDEX = enum(
|
6
|
+
:FMOD_CHANNEL_FREE,
|
7
|
+
:FMOD_CHANNEL_REUSE
|
8
|
+
)
|
9
|
+
|
10
|
+
FMOD_RESULT = enum(
|
11
|
+
:FMOD_OK,
|
12
|
+
:FMOD_ERR_ALREADYLOCKED,
|
13
|
+
:FMOD_ERR_BADCOMMAND,
|
14
|
+
:FMOD_ERR_CDDA_DRIVERS,
|
15
|
+
:FMOD_ERR_CDDA_INIT,
|
16
|
+
:FMOD_ERR_CDDA_INVALID_DEVICE,
|
17
|
+
:FMOD_ERR_CDDA_NOAUDIO,
|
18
|
+
:FMOD_ERR_CDDA_NODEVICES,
|
19
|
+
:FMOD_ERR_CDDA_NODISC,
|
20
|
+
:FMOD_ERR_CDDA_READ,
|
21
|
+
:FMOD_ERR_CHANNEL_ALLOC,
|
22
|
+
:FMOD_ERR_CHANNEL_STOLEN,
|
23
|
+
:FMOD_ERR_COM,
|
24
|
+
:FMOD_ERR_DMA,
|
25
|
+
:FMOD_ERR_DSP_CONNECTION,
|
26
|
+
:FMOD_ERR_DSP_FORMAT,
|
27
|
+
:FMOD_ERR_DSP_NOTFOUND,
|
28
|
+
:FMOD_ERR_DSP_RUNNING,
|
29
|
+
:FMOD_ERR_DSP_TOOMANYCONNECTIONS,
|
30
|
+
:FMOD_ERR_FILE_BAD,
|
31
|
+
:FMOD_ERR_FILE_COULDNOTSEEK,
|
32
|
+
:FMOD_ERR_FILE_DISKEJECTED,
|
33
|
+
:FMOD_ERR_FILE_EOF,
|
34
|
+
:FMOD_ERR_FILE_NOTFOUND,
|
35
|
+
:FMOD_ERR_FILE_UNWANTED,
|
36
|
+
:FMOD_ERR_FORMAT,
|
37
|
+
:FMOD_ERR_HTTP,
|
38
|
+
:FMOD_ERR_HTTP_ACCESS,
|
39
|
+
:FMOD_ERR_HTTP_PROXY_AUTH,
|
40
|
+
:FMOD_ERR_HTTP_SERVER_ERROR,
|
41
|
+
:FMOD_ERR_HTTP_TIMEOUT,
|
42
|
+
:FMOD_ERR_INITIALIZATION,
|
43
|
+
:FMOD_ERR_INITIALIZED,
|
44
|
+
:FMOD_ERR_INTERNAL,
|
45
|
+
:FMOD_ERR_INVALID_ADDRESS,
|
46
|
+
:FMOD_ERR_INVALID_FLOAT,
|
47
|
+
:FMOD_ERR_INVALID_HANDLE,
|
48
|
+
:FMOD_ERR_INVALID_PARAM,
|
49
|
+
:FMOD_ERR_INVALID_POSITION,
|
50
|
+
:FMOD_ERR_INVALID_SPEAKER,
|
51
|
+
:FMOD_ERR_INVALID_SYNCPOINT,
|
52
|
+
:FMOD_ERR_INVALID_VECTOR,
|
53
|
+
:FMOD_ERR_IRX,
|
54
|
+
:FMOD_ERR_MAXAUDIBLE,
|
55
|
+
:FMOD_ERR_MEMORY,
|
56
|
+
:FMOD_ERR_MEMORY_CANTPOINT,
|
57
|
+
:FMOD_ERR_MEMORY_IOP,
|
58
|
+
:FMOD_ERR_MEMORY_SRAM,
|
59
|
+
:FMOD_ERR_NEEDS2D,
|
60
|
+
:FMOD_ERR_NEEDS3D,
|
61
|
+
:FMOD_ERR_NEEDSHARDWARE,
|
62
|
+
:FMOD_ERR_NEEDSSOFTWARE,
|
63
|
+
:FMOD_ERR_NET_CONNECT,
|
64
|
+
:FMOD_ERR_NET_SOCKET_ERROR,
|
65
|
+
:FMOD_ERR_NET_URL,
|
66
|
+
:FMOD_ERR_NET_WOULD_BLOCK,
|
67
|
+
:FMOD_ERR_NOTREADY,
|
68
|
+
:FMOD_ERR_OUTPUT_ALLOCATED,
|
69
|
+
:FMOD_ERR_OUTPUT_CREATEBUFFER,
|
70
|
+
:FMOD_ERR_OUTPUT_DRIVERCALL,
|
71
|
+
:FMOD_ERR_OUTPUT_ENUMERATION,
|
72
|
+
:FMOD_ERR_OUTPUT_FORMAT,
|
73
|
+
:FMOD_ERR_OUTPUT_INIT,
|
74
|
+
:FMOD_ERR_OUTPUT_NOHARDWARE,
|
75
|
+
:FMOD_ERR_OUTPUT_NOSOFTWARE,
|
76
|
+
:FMOD_ERR_PAN,
|
77
|
+
:FMOD_ERR_PLUGIN,
|
78
|
+
:FMOD_ERR_PLUGIN_INSTANCES,
|
79
|
+
:FMOD_ERR_PLUGIN_MISSING,
|
80
|
+
:FMOD_ERR_PLUGIN_RESOURCE,
|
81
|
+
:FMOD_ERR_PRELOADED,
|
82
|
+
:FMOD_ERR_PROGRAMMERSOUND,
|
83
|
+
:FMOD_ERR_RECORD,
|
84
|
+
:FMOD_ERR_REVERB_INSTANCE,
|
85
|
+
:FMOD_ERR_SUBSOUND_ALLOCATED,
|
86
|
+
:FMOD_ERR_SUBSOUND_CANTMOVE,
|
87
|
+
:FMOD_ERR_SUBSOUND_MODE,
|
88
|
+
:FMOD_ERR_SUBSOUNDS,
|
89
|
+
:FMOD_ERR_TAGNOTFOUND,
|
90
|
+
:FMOD_ERR_TOOMANYCHANNELS,
|
91
|
+
:FMOD_ERR_UNIMPLEMENTED,
|
92
|
+
:FMOD_ERR_UNINITIALIZED,
|
93
|
+
:FMOD_ERR_UNSUPPORTED,
|
94
|
+
:FMOD_ERR_UPDATE,
|
95
|
+
:FMOD_ERR_VERSION,
|
96
|
+
:FMOD_ERR_EVENT_FAILED,
|
97
|
+
:FMOD_ERR_EVENT_INFOONLY,
|
98
|
+
:FMOD_ERR_EVENT_INTERNAL,
|
99
|
+
:FMOD_ERR_EVENT_MAXSTREAMS,
|
100
|
+
:FMOD_ERR_EVENT_MISMATCH,
|
101
|
+
:FMOD_ERR_EVENT_NAMECONFLICT,
|
102
|
+
:FMOD_ERR_EVENT_NOTFOUND,
|
103
|
+
:FMOD_ERR_EVENT_NEEDSSIMPLE,
|
104
|
+
:FMOD_ERR_EVENT_GUIDCONFLICT,
|
105
|
+
:FMOD_ERR_EVENT_ALREADY_LOADED,
|
106
|
+
:FMOD_ERR_MUSIC_UNINITIALIZED,
|
107
|
+
:FMOD_ERR_MUSIC_NOTFOUND,
|
108
|
+
:FMOD_ERR_MUSIC_NOCALLBACK
|
109
|
+
)
|
110
|
+
|
111
|
+
FMOD_DSP_TYPE = enum(
|
112
|
+
:FMOD_DSP_TYPE_UNKNOWN,
|
113
|
+
:FMOD_DSP_TYPE_MIXER,
|
114
|
+
:FMOD_DSP_TYPE_OSCILLATOR,
|
115
|
+
:FMOD_DSP_TYPE_LOWPASS,
|
116
|
+
:FMOD_DSP_TYPE_ITLOWPASS,
|
117
|
+
:FMOD_DSP_TYPE_HIGHPASS,
|
118
|
+
:FMOD_DSP_TYPE_ECHO,
|
119
|
+
:FMOD_DSP_TYPE_FLANGE,
|
120
|
+
:FMOD_DSP_TYPE_DISTORTION,
|
121
|
+
:FMOD_DSP_TYPE_NORMALIZE,
|
122
|
+
:FMOD_DSP_TYPE_PARAMEQ,
|
123
|
+
:FMOD_DSP_TYPE_PITCHSHIFT,
|
124
|
+
:FMOD_DSP_TYPE_CHORUS,
|
125
|
+
:FMOD_DSP_TYPE_REVERB,
|
126
|
+
:FMOD_DSP_TYPE_VSTPLUGIN,
|
127
|
+
:FMOD_DSP_TYPE_WINAMPPLUGIN,
|
128
|
+
:FMOD_DSP_TYPE_ITECHO,
|
129
|
+
:FMOD_DSP_TYPE_COMPRESSOR,
|
130
|
+
:FMOD_DSP_TYPE_SFXREVERB,
|
131
|
+
:FMOD_DSP_TYPE_LOWPASS_SIMPLE,
|
132
|
+
:FMOD_DSP_TYPE_DELAY,
|
133
|
+
:FMOD_DSP_TYPE_TREMOLO
|
134
|
+
)
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module FMOD
|
2
|
+
module Functions
|
3
|
+
extend FFI::Library
|
4
|
+
include Constants
|
5
|
+
include Enums
|
6
|
+
|
7
|
+
ffi_lib 'libfmodex'
|
8
|
+
|
9
|
+
typedef :int, :FMOD_BOOL
|
10
|
+
typedef :uint, :FMOD_TIMEUNIT
|
11
|
+
typedef :uint, :FMOD_MODE
|
12
|
+
typedef :uint, :FMOD_INITFLAGS
|
13
|
+
typedef :uint, :FMOD_CAPS
|
14
|
+
typedef :uint, :FMOD_DEBUGLEVEL
|
15
|
+
typedef :uint, :FMOD_MEMORY_TYPE
|
16
|
+
|
17
|
+
# typedef struct FMOD_SYSTEM FMOD_SYSTEM;
|
18
|
+
# typedef struct FMOD_SOUND FMOD_SOUND;
|
19
|
+
# typedef struct FMOD_CHANNEL FMOD_CHANNEL;
|
20
|
+
# typedef struct FMOD_CHANNELGROUP FMOD_CHANNELGROUP;
|
21
|
+
# typedef struct FMOD_SOUNDGROUP FMOD_SOUNDGROUP;
|
22
|
+
# typedef struct FMOD_REVERB FMOD_REVERB;
|
23
|
+
# typedef struct FMOD_DSP FMOD_DSP;
|
24
|
+
# typedef struct FMOD_DSPCONNECTION FMOD_DSPCONNECTION;
|
25
|
+
# typedef struct FMOD_POLYGON FMOD_POLYGON;
|
26
|
+
# typedef struct FMOD_GEOMETRY FMOD_GEOMETRY;
|
27
|
+
# typedef struct FMOD_SYNCPOINT FMOD_SYNCPOINT;
|
28
|
+
|
29
|
+
|
30
|
+
# SYSTEM FUNCTIONS
|
31
|
+
attach_function :FMOD_System_Create, [:pointer], FMOD_RESULT
|
32
|
+
attach_function :FMOD_System_GetVersion, [:pointer, :pointer], FMOD_RESULT
|
33
|
+
attach_function :FMOD_System_Init, [:pointer, :int, :int, :pointer], FMOD_RESULT
|
34
|
+
|
35
|
+
attach_function :FMOD_System_CreateSound, [:pointer, :string, :int, :int, :pointer], FMOD_RESULT
|
36
|
+
attach_function :FMOD_System_CreateStream, [:pointer, :string, :int, :int, :pointer], FMOD_RESULT
|
37
|
+
attach_function :FMOD_System_PlaySound, [:pointer, :int, :pointer, :int, :pointer], FMOD_RESULT
|
38
|
+
|
39
|
+
# FMOD_RESULT FMOD_System_GetDriverInfo(FMOD_SYSTEM * system, int id, char * name, int namelen, FMOD_GUID * guid);
|
40
|
+
# attach_function :FMOD_System_GetDriverInfo
|
41
|
+
|
42
|
+
# FMOD_RESULT FMOD_System_GetNumDrivers(FMOD_SYSTEM * system, int * numdrivers);
|
43
|
+
attach_function :FMOD_System_GetNumDrivers, [:pointer, :pointer], FMOD_RESULT
|
44
|
+
|
45
|
+
# FMOD_RESULT FMOD_System_GetHardwareChannels(FMOD_SYSTEM * system, int * num2d, int * num3d, int * total);
|
46
|
+
attach_function :FMOD_System_GetHardwareChannels, [:pointer, :pointer, :pointer, :pointer], FMOD_RESULT
|
47
|
+
|
48
|
+
# FMOD_RESULT FMOD_System_GetSoftwareChannels(FMOD_SYSTEM * system, int * numsoftwarechannels);
|
49
|
+
attach_function :FMOD_System_GetSoftwareChannels, [:pointer, :pointer], FMOD_RESULT
|
50
|
+
|
51
|
+
# FMOD_RESULT FMOD_Channel_IsPlaying(FMOD_CHANNEL * channel, FMOD_BOOL * isplaying);
|
52
|
+
attach_function :FMOD_Channel_IsPlaying, [:pointer, :pointer], FMOD_RESULT
|
53
|
+
|
54
|
+
# FMOD_RESULT FMOD_Channel_SetPaused(FMOD_CHANNEL * channel, FMOD_BOOL paused);
|
55
|
+
attach_function :FMOD_Channel_SetPaused, [:pointer, :int], FMOD_RESULT
|
56
|
+
|
57
|
+
# FMOD_RESULT FMOD_Channel_GetPaused(FMOD_CHANNEL * channel, FMOD_BOOL * paused);
|
58
|
+
attach_function :FMOD_Channel_GetPaused, [:pointer, :pointer], FMOD_RESULT
|
59
|
+
|
60
|
+
# FMOD_RESULT FMOD_Channel_SetPosition(FMOD_CHANNEL * channel, unsigned int position, FMOD_TIMEUNIT postype);
|
61
|
+
attach_function :FMOD_Channel_SetPosition, [:pointer, :int, :FMOD_TIMEUNIT], FMOD_RESULT
|
62
|
+
|
63
|
+
# FMOD_RESULT FMOD_Channel_SetPan(FMOD_CHANNEL * channel, float pan);
|
64
|
+
attach_function :FMOD_Channel_SetPan, [:pointer, :float], FMOD_RESULT
|
65
|
+
|
66
|
+
# FMOD_RESULT FMOD_Channel_GetFrequency(FMOD_CHANNEL * channel, float * frequency);
|
67
|
+
attach_function :FMOD_Channel_GetFrequency, [:pointer, :pointer], FMOD_RESULT
|
68
|
+
|
69
|
+
# FMOD_RESULT FMOD_Channel_SetFrequency(FMOD_CHANNEL * channel, float frequency);
|
70
|
+
attach_function :FMOD_Channel_SetFrequency, [:pointer, :float], FMOD_RESULT
|
71
|
+
|
72
|
+
|
73
|
+
def error_check(result)
|
74
|
+
raise "FMOD error! #{result}" if result != :FMOD_OK
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/lib/fmod/sound.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module FMOD
|
2
|
+
class Sound
|
3
|
+
include Functions
|
4
|
+
attr_reader :channel
|
5
|
+
|
6
|
+
def initialize(file, options = {})
|
7
|
+
@system_pointer = FMOD.system.pointer
|
8
|
+
@channel = options[:channel] || Channel.new
|
9
|
+
@file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def play
|
13
|
+
play_stream
|
14
|
+
end
|
15
|
+
|
16
|
+
def play_sound
|
17
|
+
sound_ptr = FFI::MemoryPointer.new(:pointer)
|
18
|
+
# FMOD_RESULT = FMOD_System_CreateStream(system, "wave.mp3", FMOD_DEFAULT, 0, &sound);
|
19
|
+
error_check FMOD_System_CreateStream(@system_pointer.read_pointer, @file, FMOD_DEFAULT, 0, sound_ptr);
|
20
|
+
|
21
|
+
# FMOD_RESULT = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound1, 0, &channel);
|
22
|
+
error_check FMOD_System_PlaySound(@system_pointer.read_pointer, FMOD_CHANNELINDEX[:FMOD_CHANNEL_FREE], sound_ptr.read_pointer, 0, @channel.pointer);
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def play_stream
|
27
|
+
sound_ptr = FFI::MemoryPointer.new(:pointer)
|
28
|
+
# FMOD_RESULT = FMOD_System_CreateSound(system, "drumloop.wav", FMOD_SOFTWARE, 0, &sound);
|
29
|
+
error_check FMOD_System_CreateSound(@system_pointer.read_pointer, @file, FMOD_DEFAULT, 0, sound_ptr);
|
30
|
+
|
31
|
+
# FMOD_RESULT = FMOD_System_PlaySound(system, FMOD_CHANNEL_FREE, sound1, 0, &channel);
|
32
|
+
error_check FMOD_System_PlaySound(@system_pointer.read_pointer, FMOD_CHANNELINDEX[:FMOD_CHANNEL_FREE], sound_ptr.read_pointer, 0, @channel.pointer);
|
33
|
+
true
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/fmod/system.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module FMOD
|
2
|
+
class System
|
3
|
+
include Functions
|
4
|
+
# pointer to the system instance
|
5
|
+
attr_reader :pointer
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
# FMOD_SYSTEM *system;
|
9
|
+
# result = FMOD_System_Create(&system);
|
10
|
+
# result = FMOD_System_Init(system, 32, FMOD_INIT_NORMAL, NULL);
|
11
|
+
@pointer = FFI::MemoryPointer.new(:pointer)
|
12
|
+
error_check FMOD_System_Create(@pointer)
|
13
|
+
error_check FMOD_System_Init(@pointer.read_pointer, 32, FMOD_INIT_NORMAL, nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def version
|
17
|
+
# unsigned int version;
|
18
|
+
# result = FMOD_System_GetVersion(system, &version);
|
19
|
+
FFI::MemoryPointer.new(:int) do |version_ptr|
|
20
|
+
error_check FMOD_System_GetVersion(@pointer.read_pointer, version_ptr);
|
21
|
+
return version_ptr.read_int
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def driver_count
|
27
|
+
# unsigned int numdrivers;
|
28
|
+
# result = FMOD_System_GetNumDrivers(system, &numdrivers);
|
29
|
+
count_ptr = FFI::MemoryPointer.new(:int)
|
30
|
+
error_check FMOD_System_GetNumDrivers(@pointer.read_pointer, count_ptr)
|
31
|
+
count_ptr.read_int
|
32
|
+
end
|
33
|
+
|
34
|
+
def software_channels
|
35
|
+
num_ptr = FFI::MemoryPointer.new(:int)
|
36
|
+
error_check FMOD_System_GetSoftwareChannels(@pointer.read_pointer, num_ptr)
|
37
|
+
num_ptr.read_int
|
38
|
+
end
|
39
|
+
|
40
|
+
def hardware_channels
|
41
|
+
num2d = FFI::MemoryPointer.new(:int)
|
42
|
+
num3d = FFI::MemoryPointer.new(:int)
|
43
|
+
total = FFI::MemoryPointer.new(:int)
|
44
|
+
error_check FMOD_System_GetHardwareChannels(@pointer.read_pointer, num2d, num3d, total)
|
45
|
+
|
46
|
+
{
|
47
|
+
:num2d => num2d.read_int,
|
48
|
+
:num3d => num3d.read_int,
|
49
|
+
:total => total.read_int,
|
50
|
+
}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/fmod/version.rb
ADDED
data/scratch.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'lib/fmod'
|
2
|
+
|
3
|
+
start_time = Time.now
|
4
|
+
puts "initializing FMOD ..."
|
5
|
+
FMOD.init
|
6
|
+
end_time = Time.new - start_time
|
7
|
+
puts "done in #{end_time} seconds."
|
8
|
+
|
9
|
+
file = (ARGV.empty?) ? "Kids.mp3" : ARGV[0]
|
10
|
+
|
11
|
+
|
12
|
+
puts "initializing a sound ..."
|
13
|
+
start_time = Time.now
|
14
|
+
sound = FMOD::Sound.new(file)
|
15
|
+
end_time = Time.new - start_time
|
16
|
+
puts "done in #{end_time} seconds."
|
17
|
+
sound.play
|
18
|
+
puts FMOD.system.version
|
19
|
+
puts sound.channel.frequency
|
20
|
+
sleep 2
|
21
|
+
# sound.channel.frequency = 11050.0
|
22
|
+
# puts sound.channel.frequency
|
23
|
+
# 10.times do |i|
|
24
|
+
# sound.channel.set_position(i + 1000)
|
25
|
+
# sleep 0.1
|
26
|
+
# end
|
27
|
+
|
28
|
+
# sleep 2
|
29
|
+
|
30
|
+
1000.times do |i|
|
31
|
+
sound.channel.set_position(i * (rand*1000).to_i)
|
32
|
+
sleep rand
|
33
|
+
end
|
34
|
+
#
|
35
|
+
# sr = 100
|
36
|
+
# step = 1.0/sr
|
37
|
+
# time = 0.0
|
38
|
+
#
|
39
|
+
# loop do
|
40
|
+
# time += step
|
41
|
+
# val = Math.cos(time * 2 * Math::PI * 440.0) * Math.cos(time * 2 * Math::PI)
|
42
|
+
# sound.channel.frequency = val * 20000
|
43
|
+
# sleep step
|
44
|
+
# end
|
45
|
+
|
46
|
+
# block
|
47
|
+
while true
|
48
|
+
sleep 5
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fmod-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- ronen barzel
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-11-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ffi
|
16
|
+
requirement: &70253800274800 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70253800274800
|
25
|
+
description: Wrapper for the FMOD audio library
|
26
|
+
email:
|
27
|
+
- ronen@barzel.org
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- Gemfile
|
34
|
+
- README.md
|
35
|
+
- Rakefile
|
36
|
+
- fmod-ruby.gemspec
|
37
|
+
- lib/fmod.rb
|
38
|
+
- lib/fmod/channel.rb
|
39
|
+
- lib/fmod/constants.rb
|
40
|
+
- lib/fmod/enums.rb
|
41
|
+
- lib/fmod/functions.rb
|
42
|
+
- lib/fmod/pointer_helper.rb
|
43
|
+
- lib/fmod/sound.rb
|
44
|
+
- lib/fmod/system.rb
|
45
|
+
- lib/fmod/version.rb
|
46
|
+
- scratch.rb
|
47
|
+
homepage: https://github.com/ronen/fmod-ruby
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.10
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Wrapper for the FMOD audio library
|
71
|
+
test_files: []
|