hornetseye-alsa 1.0.0 → 1.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/COPYING +1 -1
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/ext/alsaoutput.cc +160 -99
- data/ext/alsaoutput.hh +19 -10
- data/lib/hornetseye-alsa/alsaoutput.rb +3 -6
- metadata +4 -4
data/COPYING
CHANGED
data/README.md
CHANGED
data/Rakefile
CHANGED
data/ext/alsaoutput.cc
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* HornetsEye - Computer Vision with Ruby
|
2
|
-
Copyright (C)
|
2
|
+
Copyright (C) 2012 Jan Wedekind
|
3
3
|
|
4
4
|
This program is free software: you can redistribute it and/or modify
|
5
5
|
it under the terms of the GNU General Public License as published by
|
@@ -19,46 +19,52 @@ using namespace std;
|
|
19
19
|
|
20
20
|
VALUE AlsaOutput::cRubyClass = Qnil;
|
21
21
|
|
22
|
-
AlsaOutput::AlsaOutput(
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
AlsaOutput::AlsaOutput(const string &pcmName, unsigned int rate,
|
23
|
+
unsigned int channels) throw (Error):
|
24
|
+
m_pcmHandle(NULL), m_pcmName(pcmName), m_rate(rate), m_channels(channels),
|
25
|
+
m_periodSize(1024), m_threadInitialised(false), m_start(0), m_count(0),
|
26
|
+
m_size(rate)
|
26
27
|
{
|
27
28
|
try {
|
28
29
|
snd_pcm_hw_params_t *hwParams;
|
29
|
-
snd_pcm_hw_params_alloca(
|
30
|
-
int err = snd_pcm_open(
|
31
|
-
|
32
|
-
ERRORMACRO(
|
33
|
-
|
34
|
-
err = snd_pcm_hw_params_any(
|
35
|
-
ERRORMACRO(
|
36
|
-
|
37
|
-
err = snd_pcm_hw_params_set_access(
|
38
|
-
|
39
|
-
ERRORMACRO(
|
40
|
-
|
41
|
-
err = snd_pcm_hw_params_set_format(
|
42
|
-
|
43
|
-
|
44
|
-
<< "\" to 16-bit signed integer format: " << snd_strerror( err ) );
|
30
|
+
snd_pcm_hw_params_alloca(&hwParams);
|
31
|
+
int err = snd_pcm_open(&m_pcmHandle, m_pcmName.c_str(), SND_PCM_STREAM_PLAYBACK,
|
32
|
+
0);//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, SND_PCM_FORMAT_S16_LE);
|
43
|
+
ERRORMACRO(err >= 0, Error, , "Error setting PCM device \"" << m_pcmName
|
44
|
+
<< "\" to 16-bit signed integer format: " << snd_strerror(err));
|
45
45
|
err = snd_pcm_hw_params_set_rate_near( m_pcmHandle, hwParams, &m_rate, 0 );
|
46
|
-
ERRORMACRO(
|
47
|
-
|
48
|
-
err = snd_pcm_hw_params_set_channels(
|
49
|
-
ERRORMACRO(
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
46
|
+
ERRORMACRO(err >= 0, Error, , "Error setting sampling rate of PCM device \""
|
47
|
+
<< m_pcmName << "\" to " << rate << " Hz: " << snd_strerror(err));
|
48
|
+
err = snd_pcm_hw_params_set_channels(m_pcmHandle, hwParams, channels);
|
49
|
+
ERRORMACRO(err >= 0, Error, , "Error setting number of channels of PCM device \""
|
50
|
+
<< m_pcmName << "\" to " << channels << ": " << snd_strerror(err));
|
51
|
+
unsigned int bufferTime = 500000;
|
52
|
+
err = snd_pcm_hw_params_set_buffer_time_near(m_pcmHandle, hwParams, &bufferTime, NULL);
|
53
|
+
ERRORMACRO(err >= 0, Error, , "Error setting buffer time of PCM device \""
|
54
|
+
<< m_pcmName << "\" to " << bufferTime << " us: " << snd_strerror(err));
|
55
|
+
unsigned int periods = 16;
|
56
|
+
err = snd_pcm_hw_params_set_periods_near(m_pcmHandle, hwParams, &periods, NULL);
|
57
|
+
ERRORMACRO(err >= 0, Error, , "Error setting periods of PCM device \""
|
58
|
+
<< m_pcmName << "\" to " << periods << ": " << snd_strerror(err));
|
58
59
|
err = snd_pcm_hw_params( m_pcmHandle, hwParams );
|
59
60
|
ERRORMACRO( err >= 0, Error, , "Error setting parameters of PCM device \""
|
60
61
|
<< m_pcmName << "\": " << snd_strerror( err ) );
|
61
|
-
|
62
|
+
err = snd_pcm_hw_params_get_period_size(hwParams, &m_periodSize, NULL);
|
63
|
+
ERRORMACRO( err >= 0, Error, , "Error getting period size of PCM device \""
|
64
|
+
<< m_pcmName << "\": " << snd_strerror( err ) );
|
65
|
+
err = pthread_mutex_init(&m_mutex, NULL);
|
66
|
+
ERRORMACRO(err == 0, Error, , "Error initialising mutex: " << strerror(err));
|
67
|
+
} catch (Error &e) {
|
62
68
|
close();
|
63
69
|
throw e;
|
64
70
|
};
|
@@ -72,40 +78,71 @@ AlsaOutput::~AlsaOutput(void)
|
|
72
78
|
void AlsaOutput::close(void)
|
73
79
|
{
|
74
80
|
if ( m_pcmHandle != NULL ) {
|
75
|
-
|
81
|
+
drain();
|
82
|
+
pthread_mutex_destroy(&m_mutex);
|
76
83
|
snd_pcm_close( m_pcmHandle );
|
77
84
|
m_pcmHandle = NULL;
|
78
85
|
};
|
79
86
|
}
|
80
87
|
|
81
|
-
void AlsaOutput::write(
|
88
|
+
void AlsaOutput::write(SequencePtr frame) throw (Error)
|
82
89
|
{
|
83
|
-
ERRORMACRO(
|
84
|
-
|
85
|
-
int n = frame->size() / (
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
ERRORMACRO(m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
91
|
+
<< "\" is not open. Did you call \"close\" before?");
|
92
|
+
int n = frame->size() / (2 * m_channels);
|
93
|
+
lock();
|
94
|
+
if (!m_data.get()) {
|
95
|
+
if (m_threadInitialised) pthread_detach(m_thread);
|
96
|
+
while(m_size < n) m_size = 2 * m_size;
|
97
|
+
m_data = boost::shared_array<short int>(new short int[m_size * m_channels]);
|
98
|
+
m_start = 0;
|
99
|
+
m_count = 0;
|
100
|
+
pthread_create(&m_thread, NULL, staticThreadFunc, this);
|
101
|
+
};
|
102
|
+
if (m_count + n > m_size) {
|
103
|
+
int m_size_new = m_size;
|
104
|
+
while(m_size_new < m_count + n) m_size_new = 2 * m_size_new;
|
105
|
+
boost::shared_array<short int> data(new short int[m_size_new * m_channels]);
|
106
|
+
if (m_start + m_count > m_size) {
|
107
|
+
memcpy(data.get(), m_data.get() + m_start * m_channels, (m_size - m_start) * 2 * m_channels);
|
108
|
+
memcpy(data.get() + (m_size - m_start) * m_channels, m_data.get(), (m_start + m_count - m_size) * 2 * m_channels);
|
109
|
+
} else
|
110
|
+
memcpy(data.get(), m_data.get() + m_start * m_channels, m_count * 2 * m_channels);
|
111
|
+
m_data = data;
|
112
|
+
m_start = 0;
|
113
|
+
m_size = m_size_new;
|
92
114
|
};
|
93
|
-
|
94
|
-
|
115
|
+
int offset = m_start + m_count;
|
116
|
+
if (offset > m_size) offset -= m_size;
|
117
|
+
if (offset + n > m_size) {
|
118
|
+
memcpy(m_data.get() + offset * m_channels, frame->data(), (m_size - offset) * 2 * m_channels);
|
119
|
+
memcpy(m_data.get(), frame->data() + (m_size - offset) * m_channels, (n + m_size - offset) * 2 * m_channels);
|
120
|
+
} else
|
121
|
+
memcpy(m_data.get() + offset * m_channels, frame->data(), n * 2 * m_channels);
|
122
|
+
m_count += n;
|
123
|
+
unlock();
|
95
124
|
}
|
96
125
|
|
97
126
|
void AlsaOutput::drop(void) throw (Error)
|
98
127
|
{
|
99
128
|
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
100
129
|
<< "\" is not open. Did you call \"close\" before?" );
|
101
|
-
|
130
|
+
lock();
|
131
|
+
m_data.reset();
|
132
|
+
m_count = 0;
|
133
|
+
unlock();
|
134
|
+
snd_pcm_drop(m_pcmHandle);
|
102
135
|
}
|
103
136
|
|
104
137
|
void AlsaOutput::drain(void) throw (Error)
|
105
138
|
{
|
106
|
-
|
107
|
-
|
108
|
-
|
139
|
+
if (m_threadInitialised) {
|
140
|
+
pthread_join(m_thread, NULL);
|
141
|
+
m_threadInitialised = false;
|
142
|
+
}
|
143
|
+
ERRORMACRO(m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
144
|
+
<< "\" is not open. Did you call \"close\" before?");
|
145
|
+
snd_pcm_drain(m_pcmHandle);
|
109
146
|
}
|
110
147
|
|
111
148
|
unsigned int AlsaOutput::rate(void)
|
@@ -120,8 +157,6 @@ unsigned int AlsaOutput::channels(void)
|
|
120
157
|
|
121
158
|
int AlsaOutput::avail(void) throw (Error)
|
122
159
|
{
|
123
|
-
ERRORMACRO( m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
124
|
-
<< "\" is not open. Did you call \"close\" before?" );
|
125
160
|
snd_pcm_sframes_t frames;
|
126
161
|
int err = 0;
|
127
162
|
while ( ( frames = snd_pcm_avail( m_pcmHandle ) ) < 0 ) {
|
@@ -135,42 +170,94 @@ int AlsaOutput::avail(void) throw (Error)
|
|
135
170
|
|
136
171
|
int AlsaOutput::delay(void) throw (Error)
|
137
172
|
{
|
138
|
-
ERRORMACRO(
|
139
|
-
|
173
|
+
ERRORMACRO(m_pcmHandle != NULL, Error, , "PCM device \"" << m_pcmName
|
174
|
+
<< "\" is not open. Did you call \"close\" before?");
|
175
|
+
lock();
|
140
176
|
snd_pcm_sframes_t frames;
|
141
177
|
int err;
|
142
|
-
while (
|
143
|
-
err = snd_pcm_recover(
|
144
|
-
|
145
|
-
|
146
|
-
|
178
|
+
while ((err = snd_pcm_delay(m_pcmHandle, &frames)) < 0) {
|
179
|
+
err = snd_pcm_recover(m_pcmHandle, err, 1);
|
180
|
+
if (err < 0) {
|
181
|
+
unlock();
|
182
|
+
ERRORMACRO(false, Error, , "Error querying number of available frames for "
|
183
|
+
"update of PCM device \"" << m_pcmName << "\": "
|
184
|
+
<< snd_strerror(err));
|
185
|
+
};
|
147
186
|
};
|
187
|
+
frames += m_count;
|
188
|
+
unlock();
|
148
189
|
return frames;
|
149
190
|
}
|
150
191
|
|
151
|
-
void AlsaOutput::
|
192
|
+
void AlsaOutput::lock(void)
|
152
193
|
{
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
194
|
+
pthread_mutex_lock( &m_mutex );
|
195
|
+
}
|
196
|
+
|
197
|
+
void AlsaOutput::unlock(void)
|
198
|
+
{
|
199
|
+
pthread_mutex_unlock( &m_mutex );
|
200
|
+
}
|
201
|
+
|
202
|
+
void AlsaOutput::writei(short int *data, int count) throw (Error)
|
203
|
+
{
|
204
|
+
int err;
|
205
|
+
while ((err = snd_pcm_writei(m_pcmHandle, data, count)) < 0) {
|
206
|
+
err = snd_pcm_recover(m_pcmHandle, err, 1);
|
207
|
+
ERRORMACRO(err >= 0, Error, , "Error writing audio frames to PCM device \""
|
208
|
+
<< m_pcmName << "\": " << snd_strerror(err));
|
209
|
+
};
|
210
|
+
ERRORMACRO(count == err, Error, , "Only managed to write " << err << " of " << count
|
211
|
+
<< " frames to PCM device \"" << m_pcmName << "\"");
|
212
|
+
}
|
213
|
+
|
214
|
+
void AlsaOutput::threadFunc(void)
|
215
|
+
{
|
216
|
+
bool quit = false;
|
217
|
+
while (!quit) {
|
218
|
+
try {
|
219
|
+
lock();
|
220
|
+
int n = m_periodSize;
|
221
|
+
if (n > m_count) n = m_count;
|
222
|
+
if (m_count <= 0) m_data.reset();
|
223
|
+
if (m_start >= m_size) m_start -= m_size;
|
224
|
+
if (m_data.get()) {
|
225
|
+
if (m_start + n > m_size) {
|
226
|
+
writei(m_data.get() + m_start * m_channels, m_size - m_start);
|
227
|
+
writei(m_data.get(), m_start + n - m_size);
|
228
|
+
} else {
|
229
|
+
writei(m_data.get() + m_start * m_channels, n);
|
230
|
+
};
|
231
|
+
m_start += n;
|
232
|
+
m_count -= n;
|
233
|
+
} else
|
234
|
+
quit = true;
|
235
|
+
unlock();
|
236
|
+
snd_pcm_wait(m_pcmHandle, 1000);
|
237
|
+
} catch (Error &e) {
|
238
|
+
quit = true;
|
239
|
+
unlock();
|
240
|
+
}
|
241
|
+
};
|
242
|
+
}
|
243
|
+
|
244
|
+
void *AlsaOutput::staticThreadFunc( void *self )
|
245
|
+
{
|
246
|
+
((AlsaOutput *)self)->threadFunc();
|
247
|
+
return self;
|
158
248
|
}
|
159
249
|
|
160
250
|
VALUE AlsaOutput::registerRubyClass( VALUE rbModule )
|
161
251
|
{
|
162
252
|
cRubyClass = rb_define_class_under( rbModule, "AlsaOutput", rb_cObject );
|
163
|
-
rb_define_singleton_method(
|
164
|
-
RUBY_METHOD_FUNC( wrapNew ), 5 );
|
253
|
+
rb_define_singleton_method(cRubyClass, "new", RUBY_METHOD_FUNC(wrapNew), 3);
|
165
254
|
rb_define_method( cRubyClass, "close", RUBY_METHOD_FUNC( wrapClose ), 0 );
|
166
255
|
rb_define_method( cRubyClass, "write", RUBY_METHOD_FUNC( wrapWrite ), 1 );
|
167
256
|
rb_define_method( cRubyClass, "drop", RUBY_METHOD_FUNC( wrapDrop ), 0 );
|
168
257
|
rb_define_method( cRubyClass, "drain", RUBY_METHOD_FUNC( wrapDrain ), 0 );
|
169
258
|
rb_define_method( cRubyClass, "rate", RUBY_METHOD_FUNC( wrapRate ), 0 );
|
170
259
|
rb_define_method( cRubyClass, "channels", RUBY_METHOD_FUNC( wrapChannels ), 0 );
|
171
|
-
rb_define_method( cRubyClass, "avail", RUBY_METHOD_FUNC( wrapAvail ), 0 );
|
172
260
|
rb_define_method( cRubyClass, "delay", RUBY_METHOD_FUNC( wrapDelay ), 0 );
|
173
|
-
rb_define_method( cRubyClass, "prepare", RUBY_METHOD_FUNC( wrapPrepare ), 0 );
|
174
261
|
}
|
175
262
|
|
176
263
|
void AlsaOutput::deleteRubyObject( void *ptr )
|
@@ -178,15 +265,13 @@ void AlsaOutput::deleteRubyObject( void *ptr )
|
|
178
265
|
delete (AlsaOutputPtr *)ptr;
|
179
266
|
}
|
180
267
|
|
181
|
-
VALUE AlsaOutput::wrapNew(
|
182
|
-
VALUE rbChannels, VALUE rbPeriods, VALUE rbFrames )
|
268
|
+
VALUE AlsaOutput::wrapNew(VALUE rbClass, VALUE rbPCMName, VALUE rbRate, VALUE rbChannels)
|
183
269
|
{
|
184
270
|
VALUE retVal = Qnil;
|
185
271
|
try {
|
186
272
|
rb_check_type( rbPCMName, T_STRING );
|
187
|
-
AlsaOutputPtr ptr(
|
188
|
-
|
189
|
-
NUM2INT( rbPeriods ), NUM2INT( rbFrames ) ) );
|
273
|
+
AlsaOutputPtr ptr(new AlsaOutput(StringValuePtr(rbPCMName),
|
274
|
+
NUM2UINT(rbRate), NUM2UINT(rbChannels)));
|
190
275
|
retVal = Data_Wrap_Struct( rbClass, 0, deleteRubyObject,
|
191
276
|
new AlsaOutputPtr( ptr ) );
|
192
277
|
} catch ( exception &e ) {
|
@@ -248,18 +333,6 @@ VALUE AlsaOutput::wrapChannels( VALUE rbSelf )
|
|
248
333
|
return UINT2NUM( (*self)->channels() );
|
249
334
|
}
|
250
335
|
|
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
336
|
VALUE AlsaOutput::wrapDelay( VALUE rbSelf )
|
264
337
|
{
|
265
338
|
VALUE rbRetVal = Qnil;
|
@@ -271,15 +344,3 @@ VALUE AlsaOutput::wrapDelay( VALUE rbSelf )
|
|
271
344
|
};
|
272
345
|
return rbRetVal;
|
273
346
|
}
|
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
|
-
|
data/ext/alsaoutput.hh
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
/* HornetsEye - Computer Vision with Ruby
|
2
|
-
Copyright (C)
|
2
|
+
Copyright (C) 2012 Jan Wedekind
|
3
3
|
|
4
4
|
This program is free software: you can redistribute it and/or modify
|
5
5
|
it under the terms of the GNU General Public License as published by
|
@@ -25,9 +25,8 @@
|
|
25
25
|
class AlsaOutput
|
26
26
|
{
|
27
27
|
public:
|
28
|
-
AlsaOutput(
|
29
|
-
|
30
|
-
int periods = 16, snd_pcm_uframes_t frames = 1024 ) throw (Error);
|
28
|
+
AlsaOutput(const std::string &pcmName = "default:0",
|
29
|
+
unsigned int rate = 48000, unsigned int channels = 2) throw (Error);
|
31
30
|
virtual ~AlsaOutput(void);
|
32
31
|
void close(void);
|
33
32
|
void write( SequencePtr sequence ) throw (Error);
|
@@ -35,28 +34,38 @@ public:
|
|
35
34
|
void drain(void) throw (Error);
|
36
35
|
unsigned int rate(void);
|
37
36
|
unsigned int channels(void);
|
38
|
-
int avail(void) throw (Error);
|
39
37
|
int delay(void) throw (Error);
|
40
|
-
void
|
38
|
+
void lock(void);
|
39
|
+
void unlock(void);
|
41
40
|
static VALUE cRubyClass;
|
42
41
|
static VALUE registerRubyClass( VALUE rbModule );
|
43
42
|
static void deleteRubyObject( void *ptr );
|
44
|
-
static VALUE wrapNew(
|
45
|
-
|
43
|
+
static VALUE wrapNew(VALUE rbClass, VALUE rbPCMName, VALUE rbRate,
|
44
|
+
VALUE rbChannels);
|
46
45
|
static VALUE wrapClose( VALUE rbSelf );
|
47
46
|
static VALUE wrapWrite( VALUE rbSelf, VALUE rbSequence );
|
48
47
|
static VALUE wrapDrop( VALUE rbSelf );
|
49
48
|
static VALUE wrapDrain( VALUE rbSelf );
|
50
49
|
static VALUE wrapRate( VALUE rbSelf );
|
51
50
|
static VALUE wrapChannels( VALUE rbSelf );
|
52
|
-
static VALUE wrapAvail( VALUE rbSelf );
|
53
51
|
static VALUE wrapDelay( VALUE rbSelf );
|
54
|
-
static VALUE wrapPrepare( VALUE rbSelf );
|
55
52
|
protected:
|
53
|
+
int avail(void) throw (Error);
|
54
|
+
void writei(short int *data, int count) throw (Error);
|
55
|
+
void threadFunc(void);
|
56
|
+
static void *staticThreadFunc( void *self );
|
56
57
|
snd_pcm_t *m_pcmHandle;
|
57
58
|
std::string m_pcmName;
|
58
59
|
unsigned int m_rate;
|
59
60
|
unsigned int m_channels;
|
61
|
+
snd_pcm_uframes_t m_periodSize;
|
62
|
+
bool m_threadInitialised;
|
63
|
+
boost::shared_array<short int> m_data;
|
64
|
+
int m_start;
|
65
|
+
int m_count;
|
66
|
+
int m_size;
|
67
|
+
pthread_t m_thread;
|
68
|
+
pthread_mutex_t m_mutex;
|
60
69
|
};
|
61
70
|
|
62
71
|
typedef boost::shared_ptr< AlsaOutput > AlsaOutputPtr;
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# hornetseye-alsa - Play audio data using libalsa
|
2
|
-
# Copyright (C)
|
2
|
+
# Copyright (C) 2012 Jan Wedekind
|
3
3
|
#
|
4
4
|
# This program is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -45,14 +45,11 @@ module Hornetseye
|
|
45
45
|
# @param [String] pcm_name Name of the PCM device
|
46
46
|
# @param [Integer] rate Desired sampling rate.
|
47
47
|
# @param [Integer] channels Number of channels (1=mono, 2=stereo).
|
48
|
-
# @param [Integer] periods Number of audio frames of the output buffer.
|
49
|
-
# @param [Integer] frames Size of the audio frames of the output buffer.
|
50
48
|
# @return [AlsaOutput] An object for accessing the speakers.
|
51
49
|
#
|
52
50
|
# @see #rate
|
53
|
-
def new(
|
54
|
-
|
55
|
-
orig_new pcm_name, rate, channels, periods, frames
|
51
|
+
def new(pcm_name = 'default', rate = 48000, channels = 2)
|
52
|
+
orig_new pcm_name, rate, channels
|
56
53
|
end
|
57
54
|
|
58
55
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hornetseye-alsa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jan Wedekind
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-11-
|
18
|
+
date: 2012-11-13 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: malloc
|