1
// -------------------------------------------------------------------------
3
// Copyright (C) 2004-2013 Fons Adriaensen <fons@linuxaudio.org>
5
// This program is free software; you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation; either version 2 of the License, or
8
// (at your option) any later version.
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
// GNU General Public License for more details.
15
// You should have received a copy of the GNU General Public License
16
// along with this program; if not, write to the Free Software
17
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
// -------------------------------------------------------------------------
27
Audio::Audio (ITC_ctrl *cmain, const char *name) :
28
A_thread ("Audio"), _jname (name), _cmain (cmain), _run_alsa (0), _run_jack (0),
42
if (_run_alsa) close_alsa ();
43
if (_run_jack) close_jack ();
49
void Audio::init (void)
52
_b0 = _b1 = _b2 = _b3 = _b4 = _b5 = _b6 = 0.0f;
56
void Audio::init_alsa (const char *playdev, const char *captdev,
57
int fsamp, int fsize, int nfrags)
60
_alsa_handle = new Alsa_pcmi (playdev, captdev, 0, fsamp, fsize, nfrags);
61
if (_alsa_handle->state () < 0)
63
fprintf (stderr, "Can't connect to ALSA\n");
66
_ncapt = _alsa_handle->ncapt ();
67
_nplay = _alsa_handle->nplay ();
73
_out1 = new float [fsize];
74
_out2 = new float [fsize];
79
_cmain->put_event (EV_MESG, new M_audio (fsamp, _ncapt, _nplay, _jname));
80
_alsa_handle->printinfo ();
81
fprintf (stderr, "Connected to ALSA with %d inputs and %d outputs\n", _ncapt, _nplay);
83
if (thr_start (SCHED_FIFO, -10, 0x00010000))
85
fprintf (stderr, "Can't create ALSA thread with RT priority\n");
86
if (thr_start (SCHED_OTHER, 0, 0x00010000))
88
fprintf (stderr, "Can't create ALSA thread\n");
95
void Audio::close_alsa ()
97
// fprintf (stderr, "Closing ALSA...\n");
99
get_event (1 << EV_EXIT);
104
void Audio::thr_main (void)
106
unsigned long k, m, n;
108
_alsa_handle->pcm_start ();
112
k = _alsa_handle->pcm_wait ();
117
_alsa_handle->capt_init (_fsize);
125
if (_inputA < 0) memset (_dataA + _dind, 0, n * sizeof (float));
126
else _alsa_handle->capt_chan (_inputA, _dataA + _dind, n);
127
if (_inputB < 0) memset (_dataB + _dind, 0, n * sizeof (float));
130
if (_inputB == _inputA) memcpy (_dataB + _dind, _dataA + _dind, n * sizeof (float));
131
else _alsa_handle->capt_chan (_inputB, _dataB + _dind, n);
138
if (_inputA < 0) memset (_dataA + _dind, 0, m * sizeof (float));
139
else _alsa_handle->capt_chan (_inputA, _dataA + _dind, m);
140
if (_inputB < 0) memset (_dataB + _dind, 0, m * sizeof (float));
143
if (_inputB == _inputA) memcpy (_dataB + _dind, _dataA + _dind, m * sizeof (float));
144
else _alsa_handle->capt_chan (_inputB, _dataB + _dind, m);
150
_alsa_handle->capt_done (_fsize);
155
_alsa_handle->play_init (_fsize);
159
gen_noise (_fsize, _out1, _out2);
160
_alsa_handle->play_chan (0, _out1, _fsize);
161
_alsa_handle->play_chan (1, _out2, _fsize);
164
_alsa_handle->play_done (_fsize);
173
_alsa_handle->pcm_stop ();
178
void Audio::init_jack (const char *server)
184
opts = JackNoStartServer;
185
if (server) opts |= JackServerName;
186
_jack_handle = jack_client_open (_jname, (jack_options_t)opts, &stat, server);
189
fprintf (stderr, "Can't connect to JACK\n");
193
jack_set_process_callback (_jack_handle, jack_static_callback, (void *)this);
194
jack_on_shutdown (_jack_handle, jack_static_shutdown, (void *)this);
196
if (jack_activate (_jack_handle))
198
fprintf(stderr, "Can't activate JACK");
204
for (int i = 0; i < _ncapt; i++)
206
sprintf(s, "in_%d", i + 1);
207
_jack_in [i] = jack_port_register (_jack_handle, s, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
211
_jack_out [0] = jack_port_register (_jack_handle, "white", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
212
_jack_out [1] = jack_port_register (_jack_handle, "pink", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
216
_fsamp = jack_get_sample_rate (_jack_handle);
217
_fsize = jack_get_buffer_size (_jack_handle);
218
_jname = jack_get_client_name (_jack_handle);
219
_cmain->put_event (EV_MESG, new M_audio (_fsamp, _ncapt, _nplay, _jname));
224
void Audio::close_jack ()
226
jack_deactivate (_jack_handle);
227
jack_client_close (_jack_handle);
231
void Audio::jack_static_shutdown (void *arg)
233
return ((Audio *) arg)->jack_shutdown ();
237
void Audio::jack_shutdown (void)
239
_cmain->put_event (EV_JACK);
243
int Audio::jack_static_callback (jack_nframes_t nframes, void *arg)
245
return ((Audio *) arg)->jack_callback (nframes);
249
int Audio::jack_callback (jack_nframes_t nframes)
254
if (!_active) return 0;
257
pA = (_inputA >= 0) ? (float *)(jack_port_get_buffer (_jack_in [_inputA], nframes)) : 0;
258
pB = (_inputB >= 0) ? (float *)(jack_port_get_buffer (_jack_in [_inputB], nframes)) : 0;
265
memcpy (_dataA + _dind, pA, sizeof(float) * n);
268
else memset (_dataA + _dind, 0, sizeof(float) * n);
271
memcpy (_dataB + _dind, pB, sizeof(float) * n);
274
else memset (_dataB + _dind, 0, sizeof(float) * n);
281
if (pA) memcpy (_dataA + _dind, pA, sizeof(float) * m);
282
else memset (_dataA + _dind, 0, sizeof(float) * m);
283
if (pB) memcpy (_dataB + _dind, pB, sizeof(float) * m);
284
else memset (_dataB + _dind, 0, sizeof(float) * m);
291
(float *)(jack_port_get_buffer (_jack_out [0], nframes)),
292
(float *)(jack_port_get_buffer (_jack_out [1], nframes)));
300
void Audio::gen_noise (int n, float *op1, float *op2 )
306
x = _rngen.grandf ();
307
*op1++ = 0.07071f * x;
309
_b0 = 0.99886f * _b0 + 0.0555179f * x;
310
_b1 = 0.99332f * _b1 + 0.0750759f * x;
311
_b2 = 0.96900f * _b2 + 0.1538520f * x;
312
_b3 = 0.86650f * _b3 + 0.3104856f * x;
313
_b4 = 0.55000f * _b4 + 0.5329522f * x;
314
_b5 = -0.7616f * _b5 - 0.0168980f * x;
315
*op2++ = _b0 + _b1 + _b2 + _b3 + _b4 + _b5 + _b6 + x * 0.5362f;
321
void Audio::get_messages (void)
329
if (k && _cmain->put_event_try (EV_TRIG, k) == ITC_ctrl::NO_ERROR) _scnt -= k * _step;
332
if (get_event_nowait (1 << EV_MESG) == EV_MESG)
335
if (M->type () == MT_BUFFP)
337
M_buffp *Z = (M_buffp *) M;
345
else if (M->type () == MT_INPUT)
347
M_input *Z = (M_input *) M;
348
_inputA = Z->_inputA;
349
_inputB = Z->_inputB;
350
if (_inputA >= _ncapt) _inputA = -1;
351
if (_inputB >= _ncapt) _inputB = -1;