plaything 1.1.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|