ruby-alsa 0.0.5 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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/refs/alsa_player.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# A Minimal Capture Program
|
4
|
+
# using alsa via ruby-ffi
|
5
|
+
#
|
6
|
+
# This program opens an audio interface for capture, configures it for
|
7
|
+
# stereo, 16 bit, 44.1kHz, interleaved conventional read/write
|
8
|
+
# access. Then its reads a chunk of random data from it, and exits. It
|
9
|
+
# isn't meant to be a real program.
|
10
|
+
#
|
11
|
+
# Based on C example of Paul David's tutorial : http://equalarea.com/paul/alsa-audio.html
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
|
15
|
+
$: << File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
16
|
+
require 'alsa'
|
17
|
+
|
18
|
+
include FFI
|
19
|
+
include ALSA::PCM::Native
|
20
|
+
|
21
|
+
ALSA.logger.level = Logger::DEBUG
|
22
|
+
|
23
|
+
alsa_device = (ARGV.first or "default")
|
24
|
+
capture_handle = MemoryPointer.new :pointer
|
25
|
+
format = Format::S16_LE
|
26
|
+
|
27
|
+
ALSA::try_to "open audio device #{alsa_device}" do
|
28
|
+
open capture_handle, alsa_device, Stream::PLAYBACK, BLOCK
|
29
|
+
end
|
30
|
+
|
31
|
+
capture_handle = capture_handle.read_pointer
|
32
|
+
|
33
|
+
MemoryPointer.new(:pointer) do |hw_params|
|
34
|
+
ALSA::try_to "allocate hardware parameter structure" do
|
35
|
+
hw_params_malloc hw_params
|
36
|
+
end
|
37
|
+
hw_params = hw_params.read_pointer
|
38
|
+
|
39
|
+
ALSA::try_to "initialize hardware parameter structure" do
|
40
|
+
hw_params_any capture_handle, hw_params
|
41
|
+
end
|
42
|
+
|
43
|
+
ALSA::try_to "set access type" do
|
44
|
+
hw_params_set_access capture_handle, hw_params, Access::RW_INTERLEAVED
|
45
|
+
end
|
46
|
+
|
47
|
+
ALSA::try_to "set sample format" do
|
48
|
+
hw_params_set_format capture_handle, hw_params, format
|
49
|
+
end
|
50
|
+
|
51
|
+
ALSA::try_to "set sample rate" do
|
52
|
+
[44100, 0].to_pointers do |rate, direction|
|
53
|
+
hw_params_set_rate_near capture_handle, hw_params, rate, direction
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
ALSA::try_to "set channel count" do
|
58
|
+
hw_params_set_channels capture_handle, hw_params, 2
|
59
|
+
end
|
60
|
+
|
61
|
+
ALSA::try_to "set hw parameters" do
|
62
|
+
hw_params capture_handle, hw_params
|
63
|
+
end
|
64
|
+
|
65
|
+
ALSA::try_to "unallocate hw_params" do
|
66
|
+
hw_params_free hw_params
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
ALSA::try_to "prepare audio interface to use" do
|
71
|
+
prepare capture_handle
|
72
|
+
end
|
73
|
+
|
74
|
+
frame_count = 44100
|
75
|
+
MemoryPointer.new(format_size(format, frame_count) * 2) do |buffer|
|
76
|
+
3.times do
|
77
|
+
ALSA::try_to "write in audio interface" do
|
78
|
+
writei(capture_handle, buffer, frame_count)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
ALSA::try_to "close audio device" do
|
84
|
+
close capture_handle
|
85
|
+
end
|
Binary file
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <alsa/asoundlib.h>
|
4
|
+
#include <unistd.h>
|
5
|
+
|
6
|
+
static void playback_callback(snd_async_handler_t *callback)
|
7
|
+
{
|
8
|
+
snd_pcm_t *playback_handle = snd_async_handler_get_pcm(callback);
|
9
|
+
void *buf = snd_async_handler_get_callback_private(callback);
|
10
|
+
|
11
|
+
snd_pcm_sframes_t avail;
|
12
|
+
int err;
|
13
|
+
|
14
|
+
avail = snd_pcm_avail_update(playback_handle);
|
15
|
+
while (avail >= 1024) {
|
16
|
+
if ((err = snd_pcm_writei(playback_handle, buf, 1024)) != 1024) {
|
17
|
+
fprintf (stderr, "write to audio interface failed (%s)\n",
|
18
|
+
snd_strerror (err));
|
19
|
+
exit (1);
|
20
|
+
}
|
21
|
+
avail = snd_pcm_avail_update(playback_handle);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
main (int argc, char *argv[])
|
26
|
+
{
|
27
|
+
int i;
|
28
|
+
int err;
|
29
|
+
short buf[1024];
|
30
|
+
snd_pcm_t *playback_handle;
|
31
|
+
snd_pcm_hw_params_t *hw_params;
|
32
|
+
|
33
|
+
if ((err = snd_pcm_open (&playback_handle, argv[1], SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
|
34
|
+
fprintf (stderr, "cannot open audio device %s (%s)\n",
|
35
|
+
argv[1],
|
36
|
+
snd_strerror (err));
|
37
|
+
exit (1);
|
38
|
+
}
|
39
|
+
|
40
|
+
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
|
41
|
+
fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
|
42
|
+
snd_strerror (err));
|
43
|
+
exit (1);
|
44
|
+
}
|
45
|
+
|
46
|
+
if ((err = snd_pcm_hw_params_any (playback_handle, hw_params)) < 0) {
|
47
|
+
fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
|
48
|
+
snd_strerror (err));
|
49
|
+
exit (1);
|
50
|
+
}
|
51
|
+
|
52
|
+
if ((err = snd_pcm_hw_params_set_access (playback_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
|
53
|
+
fprintf (stderr, "cannot set access type (%s)\n",
|
54
|
+
snd_strerror (err));
|
55
|
+
exit (1);
|
56
|
+
}
|
57
|
+
|
58
|
+
if ((err = snd_pcm_hw_params_set_format (playback_handle, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
|
59
|
+
fprintf (stderr, "cannot set sample format (%s)\n",
|
60
|
+
snd_strerror (err));
|
61
|
+
exit (1);
|
62
|
+
}
|
63
|
+
|
64
|
+
if ((err = snd_pcm_hw_params_set_rate (playback_handle, hw_params, 44100, 0)) < 0) {
|
65
|
+
fprintf (stderr, "cannot set sample rate (%s)\n",
|
66
|
+
snd_strerror (err));
|
67
|
+
exit (1);
|
68
|
+
}
|
69
|
+
|
70
|
+
if ((err = snd_pcm_hw_params_set_channels (playback_handle, hw_params, 2)) < 0) {
|
71
|
+
fprintf (stderr, "cannot set channel count (%s)\n",
|
72
|
+
snd_strerror (err));
|
73
|
+
exit (1);
|
74
|
+
}
|
75
|
+
|
76
|
+
if ((err = snd_pcm_hw_params (playback_handle, hw_params)) < 0) {
|
77
|
+
fprintf (stderr, "cannot set parameters (%s)\n",
|
78
|
+
snd_strerror (err));
|
79
|
+
exit (1);
|
80
|
+
}
|
81
|
+
|
82
|
+
snd_pcm_hw_params_free (hw_params);
|
83
|
+
|
84
|
+
if ((err = snd_pcm_prepare (playback_handle)) < 0) {
|
85
|
+
fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
|
86
|
+
snd_strerror (err));
|
87
|
+
exit (1);
|
88
|
+
}
|
89
|
+
|
90
|
+
snd_async_handler_t *async_handler;
|
91
|
+
|
92
|
+
if ((err = snd_async_add_pcm_handler(&async_handler, playback_handle, playback_callback, buf)) < 0) {
|
93
|
+
fprintf (stderr, "cannot add async handler (%s)\n",
|
94
|
+
snd_strerror (err));
|
95
|
+
exit (1);
|
96
|
+
}
|
97
|
+
|
98
|
+
if ((err = snd_pcm_start (playback_handle)) < 0) {
|
99
|
+
fprintf (stderr, "cannot start audio interface for use (%s)\n",
|
100
|
+
snd_strerror (err));
|
101
|
+
exit (1);
|
102
|
+
}
|
103
|
+
|
104
|
+
if ((err = snd_pcm_writei (playback_handle, buf, 1024)) != 1024) {
|
105
|
+
fprintf (stderr, "write to audio interface failed (%s)\n",
|
106
|
+
snd_strerror (err));
|
107
|
+
exit (1);
|
108
|
+
}
|
109
|
+
|
110
|
+
while (1) {
|
111
|
+
sleep(1);
|
112
|
+
}
|
113
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# A Minimal Capture Program
|
4
|
+
# using alsa via ruby-ffi
|
5
|
+
#
|
6
|
+
# This program opens an audio interface for capture, configures it for
|
7
|
+
# stereo, 16 bit, 44.1kHz, interleaved conventional read/write
|
8
|
+
# access. Then its reads a chunk of random data from it, and exits. It
|
9
|
+
# isn't meant to be a real program.
|
10
|
+
#
|
11
|
+
# Based on C example of Paul David's tutorial : http://equalarea.com/paul/alsa-audio.html
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
|
15
|
+
$: << File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
16
|
+
require 'alsa'
|
17
|
+
|
18
|
+
include FFI
|
19
|
+
include ALSA::Native
|
20
|
+
include ALSA::PCM::Native
|
21
|
+
|
22
|
+
ALSA.logger.level = Logger::DEBUG
|
23
|
+
|
24
|
+
alsa_device = (ARGV.first or "default")
|
25
|
+
capture_handle = MemoryPointer.new :pointer
|
26
|
+
format = Format::S16_LE
|
27
|
+
|
28
|
+
ALSA::try_to "open audio device #{alsa_device}" do
|
29
|
+
open capture_handle, alsa_device, Stream::PLAYBACK, BLOCK
|
30
|
+
end
|
31
|
+
|
32
|
+
capture_handle = capture_handle.read_pointer
|
33
|
+
|
34
|
+
MemoryPointer.new(:pointer) do |hw_params|
|
35
|
+
ALSA::try_to "allocate hardware parameter structure" do
|
36
|
+
hw_params_malloc hw_params
|
37
|
+
end
|
38
|
+
hw_params = hw_params.read_pointer
|
39
|
+
|
40
|
+
ALSA::try_to "initialize hardware parameter structure" do
|
41
|
+
hw_params_any capture_handle, hw_params
|
42
|
+
end
|
43
|
+
|
44
|
+
ALSA::try_to "set access type" do
|
45
|
+
hw_params_set_access capture_handle, hw_params, Access::RW_INTERLEAVED
|
46
|
+
end
|
47
|
+
|
48
|
+
ALSA::try_to "set sample format" do
|
49
|
+
hw_params_set_format capture_handle, hw_params, format
|
50
|
+
end
|
51
|
+
|
52
|
+
ALSA::try_to "set sample rate" do
|
53
|
+
[44100, 0].to_pointers do |rate, direction|
|
54
|
+
hw_params_set_rate_near capture_handle, hw_params, rate, direction
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
ALSA::try_to "set channel count" do
|
59
|
+
hw_params_set_channels capture_handle, hw_params, 2
|
60
|
+
end
|
61
|
+
|
62
|
+
ALSA::try_to "set hw parameters" do
|
63
|
+
hw_params capture_handle, hw_params
|
64
|
+
end
|
65
|
+
|
66
|
+
ALSA::try_to "unallocate hw_params" do
|
67
|
+
hw_params_free hw_params
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ALSA::try_to "prepare audio interface to use" do
|
72
|
+
prepare capture_handle
|
73
|
+
end
|
74
|
+
|
75
|
+
async_handler = MemoryPointer.new(:pointer)
|
76
|
+
|
77
|
+
frame_count = 44100
|
78
|
+
|
79
|
+
playback_callback = Proc.new do |async_handler|
|
80
|
+
capture_handle = async_handler_get_pcm(async_handler)
|
81
|
+
buffer = async_handler_get_callback_private(async_handler)
|
82
|
+
|
83
|
+
ALSA::try_to "write in audio interface" do
|
84
|
+
writei(capture_handle, buffer, frame_count)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
buffer = MemoryPointer.new(format_size(format, frame_count) * 2)
|
89
|
+
|
90
|
+
ALSA::try_to "add async handler" do
|
91
|
+
async_add_pcm_handler(async_handler, capture_handle, playback_callback, buffer)
|
92
|
+
end
|
93
|
+
|
94
|
+
ALSA::try_to "write in audio interface" do
|
95
|
+
writei(capture_handle, buffer, frame_count)
|
96
|
+
end
|
97
|
+
|
98
|
+
loop { sleep 10 }
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# A Minimal Capture Program
|
4
|
+
# using alsa via ruby-ffi
|
5
|
+
#
|
6
|
+
# This program opens an audio interface for capture, configures it for
|
7
|
+
# stereo, 16 bit, 44.1kHz, interleaved conventional read/write
|
8
|
+
# access. Then its reads a chunk of random data from it, and exits. It
|
9
|
+
# isn't meant to be a real program.
|
10
|
+
#
|
11
|
+
# Based on C example of Paul David's tutorial : http://equalarea.com/paul/alsa-audio.html
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
|
15
|
+
$: << File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
16
|
+
require 'alsa'
|
17
|
+
|
18
|
+
include FFI
|
19
|
+
include ALSA::PCM::Native
|
20
|
+
|
21
|
+
ALSA.logger.level = Logger::DEBUG
|
22
|
+
|
23
|
+
alsa_device = (ARGV.first or "default")
|
24
|
+
capture_handle = MemoryPointer.new :pointer
|
25
|
+
format = Format::S16_LE
|
26
|
+
|
27
|
+
ALSA::try_to "open audio device #{alsa_device}" do
|
28
|
+
open capture_handle, alsa_device, Stream::CAPTURE, BLOCK
|
29
|
+
end
|
30
|
+
|
31
|
+
capture_handle = capture_handle.read_pointer
|
32
|
+
|
33
|
+
MemoryPointer.new(:pointer) do |hw_params|
|
34
|
+
ALSA::try_to "allocate hardware parameter structure" do
|
35
|
+
hw_params_malloc hw_params
|
36
|
+
end
|
37
|
+
hw_params = hw_params.read_pointer
|
38
|
+
|
39
|
+
ALSA::try_to "initialize hardware parameter structure" do
|
40
|
+
hw_params_any capture_handle, hw_params
|
41
|
+
end
|
42
|
+
|
43
|
+
ALSA::try_to "set access type" do
|
44
|
+
hw_params_set_access capture_handle, hw_params, Access::RW_INTERLEAVED
|
45
|
+
end
|
46
|
+
|
47
|
+
ALSA::try_to "set sample format" do
|
48
|
+
hw_params_set_format capture_handle, hw_params, format
|
49
|
+
end
|
50
|
+
|
51
|
+
ALSA::try_to "set sample rate" do
|
52
|
+
[44100, 0].to_pointers do |rate, direction|
|
53
|
+
hw_params_set_rate_near capture_handle, hw_params, rate, direction
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
ALSA::try_to "set channel count" do
|
58
|
+
hw_params_set_channels capture_handle, hw_params, 2
|
59
|
+
end
|
60
|
+
|
61
|
+
ALSA::try_to "set hw parameters" do
|
62
|
+
hw_params capture_handle, hw_params
|
63
|
+
end
|
64
|
+
|
65
|
+
ALSA::try_to "unallocate hw_params" do
|
66
|
+
hw_params_free hw_params
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
ALSA::try_to "prepare audio interface to use" do
|
71
|
+
prepare capture_handle
|
72
|
+
end
|
73
|
+
|
74
|
+
frame_count = 44100
|
75
|
+
MemoryPointer.new(format_size(format, frame_count) * 2) do |buffer|
|
76
|
+
3.times do
|
77
|
+
ALSA::try_to "read from audio interface" do
|
78
|
+
readi(capture_handle, buffer, frame_count)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
ALSA::try_to "close audio device" do
|
84
|
+
close capture_handle
|
85
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# A Minimal Capture Program
|
4
|
+
# using alsa via ruby-ffi
|
5
|
+
#
|
6
|
+
# This program opens an audio interface for capture, configures it for
|
7
|
+
# stereo, 16 bit, 44.1kHz, interleaved conventional read/write
|
8
|
+
# access. Then its reads a chunk of random data from it, and exits. It
|
9
|
+
# isn't meant to be a real program.
|
10
|
+
#
|
11
|
+
# Based on C example of Paul David's tutorial : http://equalarea.com/paul/alsa-audio.html
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
|
15
|
+
$: << File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
16
|
+
require 'alsa'
|
17
|
+
|
18
|
+
include FFI
|
19
|
+
include ALSA::Native
|
20
|
+
include ALSA::PCM::Native
|
21
|
+
|
22
|
+
ALSA.logger.level = Logger::DEBUG
|
23
|
+
|
24
|
+
alsa_device = (ARGV.first or "default")
|
25
|
+
capture_handle = MemoryPointer.new :pointer
|
26
|
+
format = Format::S16_LE
|
27
|
+
|
28
|
+
ALSA::try_to "open audio device #{alsa_device}" do
|
29
|
+
open capture_handle, alsa_device, Stream::CAPTURE, BLOCK
|
30
|
+
end
|
31
|
+
|
32
|
+
capture_handle = capture_handle.read_pointer
|
33
|
+
|
34
|
+
MemoryPointer.new(:pointer) do |hw_params|
|
35
|
+
ALSA::try_to "allocate hardware parameter structure" do
|
36
|
+
hw_params_malloc hw_params
|
37
|
+
end
|
38
|
+
hw_params = hw_params.read_pointer
|
39
|
+
|
40
|
+
ALSA::try_to "initialize hardware parameter structure" do
|
41
|
+
hw_params_any capture_handle, hw_params
|
42
|
+
end
|
43
|
+
|
44
|
+
ALSA::try_to "set access type" do
|
45
|
+
hw_params_set_access capture_handle, hw_params, Access::RW_INTERLEAVED
|
46
|
+
end
|
47
|
+
|
48
|
+
ALSA::try_to "set sample format" do
|
49
|
+
hw_params_set_format capture_handle, hw_params, format
|
50
|
+
end
|
51
|
+
|
52
|
+
ALSA::try_to "set sample rate" do
|
53
|
+
[44100, 0].to_pointers do |rate, direction|
|
54
|
+
hw_params_set_rate_near capture_handle, hw_params, rate, direction
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
ALSA::try_to "set channel count" do
|
59
|
+
hw_params_set_channels capture_handle, hw_params, 2
|
60
|
+
end
|
61
|
+
|
62
|
+
ALSA::try_to "set hw parameters" do
|
63
|
+
hw_params capture_handle, hw_params
|
64
|
+
end
|
65
|
+
|
66
|
+
ALSA::try_to "unallocate hw_params" do
|
67
|
+
hw_params_free hw_params
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ALSA::try_to "prepare audio interface to use" do
|
72
|
+
prepare capture_handle
|
73
|
+
end
|
74
|
+
|
75
|
+
async_handler = MemoryPointer.new(:pointer)
|
76
|
+
|
77
|
+
frame_count = 44100
|
78
|
+
|
79
|
+
capture_callback = Proc.new do |async_handler|
|
80
|
+
capture_handle = async_handler_get_pcm(async_handler)
|
81
|
+
buffer = async_handler_get_callback_private(async_handler)
|
82
|
+
|
83
|
+
ALSA::try_to "read in audio interface" do
|
84
|
+
readi(capture_handle, buffer, frame_count)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
buffer = MemoryPointer.new(format_size(format, frame_count) * 2)
|
89
|
+
|
90
|
+
ALSA::try_to "add async handler" do
|
91
|
+
async_add_pcm_handler(async_handler, capture_handle, capture_callback, buffer)
|
92
|
+
end
|
93
|
+
|
94
|
+
ALSA::try_to "read from audio interface" do
|
95
|
+
readi(capture_handle, buffer, frame_count)
|
96
|
+
end
|
97
|
+
|
98
|
+
loop { sleep 10 }
|