plaything 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/plaything.rb +39 -10
- data/lib/plaything/objects/source.rb +14 -0
- data/lib/plaything/openal.rb +7 -13
- data/lib/plaything/version.rb +1 -1
- data/spec/plaything/source_spec.rb +56 -0
- data/spec/plaything_spec.rb +10 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bf2e22e8a9aef3aa57e957acc4cab274b624131b
|
4
|
+
data.tar.gz: 19ccc9e6262d3b0fea35c91823b2caa830265077
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f187e04c89a299894e1cc498c9f5d8090a3ec4095cff8c02d1eeb27ab7ef8d3d1161d51482ce23cc75ecc40591e8c85c775e1fe3004bc2705f6f0d8c39da0ae5
|
7
|
+
data.tar.gz: 2ae6ed0336140daf95b323413b69ebb833fabbb95fb16626b89d6ea7912ac3656839abef6fbc8dbcb578aaa92f7857644ca8ca1bcc62579774dcc4e85f26c4ed
|
data/lib/plaything.rb
CHANGED
@@ -14,7 +14,7 @@ require "plaything/openal"
|
|
14
14
|
# - {#play}, {#pause}, {#stop} — controls source playback state. If the source
|
15
15
|
# runs out of audio to play, it will forcefully stop playback.
|
16
16
|
# - {#position}, can be used to retrieve playback position.
|
17
|
-
# - {#queue_size}, {#drops} — status information; should be used by the streaming
|
17
|
+
# - {#queue_size}, {#drops}, {#starved?} — status information; should be used by the streaming
|
18
18
|
# source to improve playback experience.
|
19
19
|
# - {#format=} — allows you to change format, even during playback.
|
20
20
|
# - {#stream}, {#<<} — fills the audio buffers with PCM audio.
|
@@ -55,7 +55,7 @@ class Plaything
|
|
55
55
|
@queued_buffers = []
|
56
56
|
@queued_frames = []
|
57
57
|
|
58
|
-
@
|
58
|
+
@starved = false
|
59
59
|
@total_buffers_processed = 0
|
60
60
|
|
61
61
|
@monitor = Monitor.new
|
@@ -70,7 +70,10 @@ class Plaything
|
|
70
70
|
#
|
71
71
|
# @note You must continue to supply audio, or playback will cease.
|
72
72
|
def play
|
73
|
-
synchronize
|
73
|
+
synchronize do
|
74
|
+
@starved = false
|
75
|
+
@source.play
|
76
|
+
end
|
74
77
|
end
|
75
78
|
|
76
79
|
# Pause playback of queued audio. Playback will resume from current position when {#play} is called.
|
@@ -107,13 +110,31 @@ class Plaything
|
|
107
110
|
end
|
108
111
|
end
|
109
112
|
|
110
|
-
#
|
113
|
+
# If audio is starved, and it has not been previously seen as starved, it
|
114
|
+
# will return 1. However, if audio is starved and {#drops} has already
|
115
|
+
# reported it as starved, it will return 0. Finally, if audio is not starved,
|
116
|
+
# it always returns 0.
|
117
|
+
#
|
118
|
+
# @return [Integer] number of drops since previous call to {#drops}.
|
111
119
|
def drops
|
112
|
-
|
113
|
-
|
120
|
+
if starved?
|
121
|
+
if @starved_toggle
|
122
|
+
0
|
123
|
+
else
|
124
|
+
@starved_toggle = true
|
125
|
+
1
|
126
|
+
end
|
127
|
+
else
|
128
|
+
@starved_toggle = false
|
129
|
+
0
|
114
130
|
end
|
115
131
|
end
|
116
132
|
|
133
|
+
# @return [Boolean] true if audio stream has starved
|
134
|
+
def starved?
|
135
|
+
synchronize { @starved or @source.starved? }
|
136
|
+
end
|
137
|
+
|
117
138
|
# @return [Hash] current audio format in the queues
|
118
139
|
def format
|
119
140
|
synchronize do
|
@@ -137,8 +158,8 @@ class Plaything
|
|
137
158
|
def format=(format)
|
138
159
|
synchronize do
|
139
160
|
if @source.playing?
|
140
|
-
stop
|
141
|
-
@
|
161
|
+
stop # clear audio buffers
|
162
|
+
@starved = true
|
142
163
|
end
|
143
164
|
|
144
165
|
@sample_type = format.fetch(:sample_type)
|
@@ -179,8 +200,8 @@ class Plaything
|
|
179
200
|
# @return [Integer] number of frames consumed (consumed_samples / channels), a multiple of channels
|
180
201
|
def stream(frames, frame_format)
|
181
202
|
synchronize do
|
182
|
-
if
|
183
|
-
FFI::MemoryPointer.new(OpenAL::Buffer,
|
203
|
+
if buffers_processed > 0
|
204
|
+
FFI::MemoryPointer.new(OpenAL::Buffer, buffers_processed) do |ptr|
|
184
205
|
OpenAL.source_unqueue_buffers(@source, ptr.count, ptr)
|
185
206
|
@total_buffers_processed += ptr.count
|
186
207
|
@free_buffers.concat OpenAL::Buffer.extract(ptr, ptr.count)
|
@@ -218,6 +239,14 @@ class Plaything
|
|
218
239
|
|
219
240
|
protected
|
220
241
|
|
242
|
+
def buffers_processed
|
243
|
+
if @source.playing?
|
244
|
+
@source.buffers_processed
|
245
|
+
else
|
246
|
+
@source.sample_offset.div(@buffer_length)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
221
250
|
def synchronize
|
222
251
|
@monitor.synchronize { return yield }
|
223
252
|
end
|
@@ -5,19 +5,33 @@ class Plaything
|
|
5
5
|
|
6
6
|
# Start playback.
|
7
7
|
def play
|
8
|
+
@should_be_playing = true
|
8
9
|
OpenAL.source_play(self)
|
9
10
|
end
|
10
11
|
|
11
12
|
# Pause playback.
|
12
13
|
def pause
|
14
|
+
@should_be_playing = false
|
13
15
|
OpenAL.source_pause(self)
|
14
16
|
end
|
15
17
|
|
16
18
|
# Stop playback and rewind the source.
|
17
19
|
def stop
|
20
|
+
@should_be_playing = false
|
18
21
|
OpenAL.source_stop(self)
|
19
22
|
end
|
20
23
|
|
24
|
+
# @return [Boolean] true if audio should be playing (#play has been called,
|
25
|
+
# but not #stop or #pause), but isn’t playing
|
26
|
+
def starved?
|
27
|
+
should_be_playing? and not playing?
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Boolean] true if source should currently be playing audio
|
31
|
+
def should_be_playing?
|
32
|
+
@should_be_playing
|
33
|
+
end
|
34
|
+
|
21
35
|
# @return [Integer] how many samples (/ channels) that have been played from the queued buffers
|
22
36
|
def sample_offset
|
23
37
|
get(:sample_offset, Integer)
|
data/lib/plaything/openal.rb
CHANGED
@@ -20,7 +20,8 @@ class Plaything
|
|
20
20
|
:invalid_operation, 0xA004,
|
21
21
|
:out_of_memory, 0xA005,
|
22
22
|
]
|
23
|
-
attach_function :
|
23
|
+
attach_function :alGetError, [ ], :error
|
24
|
+
attach_function :alcGetError, [ ], :error
|
24
25
|
|
25
26
|
# Overridden for three purposes.
|
26
27
|
#
|
@@ -35,14 +36,15 @@ class Plaything
|
|
35
36
|
.gsub(/(?<!\A)\p{Lu}/u, '_\0')
|
36
37
|
.downcase
|
37
38
|
bang_name = "#{ruby_name}!"
|
39
|
+
error_method = :"#{c_name.to_s[/\Aalc?/, 0]}GetError"
|
38
40
|
|
39
41
|
super(ruby_name, c_name, params, returns, options)
|
40
42
|
alias_method(bang_name, ruby_name)
|
41
43
|
|
42
44
|
define_method(ruby_name) do |*args, &block|
|
43
|
-
|
45
|
+
public_send(error_method) # clear error
|
44
46
|
public_send(bang_name, *args, &block).tap do
|
45
|
-
error =
|
47
|
+
error = public_send(error_method) # clear error
|
46
48
|
unless error == :no_error
|
47
49
|
raise Error, "#{ruby_name} failed with #{error}"
|
48
50
|
end
|
@@ -122,8 +124,8 @@ class Plaything
|
|
122
124
|
:source_type, 0x1027,
|
123
125
|
|
124
126
|
:frequency, 0x2001,
|
125
|
-
:bits, 0x2002,
|
126
|
-
:channels, 0x2003,
|
127
|
+
# :bits, 0x2002,
|
128
|
+
# :channels, 0x2003,
|
127
129
|
:size, 0x2004,
|
128
130
|
:unused, 0x2010,
|
129
131
|
:pending, 0x2011,
|
@@ -141,14 +143,6 @@ class Plaything
|
|
141
143
|
## Utility
|
142
144
|
attach_function :alGetEnumValue, [ :string ], :int
|
143
145
|
|
144
|
-
enum_type(:parameter).to_h.each do |name, value|
|
145
|
-
real_name = "AL_#{name.to_s.upcase}"
|
146
|
-
real_value = get_enum_value(real_name)
|
147
|
-
if real_value != -1 && value != real_value
|
148
|
-
raise NameError, "#{name} has value #{value}, should be #{real_value}"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
146
|
## Listeners
|
153
147
|
attach_function :alListenerf, [ :parameter, :float ], :void
|
154
148
|
|
data/lib/plaything/version.rb
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
describe Plaything::OpenAL::Source do
|
2
|
+
subject(:source) { Plaything::OpenAL::Source.new(1337) }
|
3
|
+
|
4
|
+
describe "#starved?" do
|
5
|
+
it "returns true if source should be playing but isnt" do
|
6
|
+
Plaything::OpenAL.should_receive(:source_play).with(source)
|
7
|
+
source.should_receive(:playing?).and_return(false)
|
8
|
+
|
9
|
+
source.play
|
10
|
+
|
11
|
+
source.should be_starved
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns false if source should be playing and is" do
|
15
|
+
Plaything::OpenAL.should_receive(:source_play).with(source)
|
16
|
+
source.should_receive(:playing?).and_return(true)
|
17
|
+
|
18
|
+
source.play
|
19
|
+
|
20
|
+
source.should_not be_starved
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns false if source should not be playing and isnt" do
|
24
|
+
source.should_not be_starved
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#playing?" do
|
29
|
+
it "returns true when playing" do
|
30
|
+
source.should_receive(:state).and_return(:playing)
|
31
|
+
source.should be_playing
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns false when not playing" do
|
35
|
+
source.should_receive(:state).and_return(:stopped)
|
36
|
+
source.should_not be_playing
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#stopped?" do
|
41
|
+
it "returns true when stopped" do
|
42
|
+
source.should_receive(:state).and_return(:stopped)
|
43
|
+
source.should be_stopped
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns false when not stopped" do
|
47
|
+
source.should_receive(:state).and_return(:paused)
|
48
|
+
source.should_not be_stopped
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns false when not stopped" do
|
52
|
+
source.should_receive(:state).and_return(:playing)
|
53
|
+
source.should_not be_stopped
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/spec/plaything_spec.rb
CHANGED
@@ -2,4 +2,14 @@ describe "Plaything" do
|
|
2
2
|
specify "VERSION is defined" do
|
3
3
|
defined?(Plaything::VERSION).should eq "constant"
|
4
4
|
end
|
5
|
+
|
6
|
+
describe "parameter enum" do
|
7
|
+
Plaything::OpenAL.enum_type(:parameter).to_h.each do |name, value|
|
8
|
+
specify(name) do
|
9
|
+
real_name = "AL_#{name.to_s.upcase}"
|
10
|
+
real_value = Plaything::OpenAL.get_enum_value(real_name)
|
11
|
+
value.should eq real_value # value will be -1 if it does not exist
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
5
15
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plaything
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kim Burgestrand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/plaything/support/type_class.rb
|
79
79
|
- lib/plaything/version.rb
|
80
80
|
- plaything.gemspec
|
81
|
+
- spec/plaything/source_spec.rb
|
81
82
|
- spec/plaything_spec.rb
|
82
83
|
- spec/spec_helper.rb
|
83
84
|
homepage: https://github.com/Burgestrand/plaything
|
@@ -105,5 +106,6 @@ signing_key:
|
|
105
106
|
specification_version: 4
|
106
107
|
summary: Blast raw PCM audio through your speakers using OpenAL.
|
107
108
|
test_files:
|
109
|
+
- spec/plaything/source_spec.rb
|
108
110
|
- spec/plaything_spec.rb
|
109
111
|
- spec/spec_helper.rb
|