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/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 }
|