hornetseye-alsa 0.1.0
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/.document +1 -0
- data/COPYING +679 -0
- data/README.md +4 -0
- data/Rakefile +184 -0
- data/ext/alsaoutput.cc +285 -0
- data/ext/alsaoutput.hh +68 -0
- data/ext/error.hh +50 -0
- data/ext/init.cc +38 -0
- data/ext/rubyinc.hh +54 -0
- data/ext/sequence.cc +50 -0
- data/ext/sequence.hh +39 -0
- data/lib/hornetseye-alsa/alsaoutput.rb +52 -0
- data/lib/hornetseye_alsa_ext.rb +17 -0
- metadata +131 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'date'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/loaders/makefile'
|
7
|
+
require 'rbconfig'
|
8
|
+
|
9
|
+
PKG_NAME = 'hornetseye-alsa'
|
10
|
+
PKG_VERSION = '0.1.0'
|
11
|
+
CXX = ENV[ 'CXX' ] || 'g++'
|
12
|
+
STRIP = ENV[ 'STRIP' ] || 'strip'
|
13
|
+
RB_FILES = FileList[ 'lib/**/*.rb' ]
|
14
|
+
CC_FILES = FileList[ 'ext/*.cc' ]
|
15
|
+
HH_FILES = FileList[ 'ext/*.hh' ] + FileList[ 'ext/*.tcc' ]
|
16
|
+
TC_FILES = FileList[ 'test/tc_*.rb' ]
|
17
|
+
TS_FILES = FileList[ 'test/ts_*.rb' ]
|
18
|
+
SO_FILE = "ext/#{PKG_NAME.tr '\-', '_'}.so"
|
19
|
+
PKG_FILES = [ 'Rakefile', 'README.md', 'COPYING', '.document' ] +
|
20
|
+
RB_FILES + CC_FILES + HH_FILES + TS_FILES + TC_FILES
|
21
|
+
BIN_FILES = [ 'README.md', 'COPYING', '.document', SO_FILE ] +
|
22
|
+
RB_FILES + TS_FILES + TC_FILES
|
23
|
+
SUMMARY = %q{Play audio data using libalsa}
|
24
|
+
DESCRIPTION = %q{This Ruby extension provides an interface for playing audio data using ALSA.}
|
25
|
+
AUTHOR = %q{Jan Wedekind}
|
26
|
+
EMAIL = %q{jan@wedesoft.de}
|
27
|
+
HOMEPAGE = %q{http://wedesoft.github.com/hornetseye-alsa/}
|
28
|
+
|
29
|
+
OBJ = CC_FILES.ext 'o'
|
30
|
+
$CXXFLAGS = ENV[ 'CXXFLAGS' ] || ''
|
31
|
+
$CXXFLAGS = "#{$CXXFLAGS} -fPIC -DNDEBUG"
|
32
|
+
if RbConfig::CONFIG[ 'rubyhdrdir' ]
|
33
|
+
$CXXFLAGS = "#{$CXXFLAGS} -I#{RbConfig::CONFIG[ 'rubyhdrdir' ]} " +
|
34
|
+
"-I#{RbConfig::CONFIG[ 'rubyhdrdir' ]}/#{RbConfig::CONFIG[ 'arch' ]}"
|
35
|
+
else
|
36
|
+
$CXXFLAGS += "#{$CXXFLAGS} -I#{RbConfig::CONFIG[ 'archdir' ]}"
|
37
|
+
end
|
38
|
+
$LIBRUBYARG = RbConfig::CONFIG[ 'LIBRUBYARG' ]
|
39
|
+
$SITELIBDIR = RbConfig::CONFIG[ 'sitelibdir' ]
|
40
|
+
$SITEARCHDIR = RbConfig::CONFIG[ 'sitearchdir' ]
|
41
|
+
|
42
|
+
task :default => :all
|
43
|
+
|
44
|
+
desc 'Compile Ruby extension (default)'
|
45
|
+
task :all => [ SO_FILE ]
|
46
|
+
|
47
|
+
file SO_FILE => OBJ do |t|
|
48
|
+
sh "#{CXX} -shared -o #{t.name} #{OBJ} -lasound #{$LIBRUBYARG}"
|
49
|
+
sh "#{STRIP} --strip-all #{t.name}"
|
50
|
+
end
|
51
|
+
|
52
|
+
task :test => [ SO_FILE ]
|
53
|
+
|
54
|
+
desc 'Install Ruby extension'
|
55
|
+
task :install => :all do
|
56
|
+
verbose true do
|
57
|
+
for f in RB_FILES do
|
58
|
+
FileUtils.mkdir_p "#{$SITELIBDIR}/#{File.dirname f.gsub( /^lib\//, '' )}"
|
59
|
+
FileUtils.cp_r f, "#{$SITELIBDIR}/#{f.gsub( /^lib\//, '' )}"
|
60
|
+
end
|
61
|
+
FileUtils.mkdir_p $SITEARCHDIR
|
62
|
+
FileUtils.cp SO_FILE, "#{$SITEARCHDIR}/#{File.basename SO_FILE}"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'Uninstall Ruby extension'
|
67
|
+
task :uninstall do
|
68
|
+
verbose true do
|
69
|
+
for f in RB_FILES do
|
70
|
+
FileUtils.rm_f "#{$SITELIBDIR}/#{f.gsub /^lib\//, ''}"
|
71
|
+
end
|
72
|
+
FileUtils.rm_f "#{$SITEARCHDIR}/#{File.basename SO_FILE}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Rake::TestTask.new do |t|
|
77
|
+
t.libs << 'ext'
|
78
|
+
t.test_files = TC_FILES
|
79
|
+
end
|
80
|
+
|
81
|
+
begin
|
82
|
+
require 'yard'
|
83
|
+
YARD::Rake::YardocTask.new :yard do |y|
|
84
|
+
y.options << '--no-private'
|
85
|
+
y.files << FileList[ 'lib/**/*.rb' ]
|
86
|
+
end
|
87
|
+
rescue LoadError
|
88
|
+
STDERR.puts 'Please install \'yard\' if you want to generate documentation'
|
89
|
+
end
|
90
|
+
|
91
|
+
Rake::PackageTask.new PKG_NAME, PKG_VERSION do |p|
|
92
|
+
p.need_tar = true
|
93
|
+
p.package_files = PKG_FILES
|
94
|
+
end
|
95
|
+
|
96
|
+
begin
|
97
|
+
require 'rubygems'
|
98
|
+
require 'rubygems/builder'
|
99
|
+
$SPEC = Gem::Specification.new do |s|
|
100
|
+
s.name = PKG_NAME
|
101
|
+
s.version = PKG_VERSION
|
102
|
+
s.platform = Gem::Platform::RUBY
|
103
|
+
s.date = Date.today.to_s
|
104
|
+
s.summary = SUMMARY
|
105
|
+
s.description = DESCRIPTION
|
106
|
+
s.author = AUTHOR
|
107
|
+
s.email = EMAIL
|
108
|
+
s.homepage = HOMEPAGE
|
109
|
+
s.files = PKG_FILES
|
110
|
+
s.test_files = TC_FILES
|
111
|
+
s.require_paths = [ 'lib', 'ext' ]
|
112
|
+
s.rubyforge_project = %q{hornetseye}
|
113
|
+
s.extensions = %w{Rakefile}
|
114
|
+
s.has_rdoc = 'yard'
|
115
|
+
s.extra_rdoc_files = []
|
116
|
+
s.rdoc_options = %w{--no-private}
|
117
|
+
s.add_dependency %<malloc>, [ '~> 1.2' ]
|
118
|
+
s.add_dependency %<multiarray>, [ '~> 0.11' ]
|
119
|
+
s.add_dependency %<hornetseye-frame>, [ '~> 0.7' ]
|
120
|
+
s.add_development_dependency %q{rake}
|
121
|
+
end
|
122
|
+
GEM_SOURCE = "#{PKG_NAME}-#{PKG_VERSION}.gem"
|
123
|
+
$BINSPEC = Gem::Specification.new do |s|
|
124
|
+
s.name = PKG_NAME
|
125
|
+
s.version = PKG_VERSION
|
126
|
+
s.platform = Gem::Platform::CURRENT
|
127
|
+
s.date = Date.today.to_s
|
128
|
+
s.summary = SUMMARY
|
129
|
+
s.description = DESCRIPTION
|
130
|
+
s.author = AUTHOR
|
131
|
+
s.email = EMAIL
|
132
|
+
s.homepage = HOMEPAGE
|
133
|
+
s.files = BIN_FILES
|
134
|
+
s.test_files = TC_FILES
|
135
|
+
s.require_paths = [ 'lib', 'ext' ]
|
136
|
+
s.rubyforge_project = %q{hornetseye}
|
137
|
+
s.has_rdoc = 'yard'
|
138
|
+
s.extra_rdoc_files = []
|
139
|
+
s.rdoc_options = %w{--no-private}
|
140
|
+
s.add_dependency %<malloc>, [ '~> 1.2' ]
|
141
|
+
s.add_dependency %<multiarray>, [ '~> 0.11' ]
|
142
|
+
end
|
143
|
+
GEM_BINARY = "#{PKG_NAME}-#{PKG_VERSION}-#{$BINSPEC.platform}.gem"
|
144
|
+
desc "Build the gem file #{GEM_SOURCE}"
|
145
|
+
task :gem => [ "pkg/#{GEM_SOURCE}" ]
|
146
|
+
file "pkg/#{GEM_SOURCE}" => [ 'pkg' ] + $SPEC.files do
|
147
|
+
when_writing 'Creating GEM' do
|
148
|
+
Gem::Builder.new( $SPEC ).build
|
149
|
+
verbose true do
|
150
|
+
FileUtils.mv GEM_SOURCE, "pkg/#{GEM_SOURCE}"
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
desc "Build the gem file #{GEM_BINARY}"
|
155
|
+
task :gem_binary => [ "pkg/#{GEM_BINARY}" ]
|
156
|
+
file "pkg/#{GEM_BINARY}" => [ 'pkg' ] + $BINSPEC.files do
|
157
|
+
when_writing 'Creating binary GEM' do
|
158
|
+
Gem::Builder.new( $BINSPEC ).build
|
159
|
+
verbose true do
|
160
|
+
FileUtils.mv GEM_BINARY, "pkg/#{GEM_BINARY}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
rescue LoadError
|
165
|
+
STDERR.puts 'Please install \'rubygems\' if you want to create Gem packages'
|
166
|
+
end
|
167
|
+
|
168
|
+
rule '.o' => '.cc' do |t|
|
169
|
+
sh "#{CXX} #{$CXXFLAGS} -c -o #{t.name} #{t.source}"
|
170
|
+
end
|
171
|
+
|
172
|
+
file ".depends.mf" do |t|
|
173
|
+
sh "g++ -MM #{$CXXFLAGS} #{CC_FILES.join ' '} | " +
|
174
|
+
"sed -e :a -e N -e 's/\\n/\\$/g' -e ta | " +
|
175
|
+
"sed -e 's/ *\\\\\\$ */ /g' -e 's/\\$/\\n/g' | sed -e 's/^/ext\\//' > #{t.name}"
|
176
|
+
end
|
177
|
+
CC_FILES.each do |t|
|
178
|
+
file t.ext(".o") => t
|
179
|
+
end
|
180
|
+
import ".depends.mf"
|
181
|
+
|
182
|
+
CLEAN.include 'ext/*.o'
|
183
|
+
CLOBBER.include SO_FILE, 'doc', '.yardoc', '.depends.mf'
|
184
|
+
|
data/ext/alsaoutput.cc
ADDED
@@ -0,0 +1,285 @@
|
|
1
|
+
/* HornetsEye - Computer Vision with Ruby
|
2
|
+
Copyright (C) 2006, 2007, 2008, 2009, 2010 Jan Wedekind
|
3
|
+
|
4
|
+
This program is free software: you can redistribute it and/or modify
|
5
|
+
it under the terms of the GNU General Public License as published by
|
6
|
+
the Free Software Foundation, either version 3 of the License, or
|
7
|
+
(at your option) any later version.
|
8
|
+
|
9
|
+
This program is distributed in the hope that it will be useful,
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
GNU General Public License for more details.
|
13
|
+
|
14
|
+
You should have received a copy of the GNU General Public License
|
15
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
16
|
+
#include "alsaoutput.hh"
|
17
|
+
|
18
|
+
using namespace std;
|
19
|
+
|
20
|
+
VALUE AlsaOutput::cRubyClass = Qnil;
|
21
|
+
|
22
|
+
AlsaOutput::AlsaOutput( const string &pcmName, unsigned int rate,
|
23
|
+
unsigned int channels, int periods,
|
24
|
+
int frames ) throw (Error):
|
25
|
+
m_pcmHandle(NULL), m_pcmName( pcmName ), m_rate( rate ), m_channels( channels ),
|
26
|
+
m_frames( frames )
|
27
|
+
{
|
28
|
+
try {
|
29
|
+
snd_pcm_hw_params_t *hwParams;
|
30
|
+
snd_pcm_hw_params_alloca( &hwParams );
|
31
|
+
int err = snd_pcm_open( &m_pcmHandle, m_pcmName.c_str(), SND_PCM_STREAM_PLAYBACK,
|
32
|
+
SND_PCM_NONBLOCK );
|
33
|
+
ERRORMACRO( err >= 0, Error, , "Error opening PCM device \"" << m_pcmName
|
34
|
+
<< "\": " << snd_strerror( err ) );
|
35
|
+
err = snd_pcm_hw_params_any( m_pcmHandle, hwParams );
|
36
|
+
ERRORMACRO( err >= 0, Error, , "Unable to configure the PCM device \""
|
37
|
+
<< m_pcmName << "\": " << snd_strerror( err ) );
|
38
|
+
err = snd_pcm_hw_params_set_access( m_pcmHandle, hwParams,
|
39
|
+
SND_PCM_ACCESS_RW_INTERLEAVED );
|
40
|
+
ERRORMACRO( err >= 0, Error, , "Error setting PCM device \""
|
41
|
+
<< m_pcmName << "\" to interlaced access: " << snd_strerror( err ) );
|
42
|
+
err = snd_pcm_hw_params_set_format( m_pcmHandle, hwParams,
|
43
|
+
SND_PCM_FORMAT_S16_LE );
|
44
|
+
ERRORMACRO( err >= 0, Error, , "Error setting PCM device \"" << m_pcmName
|
45
|
+
<< "\" to 16-bit signed integer format: " << snd_strerror( err ) );
|
46
|
+
err = snd_pcm_hw_params_set_rate_near( m_pcmHandle, hwParams, &m_rate, 0 );
|
47
|
+
ERRORMACRO( err >= 0, Error, , "Error setting sampling rate of PCM device \""
|
48
|
+
<< m_pcmName << "\" to " << rate << " Hz: " << snd_strerror( err ) );
|
49
|
+
err = snd_pcm_hw_params_set_channels( m_pcmHandle, hwParams, channels );
|
50
|
+
ERRORMACRO( err >= 0, Error, , "Error setting number of channels of PCM device \""
|
51
|
+
<< m_pcmName << "\" to " << channels << ": " << snd_strerror( err ) );
|
52
|
+
err = snd_pcm_hw_params_set_periods( m_pcmHandle, hwParams, periods, 0 );
|
53
|
+
ERRORMACRO( err >= 0, Error, , "Error setting number of periods of PCM device \""
|
54
|
+
<< m_pcmName << "\" to " << periods << ": " << snd_strerror( err ) );
|
55
|
+
err = snd_pcm_hw_params_set_buffer_size_near( m_pcmHandle, hwParams, &m_frames );
|
56
|
+
ERRORMACRO( err >= 0, Error, , "Error setting buffer size of PCM device \""
|
57
|
+
<< m_pcmName << "\" to " << m_frames << " frames: "
|
58
|
+
<< snd_strerror( err ) );
|
59
|
+
err = snd_pcm_hw_params( m_pcmHandle, hwParams );
|
60
|
+
ERRORMACRO( err >= 0, Error, , "Error setting parameters of PCM device \""
|
61
|
+
<< m_pcmName << "\": " << snd_strerror( err ) );
|
62
|
+
} catch ( Error &e ) {
|
63
|
+
close();
|
64
|
+
throw e;
|
65
|
+
};
|
66
|
+
}
|
67
|
+
|
68
|
+
AlsaOutput::~AlsaOutput(void)
|
69
|
+
{
|
70
|
+
close();
|
71
|
+
}
|
72
|
+
|
73
|
+
void AlsaOutput::close(void)
|
74
|
+
{
|
75
|
+
if ( m_pcmHandle != NULL ) {
|
76
|
+
drop();
|
77
|
+
snd_pcm_close( m_pcmHandle );
|
78
|
+
m_pcmHandle = NULL;
|
79
|
+
};
|
80
|
+
}
|
81
|
+
|
82
|
+
void AlsaOutput::write( SequencePtr frame ) throw (Error)
|
83
|
+
{
|
84
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
85
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
86
|
+
int err = snd_pcm_writei( m_pcmHandle, (short int *)frame->data(),
|
87
|
+
frame->size() / ( 2 * m_channels ) );
|
88
|
+
ERRORMACRO( err >= 0, Error, , "Error writing audio frames to PCM device \""
|
89
|
+
<< m_pcmName << "\": " << snd_strerror( err ) );
|
90
|
+
}
|
91
|
+
|
92
|
+
void AlsaOutput::drop(void) throw (Error)
|
93
|
+
{
|
94
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
95
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
96
|
+
snd_pcm_drop( m_pcmHandle );
|
97
|
+
}
|
98
|
+
|
99
|
+
void AlsaOutput::drain(void) throw (Error)
|
100
|
+
{
|
101
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
102
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
103
|
+
snd_pcm_drain( m_pcmHandle );
|
104
|
+
}
|
105
|
+
|
106
|
+
unsigned int AlsaOutput::rate(void)
|
107
|
+
{
|
108
|
+
return m_rate;
|
109
|
+
}
|
110
|
+
|
111
|
+
unsigned int AlsaOutput::channels(void)
|
112
|
+
{
|
113
|
+
return m_channels;
|
114
|
+
}
|
115
|
+
|
116
|
+
unsigned int AlsaOutput::frames(void)
|
117
|
+
{
|
118
|
+
return m_frames;
|
119
|
+
}
|
120
|
+
|
121
|
+
int AlsaOutput::avail(void) throw (Error)
|
122
|
+
{
|
123
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
124
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
125
|
+
snd_pcm_sframes_t frames = snd_pcm_avail( m_pcmHandle );
|
126
|
+
ERRORMACRO( frames >= 0, Error, , "Error querying number of available frames for "
|
127
|
+
"update of PCM device \"" << m_pcmName << "\": "
|
128
|
+
<< snd_strerror( frames ) );
|
129
|
+
return frames;
|
130
|
+
}
|
131
|
+
|
132
|
+
int AlsaOutput::delay(void) throw (Error)
|
133
|
+
{
|
134
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
135
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
136
|
+
snd_pcm_sframes_t frames;
|
137
|
+
int err = snd_pcm_delay( m_pcmHandle, &frames );
|
138
|
+
ERRORMACRO( err >= 0, Error, , "Error querying number of available frames for "
|
139
|
+
"update of PCM device \"" << m_pcmName << "\": "
|
140
|
+
<< snd_strerror( err ) );
|
141
|
+
return frames;
|
142
|
+
}
|
143
|
+
|
144
|
+
void AlsaOutput::prepare(void) throw (Error)
|
145
|
+
{
|
146
|
+
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
147
|
+
<< "\" is not open. Did you call \"close\" before?" );
|
148
|
+
int err = snd_pcm_prepare( m_pcmHandle );
|
149
|
+
ERRORMACRO( err >= 0, Error, , "Error preparing PCM device \"" << m_pcmName
|
150
|
+
<< "\": " << snd_strerror( err ) );
|
151
|
+
}
|
152
|
+
|
153
|
+
VALUE AlsaOutput::registerRubyClass( VALUE rbModule )
|
154
|
+
{
|
155
|
+
cRubyClass = rb_define_class_under( rbModule, "AlsaOutput", rb_cObject );
|
156
|
+
rb_define_singleton_method( cRubyClass, "new",
|
157
|
+
RUBY_METHOD_FUNC( wrapNew ), 5 );
|
158
|
+
rb_define_method( cRubyClass, "close", RUBY_METHOD_FUNC( wrapClose ), 0 );
|
159
|
+
rb_define_method( cRubyClass, "write", RUBY_METHOD_FUNC( wrapWrite ), 1 );
|
160
|
+
rb_define_method( cRubyClass, "drop", RUBY_METHOD_FUNC( wrapDrop ), 0 );
|
161
|
+
rb_define_method( cRubyClass, "drain", RUBY_METHOD_FUNC( wrapDrain ), 0 );
|
162
|
+
rb_define_method( cRubyClass, "rate", RUBY_METHOD_FUNC( wrapRate ), 0 );
|
163
|
+
rb_define_method( cRubyClass, "channels", RUBY_METHOD_FUNC( wrapChannels ), 0 );
|
164
|
+
rb_define_method( cRubyClass, "frames", RUBY_METHOD_FUNC( wrapFrames ), 0 );
|
165
|
+
rb_define_method( cRubyClass, "avail", RUBY_METHOD_FUNC( wrapAvail ), 0 );
|
166
|
+
rb_define_method( cRubyClass, "delay", RUBY_METHOD_FUNC( wrapDelay ), 0 );
|
167
|
+
rb_define_method( cRubyClass, "prepare", RUBY_METHOD_FUNC( wrapPrepare ), 0 );
|
168
|
+
}
|
169
|
+
|
170
|
+
void AlsaOutput::deleteRubyObject( void *ptr )
|
171
|
+
{
|
172
|
+
delete (AlsaOutputPtr *)ptr;
|
173
|
+
}
|
174
|
+
|
175
|
+
VALUE AlsaOutput::wrapNew( VALUE rbClass, VALUE rbPCMName, VALUE rbRate,
|
176
|
+
VALUE rbChannels, VALUE rbPeriods, VALUE rbFrames )
|
177
|
+
{
|
178
|
+
VALUE retVal = Qnil;
|
179
|
+
try {
|
180
|
+
rb_check_type( rbPCMName, T_STRING );
|
181
|
+
AlsaOutputPtr ptr( new AlsaOutput( StringValuePtr( rbPCMName ),
|
182
|
+
NUM2UINT( rbRate ), NUM2UINT( rbChannels ),
|
183
|
+
NUM2INT( rbPeriods ), NUM2INT( rbFrames ) ) );
|
184
|
+
retVal = Data_Wrap_Struct( rbClass, 0, deleteRubyObject,
|
185
|
+
new AlsaOutputPtr( ptr ) );
|
186
|
+
} catch ( exception &e ) {
|
187
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
188
|
+
};
|
189
|
+
return retVal;
|
190
|
+
}
|
191
|
+
|
192
|
+
VALUE AlsaOutput::wrapClose( VALUE rbSelf )
|
193
|
+
{
|
194
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
195
|
+
(*self)->close();
|
196
|
+
return rbSelf;
|
197
|
+
}
|
198
|
+
|
199
|
+
VALUE AlsaOutput::wrapWrite( VALUE rbSelf, VALUE rbSequence )
|
200
|
+
{
|
201
|
+
try {
|
202
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
203
|
+
SequencePtr sequence( new Sequence( rbSequence ) );
|
204
|
+
(*self)->write( sequence );
|
205
|
+
} catch ( exception &e ) {
|
206
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
207
|
+
};
|
208
|
+
return rbSequence;
|
209
|
+
}
|
210
|
+
|
211
|
+
VALUE AlsaOutput::wrapDrop( VALUE rbSelf )
|
212
|
+
{
|
213
|
+
try {
|
214
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
215
|
+
(*self)->drop();
|
216
|
+
} catch ( exception &e ) {
|
217
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
218
|
+
};
|
219
|
+
return rbSelf;
|
220
|
+
}
|
221
|
+
|
222
|
+
VALUE AlsaOutput::wrapDrain( VALUE rbSelf )
|
223
|
+
{
|
224
|
+
try {
|
225
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
226
|
+
(*self)->drain();
|
227
|
+
} catch ( exception &e ) {
|
228
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
229
|
+
};
|
230
|
+
return rbSelf;
|
231
|
+
}
|
232
|
+
|
233
|
+
VALUE AlsaOutput::wrapRate( VALUE rbSelf )
|
234
|
+
{
|
235
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
236
|
+
return UINT2NUM( (*self)->rate() );
|
237
|
+
}
|
238
|
+
|
239
|
+
VALUE AlsaOutput::wrapChannels( VALUE rbSelf )
|
240
|
+
{
|
241
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
242
|
+
return UINT2NUM( (*self)->channels() );
|
243
|
+
}
|
244
|
+
|
245
|
+
VALUE AlsaOutput::wrapFrames( VALUE rbSelf )
|
246
|
+
{
|
247
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
248
|
+
return UINT2NUM( (*self)->frames() );
|
249
|
+
}
|
250
|
+
|
251
|
+
VALUE AlsaOutput::wrapAvail( VALUE rbSelf )
|
252
|
+
{
|
253
|
+
VALUE rbRetVal = Qnil;
|
254
|
+
try {
|
255
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
256
|
+
rbRetVal = INT2NUM( (*self)->avail() );
|
257
|
+
} catch ( exception &e ) {
|
258
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
259
|
+
};
|
260
|
+
return rbRetVal;
|
261
|
+
}
|
262
|
+
|
263
|
+
VALUE AlsaOutput::wrapDelay( VALUE rbSelf )
|
264
|
+
{
|
265
|
+
VALUE rbRetVal = Qnil;
|
266
|
+
try {
|
267
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
268
|
+
rbRetVal = INT2NUM( (*self)->delay() );
|
269
|
+
} catch ( exception &e ) {
|
270
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
271
|
+
};
|
272
|
+
return rbRetVal;
|
273
|
+
}
|
274
|
+
|
275
|
+
VALUE AlsaOutput::wrapPrepare( VALUE rbSelf )
|
276
|
+
{
|
277
|
+
try {
|
278
|
+
AlsaOutputPtr *self; Data_Get_Struct( rbSelf, AlsaOutputPtr, self );
|
279
|
+
(*self)->prepare();
|
280
|
+
} catch ( exception &e ) {
|
281
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
282
|
+
};
|
283
|
+
return rbSelf;
|
284
|
+
}
|
285
|
+
|