ruby-alsa 0.0.3 → 0.0.4
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/.autotest +7 -0
- data/COPYING +674 -0
- data/COPYRIGHT +14 -0
- data/Manifest.txt +24 -0
- data/Rakefile +6 -0
- data/lib/alsa.rb +3 -2
- data/lib/alsa/logger.rb +12 -0
- data/lib/alsa/native.rb +12 -0
- data/lib/alsa/pcm/capture.rb +46 -0
- data/lib/alsa/pcm/hw_parameters.rb +124 -0
- data/lib/alsa/pcm/native.rb +52 -0
- data/lib/alsa/pcm/playback.rb +48 -0
- data/lib/alsa/pcm/stream.rb +76 -0
- data/log/test.log +2948 -0
- data/ruby-alsa.gemspec +39 -0
- data/script/console +2 -2
- data/script/play +20 -0
- data/script/record +13 -0
- data/spec.html +244 -0
- data/spec/alsa/logger_spec.rb +9 -0
- data/spec/alsa/native_spec.rb +30 -0
- data/spec/alsa/pcm/capture_spec.rb +102 -0
- data/spec/alsa/pcm/native_spec.rb +9 -0
- data/spec/alsa/pcm/playback_spec.rb +31 -0
- data/spec/alsa/pcm/stream_spec.rb +17 -0
- data/spec/alsa_spec.rb +23 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/logger.rb +6 -0
- data/tasks/buildbot.rake +1 -0
- metadata +27 -3
data/ruby-alsa.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{ruby-alsa}
|
5
|
+
s.version = "0.0.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Alban Peignier"]
|
9
|
+
s.date = %q{2010-04-25}
|
10
|
+
s.description = %q{FIX (describe your package)}
|
11
|
+
s.email = ["alban@tryphon.eu"]
|
12
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
|
13
|
+
s.files = ["Gemfile", "History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "lib/alsa.rb", "script/console", "script/destroy", "script/generate", "spec/alsa/pcm_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/rspec.rake"]
|
14
|
+
s.homepage = %q{http://projects.tryphon.eu/ruby-alsa}
|
15
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{ruby-alsa}
|
18
|
+
s.rubygems_version = %q{1.3.6}
|
19
|
+
s.summary = %q{FIX (describe your package)}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
s.add_runtime_dependency(%q<ffi>, [">= 0.6.3"])
|
27
|
+
s.add_development_dependency(%q<rubyforge>, [">= 2.0.4"])
|
28
|
+
s.add_development_dependency(%q<hoe>, [">= 2.6.0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<ffi>, [">= 0.6.3"])
|
31
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
32
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
33
|
+
end
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<ffi>, [">= 0.6.3"])
|
36
|
+
s.add_dependency(%q<rubyforge>, [">= 2.0.4"])
|
37
|
+
s.add_dependency(%q<hoe>, [">= 2.6.0"])
|
38
|
+
end
|
39
|
+
end
|
data/script/console
CHANGED
@@ -5,6 +5,6 @@ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
|
5
5
|
libs = " -r irb/completion"
|
6
6
|
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
7
|
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
-
libs << " -r #{File.dirname(__FILE__) + '/../lib/
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/alsa.rb'}"
|
9
9
|
puts "Loading ruby-alsa gem"
|
10
|
-
exec "#{irb} #{libs} --simple-prompt"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/play
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Play a raw audio content
|
4
|
+
#
|
5
|
+
# you can create a compatible raw file with sox :
|
6
|
+
# sox /path/to/audio.file -t raw -c 2 -r 44100 -e signed-integer -b 16 audiocontent.raw
|
7
|
+
#
|
8
|
+
# script/play < audiocontent.raw
|
9
|
+
|
10
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
11
|
+
require "#{File.dirname(__FILE__)}/../lib/alsa"
|
12
|
+
|
13
|
+
include ALSA::PCM
|
14
|
+
ALSA.logger.level = Logger::DEBUG
|
15
|
+
|
16
|
+
Playback.open do |playback|
|
17
|
+
playback.write do |length|
|
18
|
+
$stdin.read(length)
|
19
|
+
end
|
20
|
+
end
|
data/script/record
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
4
|
+
require "#{File.dirname(__FILE__)}/../lib/alsa"
|
5
|
+
|
6
|
+
include ALSA::PCM
|
7
|
+
ALSA.logger.level = Logger::DEBUG
|
8
|
+
|
9
|
+
Capture.open do |capture|
|
10
|
+
capture.read do |buffer, frame_count|
|
11
|
+
$stdout.write buffer
|
12
|
+
end
|
13
|
+
end
|
data/spec.html
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
+
<head>
|
7
|
+
<title>RSpec results</title>
|
8
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
9
|
+
<meta http-equiv="Expires" content="-1" />
|
10
|
+
<meta http-equiv="Pragma" content="no-cache" />
|
11
|
+
<style type="text/css">
|
12
|
+
body {
|
13
|
+
margin: 0;
|
14
|
+
padding: 0;
|
15
|
+
background: #fff;
|
16
|
+
font-size: 80%;
|
17
|
+
}
|
18
|
+
</style>
|
19
|
+
<script type="text/javascript">
|
20
|
+
// <![CDATA[
|
21
|
+
function moveProgressBar(percentDone) {
|
22
|
+
document.getElementById("rspec-header").style.width = percentDone +"%";
|
23
|
+
}
|
24
|
+
function makeRed(element_id) {
|
25
|
+
document.getElementById(element_id).style.background = '#C40D0D';
|
26
|
+
document.getElementById(element_id).style.color = '#FFFFFF';
|
27
|
+
}
|
28
|
+
|
29
|
+
function makeYellow(element_id) {
|
30
|
+
if (element_id == "rspec-header" && document.getElementById(element_id).style.background != '#C40D0D')
|
31
|
+
{
|
32
|
+
document.getElementById(element_id).style.background = '#FAF834';
|
33
|
+
document.getElementById(element_id).style.color = '#000000';
|
34
|
+
}
|
35
|
+
else
|
36
|
+
{
|
37
|
+
document.getElementById(element_id).style.background = '#FAF834';
|
38
|
+
document.getElementById(element_id).style.color = '#000000';
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
// ]]>
|
43
|
+
</script>
|
44
|
+
<style type="text/css">
|
45
|
+
#rspec-header {
|
46
|
+
background: #65C400; color: #fff; height: 4em;
|
47
|
+
}
|
48
|
+
|
49
|
+
.rspec-report h1 {
|
50
|
+
margin: 0px 10px 0px 10px;
|
51
|
+
padding: 10px;
|
52
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
53
|
+
font-size: 1.8em;
|
54
|
+
position: absolute;
|
55
|
+
}
|
56
|
+
|
57
|
+
#summary {
|
58
|
+
margin: 0; padding: 5px 10px;
|
59
|
+
font-family: "Lucida Grande", Helvetica, sans-serif;
|
60
|
+
text-align: right;
|
61
|
+
top: 0px;
|
62
|
+
right: 0px;
|
63
|
+
float:right;
|
64
|
+
}
|
65
|
+
|
66
|
+
#summary p {
|
67
|
+
margin: 0 0 0 2px;
|
68
|
+
}
|
69
|
+
|
70
|
+
#summary #totals {
|
71
|
+
font-size: 1.2em;
|
72
|
+
}
|
73
|
+
|
74
|
+
.example_group {
|
75
|
+
margin: 0 10px 5px;
|
76
|
+
background: #fff;
|
77
|
+
}
|
78
|
+
|
79
|
+
dl {
|
80
|
+
margin: 0; padding: 0 0 5px;
|
81
|
+
font: normal 11px "Lucida Grande", Helvetica, sans-serif;
|
82
|
+
}
|
83
|
+
|
84
|
+
dt {
|
85
|
+
padding: 3px;
|
86
|
+
background: #65C400;
|
87
|
+
color: #fff;
|
88
|
+
font-weight: bold;
|
89
|
+
}
|
90
|
+
|
91
|
+
dd {
|
92
|
+
margin: 5px 0 5px 5px;
|
93
|
+
padding: 3px 3px 3px 18px;
|
94
|
+
}
|
95
|
+
|
96
|
+
dd.spec.passed {
|
97
|
+
border-left: 5px solid #65C400;
|
98
|
+
border-bottom: 1px solid #65C400;
|
99
|
+
background: #DBFFB4; color: #3D7700;
|
100
|
+
}
|
101
|
+
|
102
|
+
dd.spec.failed {
|
103
|
+
border-left: 5px solid #C20000;
|
104
|
+
border-bottom: 1px solid #C20000;
|
105
|
+
color: #C20000; background: #FFFBD3;
|
106
|
+
}
|
107
|
+
|
108
|
+
dd.spec.not_implemented {
|
109
|
+
border-left: 5px solid #FAF834;
|
110
|
+
border-bottom: 1px solid #FAF834;
|
111
|
+
background: #FCFB98; color: #131313;
|
112
|
+
}
|
113
|
+
|
114
|
+
dd.spec.pending_fixed {
|
115
|
+
border-left: 5px solid #0000C2;
|
116
|
+
border-bottom: 1px solid #0000C2;
|
117
|
+
color: #0000C2; background: #D3FBFF;
|
118
|
+
}
|
119
|
+
|
120
|
+
.backtrace {
|
121
|
+
color: #000;
|
122
|
+
font-size: 12px;
|
123
|
+
}
|
124
|
+
|
125
|
+
a {
|
126
|
+
color: #BE5C00;
|
127
|
+
}
|
128
|
+
|
129
|
+
/* Ruby code, style similar to vibrant ink */
|
130
|
+
.ruby {
|
131
|
+
font-size: 12px;
|
132
|
+
font-family: monospace;
|
133
|
+
color: white;
|
134
|
+
background-color: black;
|
135
|
+
padding: 0.1em 0 0.2em 0;
|
136
|
+
}
|
137
|
+
|
138
|
+
.ruby .keyword { color: #FF6600; }
|
139
|
+
.ruby .constant { color: #339999; }
|
140
|
+
.ruby .attribute { color: white; }
|
141
|
+
.ruby .global { color: white; }
|
142
|
+
.ruby .module { color: white; }
|
143
|
+
.ruby .class { color: white; }
|
144
|
+
.ruby .string { color: #66FF00; }
|
145
|
+
.ruby .ident { color: white; }
|
146
|
+
.ruby .method { color: #FFCC00; }
|
147
|
+
.ruby .number { color: white; }
|
148
|
+
.ruby .char { color: white; }
|
149
|
+
.ruby .comment { color: #9933CC; }
|
150
|
+
.ruby .symbol { color: white; }
|
151
|
+
.ruby .regex { color: #44B4CC; }
|
152
|
+
.ruby .punct { color: white; }
|
153
|
+
.ruby .escape { color: white; }
|
154
|
+
.ruby .interp { color: white; }
|
155
|
+
.ruby .expr { color: white; }
|
156
|
+
|
157
|
+
.ruby .offending { background-color: gray; }
|
158
|
+
.ruby .linenum {
|
159
|
+
width: 75px;
|
160
|
+
padding: 0.1em 1em 0.2em 0;
|
161
|
+
color: #000000;
|
162
|
+
background-color: #FFFBD3;
|
163
|
+
}
|
164
|
+
|
165
|
+
</style>
|
166
|
+
</head>
|
167
|
+
<body>
|
168
|
+
<div class="rspec-report">
|
169
|
+
|
170
|
+
<div id="rspec-header">
|
171
|
+
<div id="label">
|
172
|
+
<h1>RSpec Code Examples</h1>
|
173
|
+
</div>
|
174
|
+
|
175
|
+
<div id="summary">
|
176
|
+
<p id="totals"> </p>
|
177
|
+
<p id="duration"> </p>
|
178
|
+
</div>
|
179
|
+
</div>
|
180
|
+
|
181
|
+
<div class="results">
|
182
|
+
<div class="example_group">
|
183
|
+
<dl>
|
184
|
+
<dt id="example_group_1">ALSA::PCM::Native</dt>
|
185
|
+
<script type="text/javascript">moveProgressBar('9.0');</script>
|
186
|
+
<dd class="spec passed"><span class="passed_spec_name">should provide the STREAM_CAPTURE constant</span></dd>
|
187
|
+
</dl>
|
188
|
+
</div>
|
189
|
+
<div class="example_group">
|
190
|
+
<dl>
|
191
|
+
<dt id="example_group_2">ALSA::PCM::Capture.open</dt>
|
192
|
+
<script type="text/javascript">moveProgressBar('18.1');</script>
|
193
|
+
<dd class="spec passed"><span class="passed_spec_name">should create a Capture instance</span></dd>
|
194
|
+
<script type="text/javascript">moveProgressBar('27.2');</script>
|
195
|
+
<dd class="spec passed"><span class="passed_spec_name">should create the Capture instance with given arguments</span></dd>
|
196
|
+
</dl>
|
197
|
+
</div>
|
198
|
+
<div class="example_group">
|
199
|
+
<dl>
|
200
|
+
<dt id="example_group_3">ALSA logger</dt>
|
201
|
+
<script type="text/javascript">moveProgressBar('36.3');</script>
|
202
|
+
<dd class="spec passed"><span class="passed_spec_name">should have a default value</span></dd>
|
203
|
+
</dl>
|
204
|
+
</div>
|
205
|
+
<div class="example_group">
|
206
|
+
<dl>
|
207
|
+
<dt id="example_group_4">ALSA::Native.error_code?</dt>
|
208
|
+
<script type="text/javascript">moveProgressBar('45.4');</script>
|
209
|
+
<dd class="spec passed"><span class="passed_spec_name">should return true when given value is negative</span></dd>
|
210
|
+
<script type="text/javascript">moveProgressBar('54.5');</script>
|
211
|
+
<dd class="spec passed"><span class="passed_spec_name">should return false when given value is zero</span></dd>
|
212
|
+
<script type="text/javascript">moveProgressBar('63.6');</script>
|
213
|
+
<dd class="spec passed"><span class="passed_spec_name">should return false when given value is positive</span></dd>
|
214
|
+
</dl>
|
215
|
+
</div>
|
216
|
+
<div class="example_group">
|
217
|
+
<dl>
|
218
|
+
<dt id="example_group_5">ALSA::Native.strerror</dt>
|
219
|
+
<script type="text/javascript">moveProgressBar('72.7');</script>
|
220
|
+
<dd class="spec passed"><span class="passed_spec_name">should invoke snd_strerror function</span></dd>
|
221
|
+
</dl>
|
222
|
+
</div>
|
223
|
+
<div class="example_group">
|
224
|
+
<dl>
|
225
|
+
<dt id="example_group_6">ALSA try_to</dt>
|
226
|
+
<script type="text/javascript">moveProgressBar('81.8');</script>
|
227
|
+
<dd class="spec passed"><span class="passed_spec_name">should log in debug the given message</span></dd>
|
228
|
+
<script type="text/javascript">moveProgressBar('90.9');</script>
|
229
|
+
<dd class="spec passed"><span class="passed_spec_name">should execute the given block and return its value</span></dd>
|
230
|
+
</dl>
|
231
|
+
</div>
|
232
|
+
<div class="example_group">
|
233
|
+
<dl>
|
234
|
+
<dt id="example_group_7">ALSA try_to when block returns a negative value</dt>
|
235
|
+
<script type="text/javascript">moveProgressBar('100.0');</script>
|
236
|
+
<dd class="spec passed"><span class="passed_spec_name">should raise an error (with strerror of error code)</span></dd>
|
237
|
+
</dl>
|
238
|
+
</div>
|
239
|
+
<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>0.037272 seconds</strong>";</script>
|
240
|
+
<script type="text/javascript">document.getElementById('totals').innerHTML = "11 examples, 0 failures";</script>
|
241
|
+
</div>
|
242
|
+
</div>
|
243
|
+
</body>
|
244
|
+
</html>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ALSA::Native do
|
4
|
+
|
5
|
+
describe ".error_code?" do
|
6
|
+
|
7
|
+
it "should return true when given value is negative" do
|
8
|
+
ALSA::Native.error_code?(-1).should be_true
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return false when given value is zero" do
|
12
|
+
ALSA::Native.error_code?(0).should be_false
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return false when given value is positive" do
|
16
|
+
ALSA::Native.error_code?(1).should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".strerror" do
|
22
|
+
|
23
|
+
it "should invoke snd_strerror function" do
|
24
|
+
ALSA::Native.strerror(500000).should == "Sound protocol is not compatible"
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ALSA::PCM::Capture do
|
4
|
+
|
5
|
+
let(:device) { "default" }
|
6
|
+
|
7
|
+
def pending_if_no_device
|
8
|
+
pending("requires a real alsa device") unless File.exists?("/proc/asound")
|
9
|
+
end
|
10
|
+
|
11
|
+
describe ".open" do
|
12
|
+
|
13
|
+
let(:capture) { stub :open => true }
|
14
|
+
let(:hardware_attributes) { Hash.new :dummy => true }
|
15
|
+
|
16
|
+
before(:each) do
|
17
|
+
ALSA::PCM::Capture.stub :new => capture
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create a Capture instance" do
|
21
|
+
ALSA::PCM::Capture.should_receive(:new).and_return(capture)
|
22
|
+
ALSA::PCM::Capture.open(:device)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should create the Capture instance with given arguments" do
|
26
|
+
capture.should_receive(:open).with(:device, hardware_attributes)
|
27
|
+
ALSA::PCM::Capture.open(:device, hardware_attributes)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#open" do
|
33
|
+
|
34
|
+
let(:capture) { ALSA::PCM::Capture.new }
|
35
|
+
|
36
|
+
after(:each) do
|
37
|
+
capture.close if capture.opened?
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should initialize the native handle" do
|
41
|
+
pending_if_no_device
|
42
|
+
|
43
|
+
capture.open(device)
|
44
|
+
capture.handle.should_not be_nil
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when a block is given" do
|
48
|
+
|
49
|
+
it "should yield the block with itself" do
|
50
|
+
pending_if_no_device
|
51
|
+
|
52
|
+
capture.open(device) do |given_capture|
|
53
|
+
given_capture.should == capture
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should close the capture after block" do
|
58
|
+
pending_if_no_device
|
59
|
+
|
60
|
+
capture.open(device) {}
|
61
|
+
capture.should_not be_opened
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#read" do
|
69
|
+
|
70
|
+
let(:capture) { ALSA::PCM::Capture.new }
|
71
|
+
|
72
|
+
it "should raise an error when capture isn't opened" do
|
73
|
+
lambda { capture.read }.should raise_error
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should yield with read samples (buffer and frame count)" do
|
77
|
+
pending_if_no_device
|
78
|
+
|
79
|
+
capture.open(device) do |capture|
|
80
|
+
capture.read do |buffer, frame_count|
|
81
|
+
buffer.size.should == capture.hw_params.buffer_size_for(frame_count)
|
82
|
+
false
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should stop reading when block returns false" do
|
88
|
+
pending_if_no_device
|
89
|
+
|
90
|
+
read_count = 0
|
91
|
+
capture.open(device) do |capture|
|
92
|
+
capture.read do |buffer, frame_count|
|
93
|
+
read_count += 1
|
94
|
+
read_count < 3
|
95
|
+
end
|
96
|
+
end
|
97
|
+
read_count.should == 3
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|