ruby-alsa 0.0.5 → 0.7
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.
- data/Manifest.txt +18 -0
- data/debian/changelog +11 -0
- data/debian/compat +1 -0
- data/debian/control +18 -0
- data/debian/rules +15 -0
- data/lib/alsa.rb +3 -1
- data/lib/alsa/ffi_ext.rb +35 -0
- data/lib/alsa/native.rb +5 -0
- data/lib/alsa/pcm/capture.rb +39 -3
- data/lib/alsa/pcm/hw_parameters.rb +89 -0
- data/lib/alsa/pcm/native.rb +23 -3
- data/lib/alsa/pcm/playback.rb +50 -3
- data/lib/alsa/pcm/stream.rb +43 -1
- data/lib/alsa/pcm/sw_parameters.rb +53 -0
- data/lib/alsa/sine.rb +21 -0
- data/log/test.log +217 -0
- data/refs/alsa_player +0 -0
- data/refs/alsa_player.c +80 -0
- data/refs/alsa_player.rb +85 -0
- data/refs/alsa_player_async +0 -0
- data/refs/alsa_player_async.c +113 -0
- data/refs/alsa_player_async.rb +98 -0
- data/refs/alsa_recorder.rb +85 -0
- data/refs/alsa_recorder_async.rb +98 -0
- data/refs/pcm_wrap.rb +552 -0
- data/ruby-alsa.gemspec +8 -8
- data/script/play +9 -2
- data/script/record +15 -4
- data/setup.rb +1585 -0
- data/spec/alsa/pcm/native_spec.rb +2 -2
- data/spec/alsa/pcm/stream_spec.rb +4 -4
- data/tasks/debian.rake +19 -0
- metadata +35 -7
data/Manifest.txt
CHANGED
@@ -6,7 +6,12 @@ History.txt
|
|
6
6
|
Manifest.txt
|
7
7
|
README.rdoc
|
8
8
|
Rakefile
|
9
|
+
debian/changelog
|
10
|
+
debian/compat
|
11
|
+
debian/control
|
12
|
+
debian/rules
|
9
13
|
lib/alsa.rb
|
14
|
+
lib/alsa/ffi_ext.rb
|
10
15
|
lib/alsa/logger.rb
|
11
16
|
lib/alsa/native.rb
|
12
17
|
lib/alsa/pcm/capture.rb
|
@@ -14,13 +19,25 @@ lib/alsa/pcm/hw_parameters.rb
|
|
14
19
|
lib/alsa/pcm/native.rb
|
15
20
|
lib/alsa/pcm/playback.rb
|
16
21
|
lib/alsa/pcm/stream.rb
|
22
|
+
lib/alsa/pcm/sw_parameters.rb
|
23
|
+
lib/alsa/sine.rb
|
17
24
|
log/test.log
|
25
|
+
refs/alsa_player
|
26
|
+
refs/alsa_player.c
|
27
|
+
refs/alsa_player.rb
|
28
|
+
refs/alsa_player_async
|
29
|
+
refs/alsa_player_async.c
|
30
|
+
refs/alsa_player_async.rb
|
31
|
+
refs/alsa_recorder.rb
|
32
|
+
refs/alsa_recorder_async.rb
|
33
|
+
refs/pcm_wrap.rb
|
18
34
|
ruby-alsa.gemspec
|
19
35
|
script/console
|
20
36
|
script/destroy
|
21
37
|
script/generate
|
22
38
|
script/play
|
23
39
|
script/record
|
40
|
+
setup.rb
|
24
41
|
spec.html
|
25
42
|
spec/alsa/logger_spec.rb
|
26
43
|
spec/alsa/native_spec.rb
|
@@ -34,4 +51,5 @@ spec/spec.opts
|
|
34
51
|
spec/spec_helper.rb
|
35
52
|
spec/support/logger.rb
|
36
53
|
tasks/buildbot.rake
|
54
|
+
tasks/debian.rake
|
37
55
|
tasks/rspec.rake
|
data/debian/changelog
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
libalsa-ruby (0.7-1) unstable; urgency=low
|
2
|
+
|
3
|
+
* New upstream release
|
4
|
+
|
5
|
+
-- Alban Peignier <alban@tryphon.eu> Thu, 14 Oct 2010 10:09:54 +0200
|
6
|
+
|
7
|
+
libalsa-ruby (0.1-1) unstable; urgency=low
|
8
|
+
|
9
|
+
* Initial release
|
10
|
+
|
11
|
+
-- Alban Peignier <alban@tryphon.eu> Sun, 1 Aug 2010 17:57:43 +0200
|
data/debian/compat
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
5
|
data/debian/control
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Source: libalsa-ruby
|
2
|
+
Section: sound
|
3
|
+
Priority: optional
|
4
|
+
Maintainer: Alban Peignier <alban@tryphon.eu>
|
5
|
+
Build-Depends: debhelper, cdbs, ruby-pkg-tools, libsetup-ruby1.8
|
6
|
+
Build-Depends-Indep: ruby1.8
|
7
|
+
Standards-Version: 3.8.1
|
8
|
+
Homepage: http://projects.tryphon.eu/ruby-alsa
|
9
|
+
|
10
|
+
Package: libalsa-ruby1.8
|
11
|
+
Architecture: all
|
12
|
+
Depends: ruby1.8, libruby1.8, libasound2, libffi-ruby
|
13
|
+
Description: Ruby 1.8 binding for ALSA library.
|
14
|
+
|
15
|
+
Package: libalsa-ruby
|
16
|
+
Architecture: all
|
17
|
+
Depends: libalsa-ruby1.8
|
18
|
+
Description: Ruby binding for ALSA library.
|
data/debian/rules
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/make -f
|
2
|
+
|
3
|
+
include /usr/share/cdbs/1/rules/debhelper.mk
|
4
|
+
include /usr/share/ruby-pkg-tools/1/class/ruby-setup-rb.mk
|
5
|
+
|
6
|
+
install/libalsa-ruby::
|
7
|
+
# cp $(DEB_SRCDIR)/debian/alsa-backup.conf debian/$(cdbs_curpkg)/etc/
|
8
|
+
echo DEB_RUBY_LIB_PACKAGES
|
9
|
+
echo $(DEB_RUBY_LIB_PACKAGES)
|
10
|
+
echo DEB_RUBY_REAL_LIB_PACKAGES
|
11
|
+
echo $(DEB_RUBY_REAL_LIB_PACKAGES)
|
12
|
+
echo DEB_RUBY_DUMMY_LIB_PACKAGES
|
13
|
+
echo $(DEB_RUBY_DUMMY_LIB_PACKAGES)
|
14
|
+
echo DEB_RUBY_LIB_DOC_PACKAGES
|
15
|
+
echo $(DEB_RUBY_LIB_DOC_PACKAGES)
|
data/lib/alsa.rb
CHANGED
@@ -5,15 +5,17 @@ require 'ffi'
|
|
5
5
|
|
6
6
|
module ALSA
|
7
7
|
|
8
|
-
VERSION = "0.
|
8
|
+
VERSION = "0.7"
|
9
9
|
|
10
10
|
end
|
11
11
|
|
12
12
|
require 'logger'
|
13
|
+
require 'alsa/ffi_ext'
|
13
14
|
require 'alsa/logger'
|
14
15
|
require 'alsa/native'
|
15
16
|
require 'alsa/pcm/native'
|
16
17
|
require 'alsa/pcm/hw_parameters'
|
18
|
+
require 'alsa/pcm/sw_parameters'
|
17
19
|
require 'alsa/pcm/stream'
|
18
20
|
require 'alsa/pcm/capture'
|
19
21
|
require 'alsa/pcm/playback'
|
data/lib/alsa/ffi_ext.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class Integer
|
2
|
+
|
3
|
+
def to_pointer
|
4
|
+
pointer = MemoryPointer.new(:int)
|
5
|
+
pointer.write_int(self)
|
6
|
+
|
7
|
+
unless block_given?
|
8
|
+
pointer
|
9
|
+
else
|
10
|
+
begin
|
11
|
+
return yield pointer
|
12
|
+
ensure
|
13
|
+
pointer.free
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class Array
|
21
|
+
|
22
|
+
def to_pointers
|
23
|
+
pointers = map(&:to_pointer)
|
24
|
+
unless block_given?
|
25
|
+
pointers
|
26
|
+
else
|
27
|
+
begin
|
28
|
+
return yield pointers
|
29
|
+
ensure
|
30
|
+
pointers.each(&:free)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/alsa/native.rb
CHANGED
@@ -8,5 +8,10 @@ module ALSA
|
|
8
8
|
def self.error_code?(response)
|
9
9
|
response and response < 0
|
10
10
|
end
|
11
|
+
|
12
|
+
callback :async_callback, [:pointer], :void
|
13
|
+
attach_function :async_add_pcm_handler, :snd_async_add_pcm_handler, [ :pointer, :pointer, :async_callback, :pointer ], :int
|
14
|
+
attach_function :async_handler_get_pcm, :snd_async_handler_get_pcm, [ :pointer ], :pointer
|
15
|
+
attach_function :async_handler_get_callback_private, :snd_async_handler_get_callback_private, [ :pointer ], :pointer
|
11
16
|
end
|
12
17
|
end
|
data/lib/alsa/pcm/capture.rb
CHANGED
@@ -2,15 +2,14 @@ module ALSA::PCM
|
|
2
2
|
class Capture < Stream
|
3
3
|
|
4
4
|
def native_constant
|
5
|
-
ALSA::PCM::Native::
|
5
|
+
ALSA::PCM::Native::Stream::CAPTURE
|
6
6
|
end
|
7
7
|
|
8
8
|
def read
|
9
9
|
check_handle!
|
10
10
|
|
11
|
-
ALSA.logger.debug { "start read with #{hw_params.
|
11
|
+
ALSA.logger.debug { "start read with #{hw_params.inspect}"}
|
12
12
|
|
13
|
-
ALSA.logger.debug { "allocate #{hw_params.buffer_size_for(buffer_frame_count)} bytes for #{buffer_frame_count} frames" }
|
14
13
|
FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(buffer_frame_count)) do |buffer|
|
15
14
|
begin
|
16
15
|
read_buffer buffer, buffer_frame_count
|
@@ -18,6 +17,41 @@ module ALSA::PCM
|
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
20
|
+
def read_in_background(&block)
|
21
|
+
check_handle!
|
22
|
+
|
23
|
+
async_handler = FFI::MemoryPointer.new(:pointer)
|
24
|
+
buffer = FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(buffer_frame_count))
|
25
|
+
|
26
|
+
started = false
|
27
|
+
|
28
|
+
capture_callback = Proc.new do |async_handler|
|
29
|
+
if started
|
30
|
+
frame_to_read = buffer_frame_count
|
31
|
+
read_buffer buffer, frame_to_read
|
32
|
+
yield buffer, frame_to_read
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
ALSA::try_to "add pcm handler" do
|
37
|
+
ALSA::Native::async_add_pcm_handler(async_handler, handle, capture_callback, nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
ALSA::try_to "start capture" do
|
41
|
+
ALSA::PCM::Native::start(handle)
|
42
|
+
end
|
43
|
+
|
44
|
+
hole_frame_count = ALSA::try_to "read available space" do
|
45
|
+
ALSA::PCM::Native::avail_update(self.handle)
|
46
|
+
end
|
47
|
+
ALSA.logger.debug { "read synchronously #{hole_frame_count} frames"}
|
48
|
+
FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(hole_frame_count)) do |hole|
|
49
|
+
ALSA::PCM::Native::readi self.handle, hole, hole_frame_count
|
50
|
+
end
|
51
|
+
|
52
|
+
started = true
|
53
|
+
end
|
54
|
+
|
21
55
|
def read_buffer(buffer, frame_count)
|
22
56
|
check_handle!
|
23
57
|
|
@@ -31,6 +65,8 @@ module ALSA::PCM
|
|
31
65
|
end
|
32
66
|
end
|
33
67
|
|
68
|
+
ALSA.logger.debug { "read frame count: #{read_count}/#{frame_count}"}
|
69
|
+
|
34
70
|
missing_frame_count = frame_count - read_count
|
35
71
|
if missing_frame_count > 0
|
36
72
|
ALSA.logger.debug { "re-read missing frame count: #{missing_frame_count}"}
|
@@ -59,10 +59,62 @@ module ALSA::PCM
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
def period_time=(period_time)
|
63
|
+
ALSA::try_to "set period time (#{period_time})" do
|
64
|
+
value = FFI::MemoryPointer.new(:int)
|
65
|
+
value.write_int(period_time)
|
66
|
+
|
67
|
+
dir = FFI::MemoryPointer.new(:int)
|
68
|
+
dir.write_int(-1)
|
69
|
+
error_code = ALSA::PCM::Native::hw_params_set_period_time_near self.device.handle, self.handle, value, dir
|
70
|
+
|
71
|
+
value.free
|
72
|
+
dir.free
|
73
|
+
|
74
|
+
error_code
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def period_time
|
79
|
+
value = nil
|
80
|
+
ALSA::try_to "get period time" do
|
81
|
+
value_pointer = FFI::MemoryPointer.new(:int)
|
82
|
+
dir_pointer = FFI::MemoryPointer.new(:int)
|
83
|
+
dir_pointer.write_int(0)
|
84
|
+
|
85
|
+
error_code = ALSA::PCM::Native::hw_params_get_period_time self.handle, value_pointer, dir_pointer
|
86
|
+
|
87
|
+
value = value_pointer.read_int
|
88
|
+
|
89
|
+
value_pointer.free
|
90
|
+
dir_pointer.free
|
91
|
+
|
92
|
+
error_code
|
93
|
+
end
|
94
|
+
value
|
95
|
+
end
|
96
|
+
|
97
|
+
def buffer_time=(buffer_time)
|
98
|
+
ALSA::try_to "set buffer time (#{buffer_time})" do
|
99
|
+
value = FFI::MemoryPointer.new(:int)
|
100
|
+
value.write_int(buffer_time)
|
101
|
+
|
102
|
+
dir = FFI::MemoryPointer.new(:int)
|
103
|
+
dir.write_int(-1)
|
104
|
+
error_code = ALSA::PCM::Native::hw_params_set_buffer_time_near self.device.handle, self.handle, value, dir
|
105
|
+
|
106
|
+
value.free
|
107
|
+
dir.free
|
108
|
+
|
109
|
+
error_code
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
62
113
|
def sample_rate
|
63
114
|
rate = nil
|
64
115
|
ALSA::try_to "get sample rate" do
|
65
116
|
rate_pointer = FFI::MemoryPointer.new(:int)
|
117
|
+
|
66
118
|
dir_pointer = FFI::MemoryPointer.new(:int)
|
67
119
|
dir_pointer.write_int(0)
|
68
120
|
|
@@ -106,6 +158,39 @@ module ALSA::PCM
|
|
106
158
|
channels
|
107
159
|
end
|
108
160
|
|
161
|
+
def period_size
|
162
|
+
value = nil
|
163
|
+
ALSA::try_to "get period size" do
|
164
|
+
value_pointer = FFI::MemoryPointer.new(:int)
|
165
|
+
dir_pointer = FFI::MemoryPointer.new(:int)
|
166
|
+
dir_pointer.write_int(0)
|
167
|
+
|
168
|
+
error_code = ALSA::PCM::Native::hw_params_get_period_size self.handle, value_pointer, dir_pointer
|
169
|
+
|
170
|
+
value = value_pointer.read_int
|
171
|
+
|
172
|
+
value_pointer.free
|
173
|
+
dir_pointer.free
|
174
|
+
|
175
|
+
error_code
|
176
|
+
end
|
177
|
+
value
|
178
|
+
end
|
179
|
+
|
180
|
+
def buffer_size
|
181
|
+
value = nil
|
182
|
+
ALSA::try_to "get buffer size" do
|
183
|
+
value_pointer = FFI::MemoryPointer.new(:int)
|
184
|
+
error_code = ALSA::PCM::Native::hw_params_get_buffer_size self.handle, value_pointer
|
185
|
+
value = value_pointer.read_int
|
186
|
+
|
187
|
+
value_pointer.free
|
188
|
+
|
189
|
+
error_code
|
190
|
+
end
|
191
|
+
value
|
192
|
+
end
|
193
|
+
|
109
194
|
def buffer_size_for(frame_count)
|
110
195
|
ALSA::PCM::Native::format_size(self.sample_format, frame_count) * self.channels
|
111
196
|
end
|
@@ -120,5 +205,9 @@ module ALSA::PCM
|
|
120
205
|
end
|
121
206
|
end
|
122
207
|
|
208
|
+
def inspect
|
209
|
+
"#<ALSA::PCM::HwParameters:#{object_id} sample_rate=#{sample_rate}, channels=#{channels}, period_time=#{period_time}, period_size=#{period_size}, buffer_size=#{buffer_size}>"
|
210
|
+
end
|
211
|
+
|
123
212
|
end
|
124
213
|
end
|
data/lib/alsa/pcm/native.rb
CHANGED
@@ -4,14 +4,19 @@ module ALSA::PCM
|
|
4
4
|
extend FFI::Library
|
5
5
|
ffi_lib "libasound.so.2"
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
module Stream
|
8
|
+
PLAYBACK = 0
|
9
|
+
CAPTURE = 1
|
10
|
+
end
|
9
11
|
|
10
12
|
BLOCK = 0
|
11
13
|
attach_function :open, :snd_pcm_open, [:pointer, :string, :int, :int], :int
|
12
14
|
attach_function :prepare, :snd_pcm_prepare, [ :pointer ], :int
|
13
15
|
attach_function :close, :snd_pcm_close, [:pointer], :int
|
14
16
|
|
17
|
+
attach_function :wait, :snd_pcm_wait, [:pointer, :int], :int
|
18
|
+
attach_function :avail_update, :snd_pcm_avail_update, [:pointer], :int
|
19
|
+
|
15
20
|
attach_function :readi, :snd_pcm_readi, [ :pointer, :pointer, :ulong ], :long
|
16
21
|
attach_function :writei, :snd_pcm_writei, [ :pointer, :pointer, :ulong ], :long
|
17
22
|
|
@@ -43,10 +48,25 @@ module ALSA::PCM
|
|
43
48
|
attach_function :hw_params_get_rate, :snd_pcm_hw_params_get_rate, [ :pointer, :pointer, :pointer ], :int
|
44
49
|
attach_function :hw_params_set_rate_near, :snd_pcm_hw_params_set_rate_near, [ :pointer, :pointer, :pointer, :pointer ], :int
|
45
50
|
attach_function :hw_params_set_channels, :snd_pcm_hw_params_set_channels, [ :pointer, :pointer, :uint ], :int
|
46
|
-
attach_function :hw_params_get_channels, :
|
51
|
+
attach_function :hw_params_get_channels, :snd_pcm_hw_params_get_channels, [ :pointer, :pointer ], :int
|
47
52
|
attach_function :hw_params_set_periods, :snd_pcm_hw_params_set_periods, [ :pointer, :pointer, :uint, :int ], :int
|
53
|
+
attach_function :hw_params_set_period_time_near, :snd_pcm_hw_params_set_period_time_near, [ :pointer, :pointer, :pointer, :pointer ], :int
|
54
|
+
attach_function :hw_params_get_period_time, :snd_pcm_hw_params_get_period_time, [ :pointer, :pointer, :pointer ], :int
|
55
|
+
attach_function :hw_params_get_period_size, :snd_pcm_hw_params_get_period_size, [ :pointer, :pointer, :pointer ], :int
|
56
|
+
attach_function :hw_params_get_buffer_size, :snd_pcm_hw_params_get_buffer_size, [ :pointer, :pointer ], :int
|
57
|
+
attach_function :hw_params_set_buffer_time_near, :snd_pcm_hw_params_set_buffer_time_near, [ :pointer, :pointer, :pointer, :pointer ], :int
|
58
|
+
|
59
|
+
attach_function :sw_params, :snd_pcm_sw_params, [:pointer, :pointer], :int
|
60
|
+
attach_function :sw_params_malloc, :snd_pcm_sw_params_malloc, [:pointer], :int
|
61
|
+
attach_function :sw_params_free, :snd_pcm_sw_params_free, [:pointer], :int
|
62
|
+
attach_function :sw_params_current, :snd_pcm_sw_params_current, [ :pointer, :pointer ], :int
|
63
|
+
attach_function :sw_params_set_avail_min, :snd_pcm_sw_params_set_avail_min, [ :pointer, :pointer, :uint ], :int
|
64
|
+
attach_function :sw_params_get_avail_min, :snd_pcm_sw_params_get_avail_min, [ :pointer, :pointer ], :int
|
48
65
|
|
49
66
|
attach_function :format_size, :snd_pcm_format_size, [ :int, :uint ], :int
|
50
67
|
attach_function :bytes_to_frames, :snd_pcm_bytes_to_frames, [ :pointer, :int ], :int
|
68
|
+
|
69
|
+
attach_function :start, :snd_pcm_start, [ :pointer ], :int
|
70
|
+
|
51
71
|
end
|
52
72
|
end
|
data/lib/alsa/pcm/playback.rb
CHANGED
@@ -2,7 +2,7 @@ module ALSA::PCM
|
|
2
2
|
class Playback < Stream
|
3
3
|
|
4
4
|
def native_constant
|
5
|
-
ALSA::PCM::Native::
|
5
|
+
ALSA::PCM::Native::Stream::PLAYBACK
|
6
6
|
end
|
7
7
|
|
8
8
|
def write_buffer(buffer, frame_count)
|
@@ -11,28 +11,75 @@ module ALSA::PCM
|
|
11
11
|
write_count = ALSA::try_to "write in audio interface" do
|
12
12
|
response = ALSA::PCM::Native::writei(self.handle, buffer, frame_count)
|
13
13
|
if ALSA::Native::error_code?(response)
|
14
|
-
ALSA.logger.warn { "try to recover '#{ALSA::Native::strerror(response)}' on
|
14
|
+
ALSA.logger.warn { "try to recover '#{ALSA::Native::strerror(response)}' on write"}
|
15
15
|
ALSA::PCM::Native::pcm_recover(self.handle, response, 1)
|
16
16
|
else
|
17
17
|
response
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
ALSA.logger.debug { "write frame count: #{write_count}/#{frame_count}"}
|
22
|
+
|
21
23
|
missing_frame_count = frame_count - write_count
|
22
24
|
if missing_frame_count > 0
|
23
25
|
ALSA.logger.debug { "missing wroted frame count: #{missing_frame_count}"}
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
29
|
+
def write_in_background(&block)
|
30
|
+
check_handle!
|
31
|
+
|
32
|
+
async_handler = FFI::MemoryPointer.new(:pointer)
|
33
|
+
buffer = FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(buffer_frame_count))
|
34
|
+
|
35
|
+
started = false
|
36
|
+
|
37
|
+
playback_callback = Proc.new do |async_handler|
|
38
|
+
if started
|
39
|
+
audio_content = yield(buffer.size)
|
40
|
+
buffer.write_string audio_content
|
41
|
+
|
42
|
+
read_frame_count =
|
43
|
+
if audio_content.size == buffer.size
|
44
|
+
buffer_frame_count
|
45
|
+
else
|
46
|
+
hw_params.frame_count_for(audio_content.size)
|
47
|
+
end
|
48
|
+
|
49
|
+
write_buffer buffer, read_frame_count
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
ALSA::try_to "add pcm handler" do
|
54
|
+
ALSA::Native::async_add_pcm_handler(async_handler, handle, playback_callback, nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
ALSA::try_to "start playback" do
|
58
|
+
ALSA::PCM::Native::start(handle)
|
59
|
+
end
|
60
|
+
|
61
|
+
silent_frame_count = ALSA::try_to "read available space" do
|
62
|
+
ALSA::PCM::Native::avail_update(self.handle)
|
63
|
+
end
|
64
|
+
ALSA.logger.debug { "write synchronously a silence of #{silent_frame_count} frames"}
|
65
|
+
FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(silent_frame_count)) do |silent|
|
66
|
+
ALSA::PCM::Native::writei self.handle, silent, silent_frame_count
|
67
|
+
end
|
68
|
+
|
69
|
+
started = true
|
70
|
+
end
|
71
|
+
|
27
72
|
def write
|
28
73
|
check_handle!
|
29
74
|
|
75
|
+
ALSA.logger.debug { "start write with #{hw_params.inspect}" }
|
76
|
+
|
30
77
|
FFI::MemoryPointer.new(:char, hw_params.buffer_size_for(buffer_frame_count)) do |buffer|
|
31
78
|
while audio_content = yield(buffer.size)
|
32
79
|
buffer.write_string audio_content
|
33
80
|
|
34
81
|
read_frame_count =
|
35
|
-
if audio_content.size == buffer.size
|
82
|
+
if audio_content.size == buffer.size
|
36
83
|
buffer_frame_count
|
37
84
|
else
|
38
85
|
hw_params.frame_count_for(audio_content.size)
|