summaryrefslogtreecommitdiff
path: root/tools/zalsa
diff options
context:
space:
mode:
Diffstat (limited to 'tools/zalsa')
-rw-r--r--tools/zalsa/alsathread.cc226
-rw-r--r--tools/zalsa/alsathread.h68
-rw-r--r--tools/zalsa/jackclient.cc549
-rw-r--r--tools/zalsa/jackclient.h120
-rw-r--r--tools/zalsa/lfqueue.cc89
-rw-r--r--tools/zalsa/lfqueue.h182
-rw-r--r--tools/zalsa/pxthread.cc87
-rw-r--r--tools/zalsa/pxthread.h53
-rw-r--r--tools/zalsa/timers.h53
-rw-r--r--tools/zalsa/zita-a2j.cc409
-rw-r--r--tools/zalsa/zita-j2a.cc408
11 files changed, 0 insertions, 2244 deletions
diff --git a/tools/zalsa/alsathread.cc b/tools/zalsa/alsathread.cc
deleted file mode 100644
index bb5cf75b..00000000
--- a/tools/zalsa/alsathread.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include "alsathread.h"
-#include "timers.h"
-
-
-Alsathread::Alsathread (Alsa_pcmi *alsadev, int mode) :
- _alsadev (alsadev ),
- _mode (mode),
- _state (INIT),
- _fsize (alsadev->fsize ()),
- _audioq (0),
- _commq (0),
- _alsaq (0)
-{
- // Compute DLL filter coefficients.
- _dt = (double) _fsize / _alsadev->fsamp ();
- _w1 = 2 * M_PI * 0.1 * _dt;
- _w2 = _w1 * _w1;
- _w1 *= 1.6;
-}
-
-
-Alsathread::~Alsathread (void)
-{
- if (_state != INIT)
- {
- _state = TERM;
- thr_wait ();
- }
- else
- {
- _alsadev->pcm_stop ();
- }
-}
-
-
-int Alsathread::start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio)
-{
- // Start the ALSA thread.
- _audioq = audioq;
- _commq = commq;
- _alsaq = alsaq;
- _state = WAIT;
- if (thr_start (SCHED_FIFO, rtprio, 0x10000)) return 1;
- return 0;
-}
-
-
-void Alsathread::send (int k, double t)
-{
- Adata *D;
-
- // Send (state, frame count, timestamp) to Jack thread.
- if (_alsaq->wr_avail ())
- {
- D = _alsaq->wr_datap ();
- D->_state = _state;
- D->_nsamp = k;
- D->_timer = t;
- _alsaq->wr_commit ();
- }
-}
-
-
-// The following two functions transfer data between the audio queue
-// and the ALSA device. Note that we do *not* check the queue's fill
-// state, and it may overrun or underrun. It actually will in the first
-// few iterations and in error conditions. This is entirely intentional.
-// The queue keeps correct read and write counters even in that case,
-// and the main control loop and error recovery depend on it working
-// and being used in this way.
-
-int Alsathread::capture (void)
-{
- int c, n, k;
- float *p;
-
- // Start reading from ALSA device.
- _alsadev->capt_init (_fsize);
- if (_state == PROC)
- {
- // Input frames from the ALSA device to the audio queue.
- // The outer loop takes care of wraparound.
- for (n = _fsize; n; n -= k)
- {
- p = _audioq->wr_datap (); // Audio queue write pointer.
- k = _audioq->wr_linav (); // Number of frames that can be
- if (k > n) k = n; // written without wraparound.
- for (c = 0; c < _audioq->nchan (); c++)
- {
- // Copy and interleave one channel.
- _alsadev->capt_chan (c, p + c, k, _audioq->nchan ());
- }
- _audioq->wr_commit (k); // Update audio queue state.
- }
- }
- // Finish reading from ALSA device.
- _alsadev->capt_done (_fsize);
- return _fsize;
-}
-
-
-int Alsathread::playback (void)
-{
- int c, n, k;
- float *p;
-
- // Start writing to ALSA device.
- _alsadev->play_init (_fsize);
- c = 0;
- if (_state == PROC)
- {
- // Output frames from the audio queue to the ALSA device.
- // The outer loop takes care of wraparound.
- for (n = _fsize; n; n -= k)
- {
- p = _audioq->rd_datap (); // Audio queue read pointer.
- k = _audioq->rd_linav (); // Number of frames that can
- if (k > n) k = n; // be read without wraparound.
- for (c = 0; c < _audioq->nchan (); c++)
- {
- // De-interleave and copy one channel.
- _alsadev->play_chan (c, p + c, k, _audioq->nchan ());
- }
- _audioq->rd_commit (k); // Update audio queue state.
- }
- }
- // Clear all or remaining channels.
- while (c < _alsadev->nplay ()) _alsadev->clear_chan (c++, _fsize);
- // Finish writing to ALSA device.
- _alsadev->play_done (_fsize);
- return _fsize;
-}
-
-
-void Alsathread::thr_main (void)
-{
- int na, nu;
- double tw, er;
-
- _alsadev->pcm_start ();
- while (_state != TERM)
- {
- // Wait for next cycle, then take timestamp.
- na = _alsadev->pcm_wait ();
-
- tw = tjack (jack_get_time ());
- // Check for errors - requires restart.
- if (_alsadev->state () && (na == 0))
- {
- _state = WAIT;
- send (0, 0);
- usleep (10000);
- continue;
- }
-
- // Check for commands from the Jack thread.
- if (_commq->rd_avail ())
- {
- _state = _commq->rd_int32 ();
- if (_state == PROC) _first = true;
- if (_state == TERM) send (0, 0);
- }
-
- // We could have more than one period.
- nu = 0;
- while (na >= _fsize)
- {
- // Transfer frames.
- if (_mode == PLAY) nu += playback ();
- else nu += capture ();
- // Update loop condition.
- na -= _fsize;
- // Run the DLL if in PROC state.
- if (_state == PROC)
- {
- if (_first)
- {
- // Init DLL in first iteration.
- _first = false;
- _dt = (double) _fsize / _alsadev->fsamp ();
- _t0 = tw;
- _t1 = tw + _dt;
- }
- else
- {
- // Update the DLL.
- // If we have more than one period, use
- // the time error only for the last one.
- if (na >= _fsize) er = 0;
- else er = tjack_diff (tw, _t1);
- _t0 = _t1;
- _t1 = tjack_diff (_t1 + _dt + _w1 * er, 0.0);
- _dt += _w2 * er;
- }
- }
- }
-
- // Send number of frames used and timestamp to Jack thread.
- if (_state == PROC) send (nu, _t1);
- }
- _alsadev->pcm_stop ();
-}
diff --git a/tools/zalsa/alsathread.h b/tools/zalsa/alsathread.h
deleted file mode 100644
index f9cb761c..00000000
--- a/tools/zalsa/alsathread.h
+++ /dev/null
@@ -1,68 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#ifndef __ALSATHREAD_H
-#define __ALSATHREAD_H
-
-
-#include <zita-alsa-pcmi.h>
-#include "jack/jack.h"
-#include "pxthread.h"
-#include "lfqueue.h"
-
-
-class Alsathread : public Pxthread
-{
-public:
-
- enum { INIT, WAIT, PROC, TERM };
- enum { PLAY, CAPT };
-
- Alsathread (Alsa_pcmi *alsadev, int mode);
- virtual ~Alsathread (void);
- virtual void thr_main (void);
-
- int start (Lfq_audio *audioq, Lfq_int32 *commq, Lfq_adata *alsaq, int rtprio);
-
-private:
-
- void send (int k, double t);
- int capture (void);
- int playback (void);
-
- Alsa_pcmi *_alsadev;
- int _mode;
- int _state;
- int _nfail;
- int _fsize;
- Lfq_audio *_audioq;
- Lfq_int32 *_commq;
- Lfq_adata *_alsaq;
- bool _first;
-// double _jtmod;
- double _t0;
- double _t1;
- double _dt;
- double _w1;
- double _w2;
-};
-
-
-#endif
diff --git a/tools/zalsa/jackclient.cc b/tools/zalsa/jackclient.cc
deleted file mode 100644
index 095b2632..00000000
--- a/tools/zalsa/jackclient.cc
+++ /dev/null
@@ -1,549 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include <stdio.h>
-#include <math.h>
-#include "jackclient.h"
-#include "alsathread.h"
-#include "timers.h"
-
-
-Jackclient::Jackclient (jack_client_t* cl, const char *jserv, int mode, int nchan, bool sync, void *arg) :
- _client (cl),
- _arg (arg),
- _mode (mode),
- _nchan (nchan),
- _state (INIT),
- _freew (false),
- _resamp (0)
-{
- init (jserv);
- if (!sync) _resamp = new VResampler ();
-}
-
-
-Jackclient::~Jackclient (void)
-{
- fini ();
-}
-
-
-bool Jackclient::init (const char *jserv)
-{
- int i, spol, flags;
- char s [64];
- struct sched_param spar;
-
- if (_client == 0)
- {
- fprintf (stderr, "Can't connect to Jack, is the server running ?\n");
- return false;
- }
- jack_set_process_callback (_client, jack_static_process, (void *) this);
- jack_set_latency_callback (_client, jack_static_latency, (void *) this);
- jack_set_freewheel_callback (_client, jack_static_freewheel, (void *) this);
- jack_set_buffer_size_callback (_client, jack_static_buffsize, (void *) this);
- jack_on_shutdown (_client, jack_static_shutdown, (void *) this);
-
- _bsize = 0;
- _fsamp = 0;
- if (jack_activate (_client))
- {
- fprintf(stderr, "Can't activate Jack");
- return false;
- }
- _jname = jack_get_client_name (_client);
- _bsize = jack_get_buffer_size (_client);
- _fsamp = jack_get_sample_rate (_client);
-
- flags = JackPortIsTerminal | JackPortIsPhysical;
- for (i = 0; i < _nchan; i++)
- {
- if (_mode == PLAY)
- {
- sprintf (s, "playback_%d", i + 1);
- _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE,
- flags | JackPortIsInput, 0);
- }
- else
- {
- sprintf (s, "capture_%d", i + 1);
- _ports [i] = jack_port_register (_client, s, JACK_DEFAULT_AUDIO_TYPE,
- flags | JackPortIsOutput, 0);
- }
- }
- pthread_getschedparam (jack_client_thread_id (_client), &spol, &spar);
- _rprio = spar.sched_priority - sched_get_priority_max (spol);
- _buff = new float [_bsize * _nchan];
- return true;
-}
-
-
-void Jackclient::fini (void)
-{
- delete[] _buff;
- delete _resamp;
-}
-
-
-void Jackclient::jack_static_shutdown (void *arg)
-{
- ((Jackclient *) arg)->sendinfo (TERM, 0, 0);
-}
-
-
-int Jackclient::jack_static_buffsize (jack_nframes_t nframes, void *arg)
-{
- Jackclient *J = (Jackclient *) arg;
-
- if (J->_bsize == 0) J->_bsize = nframes;
- else if (J->_bsize != (int) nframes) J->_state = Jackclient::TERM;
- return 0;
-}
-
-
-void Jackclient::jack_static_freewheel (int state, void *arg)
-{
- ((Jackclient *) arg)->jack_freewheel (state);
-}
-
-
-void Jackclient::jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg)
-{
- ((Jackclient *) arg)->jack_latency (jlcm);
-}
-
-
-int Jackclient::jack_static_process (jack_nframes_t nframes, void *arg)
-{
- return ((Jackclient *) arg)->jack_process (nframes);
-}
-
-
-void Jackclient::start (Lfq_audio *audioq,
- Lfq_int32 *commq,
- Lfq_adata *alsaq,
- Lfq_jdata *infoq,
- double ratio,
- int delay,
- int ltcor,
- int rqual)
-{
- double d;
-
- _audioq = audioq;
- _commq = commq;
- _alsaq = alsaq;
- _infoq = infoq;
- _ratio = ratio;
- _delay = delay;
- _rcorr = 1.0;
- if (_resamp)
- {
- _resamp->setup (_ratio, _nchan, rqual);
- _resamp->set_rrfilt (100);
- d = _resamp->inpsize () / 2.0;
- if (_mode == PLAY) d *= _ratio;
- _delay += d;
- }
- _ltcor = ltcor;
- _ppsec = (_fsamp + _bsize / 2) / _bsize;
- initwait (_ppsec / 2);
- jack_recompute_total_latencies (_client);
-}
-
-
-void Jackclient::initwait (int nwait)
-{
- _count = -nwait;
- _commq->wr_int32 (Alsathread::WAIT);
- _state = WAIT;
- if (nwait > _ppsec) sendinfo (WAIT, 0, 0);
-}
-
-
-void Jackclient::initsync (void)
-{
- // Reset all lock-free queues.
- _commq->reset ();
- _alsaq->reset ();
- _audioq->reset ();
- if (_resamp)
- {
- // Reset and prefill the resampler.
- _resamp->reset ();
- _resamp->inp_count = _resamp->inpsize () / 2 - 1;
- _resamp->out_count = 99999;
- _resamp->process ();
- }
- // Initialise state variables.
- _t_a0 = _t_a1 = 0;
- _k_a0 = _k_a1 = 0;
- // Initialise loop filter state.
- _z1 = _z2 = _z3 = 0;
- // Activate the ALSA thread,
- _commq->wr_int32 (Alsathread::PROC);
- _state = SYNC0;
- sendinfo (SYNC0, 0, 0);
-}
-
-
-void Jackclient::setloop (double bw)
-{
- double w;
-
- // Set the loop bandwidth to bw Hz.
- w = 6.28 * bw * _bsize / _fsamp;
- _w0 = 1.0 - exp (-20.0 * w);
- _w1 = w * 2 / _bsize;
- _w2 = w / 2;
- if (_mode == PLAY) _w1 /= _ratio;
- else _w1 *= _ratio;
-}
-
-
-void Jackclient::playback (int nframes)
-{
- int i, j, n;
- float *p, *q;
- float *inp [MAXCHAN];
-
- _bstat = _audioq->rd_avail ();
- for (i = 0; i < _nchan; i++)
- {
- inp [i] = (float *)(jack_port_get_buffer (_ports [i], nframes));
- }
- if (_resamp)
- {
- // Interleave inputs into _buff.
- for (i = 0; i < _nchan; i++)
- {
- p = inp [i];
- q = _buff + i;
- for (j = 0; j < _bsize; j++) q [j * _nchan] = p [j];
- }
- // Resample _buff and write to audio queue.
- // The while loop takes care of wraparound.
- _resamp->inp_count = _bsize;
- _resamp->inp_data = _buff;
- while (_resamp->inp_count)
- {
- _resamp->out_count = _audioq->wr_linav ();
- _resamp->out_data = _audioq->wr_datap ();
- n = _resamp->out_count;
- _resamp->process ();
- n -= _resamp->out_count;
- _audioq->wr_commit (n);
- }
- }
- else
- {
- // Interleave inputs into audio queue.
- // The while loop takes care of wraparound.
- while (nframes)
- {
- q = _audioq->wr_datap ();
- n = _audioq->wr_linav ();
- if (n > nframes) n = nframes;
- for (i = 0; i < _nchan; i++)
- {
- p = inp [i];
- for (j = 0; j < n; j++) q [j * _nchan] = p [j];
- inp [i] += n;
- q += 1;
- }
- _audioq->wr_commit (n);
- nframes -= n;
- }
- }
-}
-
-
-void Jackclient::capture (int nframes)
-{
- int i, j, n;
- float *p, *q;
- float *out [MAXCHAN];
-
- for (i = 0; i < _nchan; i++)
- {
- out [i] = (float *)(jack_port_get_buffer (_ports [i], nframes));
- }
- if (_resamp)
- {
- // Read from audio queue and resample.
- // The while loop takes care of wraparound.
- _resamp->out_count = _bsize;
- _resamp->out_data = _buff;
- while (_resamp->out_count)
- {
- _resamp->inp_count = _audioq->rd_linav ();
- _resamp->inp_data = _audioq->rd_datap ();
- n = _resamp->inp_count;
- _resamp->process ();
- n -= _resamp->inp_count;
- _audioq->rd_commit (n);
- }
- // Deinterleave _buff to outputs.
- for (i = 0; i < _nchan; i++)
- {
- p = _buff + i;
- q = out [i];
- for (j = 0; j < _bsize; j++) q [j] = p [j * _nchan];
- }
- }
- else
- {
- // Deinterleave audio queue to outputs.
- // The while loop takes care of wraparound.
- while (nframes)
- {
- p = _audioq->rd_datap ();
- n = _audioq->rd_linav ();
- if (n > nframes) n = nframes;
- for (i = 0; i < _nchan; i++)
- {
- q = out [i];
- for (j = 0; j < n; j++) q [j] = p [j * _nchan];
- out [i] += n;
- p += 1;
- }
- _audioq->rd_commit (n);
- nframes -= n;
- }
- }
- _bstat = _audioq->rd_avail ();
-}
-
-
-void Jackclient::silence (int nframes)
-{
- int i;
- float *q;
-
- // Write silence to all jack ports.
- for (i = 0; i < _nchan; i++)
- {
- q = (float *)(jack_port_get_buffer (_ports [i], nframes));
- memset (q, 0, nframes * sizeof (float));
- }
-}
-
-
-void Jackclient::sendinfo (int state, double error, double ratio)
-{
- Jdata *J;
-
- if (_infoq->wr_avail ())
- {
- J = _infoq->wr_datap ();
- J->_state = state;
- J->_error = error;
- J->_ratio = ratio;
- J->_bstat = _bstat;
- _infoq->wr_commit ();
- }
-}
-
-
-void Jackclient::jack_freewheel (int state)
-{
- _freew = state ? true : false;
- if (_freew) initwait (_ppsec / 4);
-}
-
-
-void Jackclient::jack_latency (jack_latency_callback_mode_t jlcm)
-{
- jack_latency_range_t R;
- int i;
-
- if (_state < WAIT) return;
- if (_mode == PLAY)
- {
- if (jlcm != JackPlaybackLatency) return;
- R.min = R.max = (int)(_delay / _ratio) + _ltcor;
- }
- else
- {
- if (jlcm != JackCaptureLatency) return;
- R.min = R.max = (int)(_delay * _ratio) + _ltcor;
- }
- for (i = 0; i < _nchan; i++)
- {
- jack_port_set_latency_range (_ports [i], jlcm, &R);
- }
-}
-
-
-int Jackclient::jack_process (int nframes)
-{
- int dk, n;
- Adata *D;
- jack_time_t t0, t1;
- jack_nframes_t ft;
- float us;
- double tj, err, d1, d2, rd;
-
- // Buffer size change or other evil.
- if (_state == TERM)
- {
- sendinfo (TERM, 0, 0);
- return 0;
- }
- // Skip cylce if ports may not yet exist.
- if (_state < WAIT) return 0;
-
- // Start synchronisation 1/2 second after entering
- // the WAIT state. This delay allows the ALSA thread
- // to restart cleanly if necessary. Disabled while
- // freewheeling.
- if (_state == WAIT)
- {
- if (_freew) return 0;
- if (_mode == CAPT) silence (nframes);
- if (++_count == 0) initsync ();
- else return 0;
- }
-
- // Get the start time of the current cycle.
- jack_get_cycle_times (_client, &ft, &t0, &t1, &us);
- tj = tjack (t0);
-
- // Check for any skipped cycles.
- if (_state >= SYNC1)
- {
- dk = ft - _ft - _bsize;
- if (_mode == PLAY)
- {
- dk = (int)(dk * _ratio + 0.5);
- _audioq->wr_commit (dk);
- }
- else
- {
- dk = (int)(dk / _ratio + 0.5);
- _audioq->rd_commit (dk);
- }
- }
- _ft = ft;
-
- // Check if we have timing data from the ALSA thread.
- n = _alsaq->rd_avail ();
- // If the data queue is full restart synchronisation.
- // This can happen e.g. on a jack engine timeout, or
- // when too many cycles have been skipped.
- if (n == _alsaq->size ())
- {
- initwait (_ppsec / 2);
- return 0;
- }
- if (n)
- {
- // Else move interval end to start, and update the
- // interval end keeping only the most recent data.
- if (_state < SYNC2) _state++;
- _t_a0 = _t_a1;
- _k_a0 = _k_a1;
- while (_alsaq->rd_avail ())
- {
- D = _alsaq->rd_datap ();
- // Restart synchronisation in case of
- // an error in the ALSA interface.
- if (D->_state == Alsathread::WAIT)
- {
- initwait (_ppsec / 2);
- return 0;
- }
- _t_a1 = D->_timer;
- _k_a1 += D->_nsamp;
- _alsaq->rd_commit ();
- }
- }
-
- err = 0;
- if (_state >= SYNC2)
- {
- // Compute the delay error.
- d1 = tjack_diff (tj, _t_a0);
- d2 = tjack_diff (_t_a1, _t_a0);
- rd = _resamp ? _resamp->inpdist () : 0.0;
-
- if (_mode == PLAY)
- {
- n = _audioq->nwr () - _k_a0; // Must be done as integer as both terms will overflow.
- err = n - (_k_a1 - _k_a0) * d1 / d2 + rd * _ratio - _delay;
- }
- else
- {
- n = _k_a0 - _audioq->nrd (); // Must be done as integer as both terms will overflow.
- err = n + (_k_a1 - _k_a0) * d1 / d2 + rd - _delay ;
- }
- n = (int)(floor (err + 0.5));
- if (_state == SYNC2)
- {
- // We have the first delay error value. Adjust the audio
- // queue to obtain the actually wanted delay, and start
- // tracking.
- if (_mode == PLAY) _audioq->wr_commit (-n);
- else _audioq->rd_commit (n);
- err -= n;
- setloop (1.0);
- _state = PROC1;
- }
- }
-
- // Switch to lower bandwidth after 4 seconds.
- if ((_state == PROC1) && (++_count == 4 * _ppsec))
- {
- _state = PROC2;
- setloop (0.05);
- }
-
- if (_state >= PROC1)
- {
- _z1 += _w0 * (_w1 * err - _z1);
- _z2 += _w0 * (_z1 - _z2);
- _z3 += _w2 * _z2;
- // Check error conditions.
- if (fabs (_z3) > 0.05)
- {
- // Something is really wrong, wait 10 seconds then restart.
- initwait (10 * _ppsec);
- return 0;
- }
- // Run loop filter and set resample ratio.
- if (_resamp)
- {
- _rcorr = 1 - (_z2 + _z3);
- if (_rcorr > 1.05) _rcorr = 1.05;
- if (_rcorr < 0.95) _rcorr = 0.95;
- _resamp->set_rratio (_rcorr);
- }
- sendinfo (_state, err, _rcorr);
-
- // Resample and transfer between audio
- // queue and jack ports.
- if (_mode == PLAY) playback (nframes);
- else capture (nframes);
- }
- else if (_mode == CAPT) silence (nframes);
-
- return 0;
-}
diff --git a/tools/zalsa/jackclient.h b/tools/zalsa/jackclient.h
deleted file mode 100644
index 52f3ddfd..00000000
--- a/tools/zalsa/jackclient.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#ifndef __JACKCLIENT_H
-#define __JACKCLIENT_H
-
-
-#include <zita-resampler/vresampler.h>
-#include "jack/jack.h"
-#include "lfqueue.h"
-
-
-class Jackclient
-{
-public:
-
- Jackclient (jack_client_t*, const char *jserv, int mode, int nchan, bool sync, void *arg);
- virtual ~Jackclient (void);
-
- enum { PLAY, CAPT, MAXCHAN = 64 };
- enum { INIT, TERM, WAIT, SYNC0, SYNC1, SYNC2, PROC1, PROC2 };
-
- void start (Lfq_audio *audioq,
- Lfq_int32 *commq,
- Lfq_adata *alsaq,
- Lfq_jdata *infoq,
- double ratio,
- int delay,
- int ltcor,
- int rqual);
-
- const char *jname (void) const { return _jname; }
- int fsamp (void) const { return _fsamp; }
- int bsize (void) const { return _bsize; }
- int rprio (void) const { return _rprio; }
- void *getarg(void) const { return _arg; }
-
-private:
-
- bool init (const char *jserv);
- void fini (void);
- void initwait (int nwait);
- void initsync (void);
- void setloop (double bw);
- void silence (int nframes);
- void playback (int nframes);
- void capture (int nframes);
- void sendinfo (int state, double error, double ratio);
-
- virtual void thr_main (void) {}
-
- void jack_freewheel (int state);
- void jack_latency (jack_latency_callback_mode_t jlcm);
- int jack_process (int nframes);
-
- jack_client_t *_client;
- jack_port_t *_ports [MAXCHAN];
- void *_arg;
- const char *_jname;
- int _mode;
- int _nchan;
- int _state;
- int _count;
- int _fsamp;
- int _bsize;
- int _rprio;
- bool _freew;
- float *_buff;
-
- Lfq_audio *_audioq;
- Lfq_int32 *_commq;
- Lfq_adata *_alsaq;
- Lfq_jdata *_infoq;
- double _ratio;
- int _ppsec;
- int _bstat;
-
- jack_nframes_t _ft;
- double _t_a0;
- double _t_a1;
- int _k_a0;
- int _k_a1;
- double _delay;
- int _ltcor;
-
- double _w0;
- double _w1;
- double _w2;
- double _z1;
- double _z2;
- double _z3;
- double _rcorr;
- VResampler *_resamp;
-
- static void jack_static_shutdown (void *arg);
- static int jack_static_buffsize (jack_nframes_t nframes, void *arg);
- static void jack_static_freewheel (int state, void *arg);
- static void jack_static_latency (jack_latency_callback_mode_t jlcm, void *arg);
- static int jack_static_process (jack_nframes_t nframes, void *arg);
-};
-
-
-#endif
diff --git a/tools/zalsa/lfqueue.cc b/tools/zalsa/lfqueue.cc
deleted file mode 100644
index f66d07e3..00000000
--- a/tools/zalsa/lfqueue.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include <assert.h>
-#include "lfqueue.h"
-
-
-Lfq_adata::Lfq_adata (int size) :
- _size (size),
- _mask (size - 1),
- _nwr (0),
- _nrd (0)
-{
- assert (!(_size & _mask));
- _data = new Adata [_size];
-}
-
-Lfq_adata::~Lfq_adata (void)
-{
- delete[] _data;
-}
-
-
-Lfq_jdata::Lfq_jdata (int size) :
- _size (size),
- _mask (size - 1),
- _nwr (0),
- _nrd (0)
-{
- assert (!(_size & _mask));
- _data = new Jdata [_size];
-}
-
-Lfq_jdata::~Lfq_jdata (void)
-{
- delete[] _data;
-}
-
-
-Lfq_int32::Lfq_int32 (int size) :
- _size (size),
- _mask (size - 1),
- _nwr (0),
- _nrd (0)
-{
- assert (!(_size & _mask));
- _data = new int32_t [_size];
-}
-
-Lfq_int32::~Lfq_int32 (void)
-{
- delete[] _data;
-}
-
-
-Lfq_audio::Lfq_audio (int nsamp, int nchan) :
- _size (nsamp),
- _mask (nsamp - 1),
- _nch (nchan),
- _nwr (0),
- _nrd (0)
-{
- assert (!(_size & _mask));
- _data = new float [_nch * _size];
-}
-
-Lfq_audio::~Lfq_audio (void)
-{
- delete[] _data;
-}
-
-
diff --git a/tools/zalsa/lfqueue.h b/tools/zalsa/lfqueue.h
deleted file mode 100644
index 3943d401..00000000
--- a/tools/zalsa/lfqueue.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#ifndef __LFQUEUE_H
-#define __LFQUEUE_H
-
-
-#include <stdint.h>
-#include <string.h>
-
-
-class Adata
-{
-public:
-
- int32_t _state;
- int32_t _nsamp;
- double _timer;
-};
-
-
-class Lfq_adata
-{
-public:
-
- Lfq_adata (int size);
- ~Lfq_adata (void);
-
- void reset (void) { _nwr = _nrd = 0; }
- int size (void) const { return _size; }
-
- int wr_avail (void) const { return _size - _nwr + _nrd; }
- Adata *wr_datap (void) { return _data + (_nwr & _mask); }
- void wr_commit (void) { _nwr++; }
-
- int rd_avail (void) const { return _nwr - _nrd; }
- Adata *rd_datap (void) { return _data + (_nrd & _mask); }
- void rd_commit (void) { _nrd++; }
-
-private:
-
- Adata *_data;
- int _size;
- int _mask;
- int _nwr;
- int _nrd;
-};
-
-
-class Jdata
-{
-public:
-
- int32_t _state;
- double _error;
- double _ratio;
- int _bstat;
-};
-
-
-class Lfq_jdata
-{
-public:
-
- Lfq_jdata (int size);
- ~Lfq_jdata (void);
-
- void reset (void) { _nwr = _nrd = 0; }
- int size (void) const { return _size; }
-
- int wr_avail (void) const { return _size - _nwr + _nrd; }
- Jdata *wr_datap (void) { return _data + (_nwr & _mask); }
- void wr_commit (void) { _nwr++; }
-
- int rd_avail (void) const { return _nwr - _nrd; }
- Jdata *rd_datap (void) { return _data + (_nrd & _mask); }
- void rd_commit (void) { _nrd++; }
-
-private:
-
- Jdata *_data;
- int _size;
- int _mask;
- int _nwr;
- int _nrd;
-};
-
-
-class Lfq_int32
-{
-public:
-
- Lfq_int32 (int size);
- ~Lfq_int32 (void);
-
- int size (void) const { return _size; }
- void reset (void) { _nwr = _nrd = 0; }
-
- int wr_avail (void) const { return _size - _nwr + _nrd; }
- int32_t *wr_datap (void) { return _data + (_nwr & _mask); }
- void wr_commit (void) { _nwr++; }
-
- int rd_avail (void) const { return _nwr - _nrd; }
- int32_t *rd_datap (void) { return _data + (_nrd & _mask); }
- void rd_commit (void) { _nrd++; }
-
- void wr_int32 (int32_t v) { _data [_nwr++ & _mask] = v; }
- void wr_uint32 (uint32_t v) { _data [_nwr++ & _mask] = v; }
- void wr_float (float v) { *(float *)(_data + (_nwr++ & _mask)) = v; }
-
- int32_t rd_int32 (void) { return _data [_nrd++ & _mask]; }
- int32_t rd_uint32 (void) { return _data [_nrd++ & _mask]; }
- float rd_float (void) { return *(float *)(_data + (_nrd++ & _mask)); }
-
-private:
-
- int32_t *_data;
- int _size;
- int _mask;
- int _nwr;
- int _nrd;
-};
-
-
-class Lfq_audio
-{
-public:
-
- Lfq_audio (int nsamp, int nchan);
- ~Lfq_audio (void);
-
- int size (void) const { return _size; }
- void reset (void)
- {
- _nwr = _nrd = 0;
- memset (_data, 0, _size * _nch * sizeof (float));
- }
-
- int nchan (void) const { return _nch; }
- int nwr (void) const { return _nwr; };
- int nrd (void) const { return _nrd; };
-
- int wr_avail (void) const { return _size - _nwr + _nrd; }
- int wr_linav (void) const { return _size - (_nwr & _mask); }
- float *wr_datap (void) { return _data + _nch * (_nwr & _mask); }
- void wr_commit (int k) { _nwr += k; }
-
- int rd_avail (void) const { return _nwr - _nrd; }
- int rd_linav (void) const { return _size - (_nrd & _mask); }
- float *rd_datap (void) { return _data + _nch * (_nrd & _mask); }
- void rd_commit (int k) { _nrd += k; }
-
-private:
-
- float *_data;
- int _size;
- int _mask;
- int _nch;
- int _nwr;
- int _nrd;
-};
-
-
-#endif
-
diff --git a/tools/zalsa/pxthread.cc b/tools/zalsa/pxthread.cc
deleted file mode 100644
index 522827d4..00000000
--- a/tools/zalsa/pxthread.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include "pxthread.h"
-
-
-Pxthread::Pxthread (void) : _thrid (0)
-{
-}
-
-
-Pxthread::~Pxthread (void)
-{
-}
-
-
-extern "C" void *Pxthread_entry_point (void *arg)
-{
- Pxthread *T = (Pxthread *) arg;
- T->thr_main ();
- return NULL;
-}
-
-
-int Pxthread::thr_start (int policy, int priority, size_t stacksize)
-{
- int min, max, rc;
- pthread_attr_t attr;
- struct sched_param parm;
-
- min = sched_get_priority_min (policy);
- max = sched_get_priority_max (policy);
- priority += max;
- if (priority > max) priority = max;
- if (priority < min) priority = min;
- parm.sched_priority = priority;
-
- pthread_attr_init (&attr);
- pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
- pthread_attr_setschedpolicy (&attr, policy);
- pthread_attr_setschedparam (&attr, &parm);
- pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
- pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED);
- pthread_attr_setstacksize (&attr, stacksize);
-
- _thrid = 0;
- rc = pthread_create (&_thrid,
- &attr,
- Pxthread_entry_point,
- this);
-
- pthread_attr_destroy (&attr);
-
- return rc;
-}
-
-
-void Pxthread::thr_main (void)
-{
-}
-
-
-void Pxthread::thr_wait (void)
-{
- if (_thrid == 0)
- return;
- pthread_join (_thrid, NULL);
- _thrid = 0;
-}
-
diff --git a/tools/zalsa/pxthread.h b/tools/zalsa/pxthread.h
deleted file mode 100644
index 542aa6ed..00000000
--- a/tools/zalsa/pxthread.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#ifndef __PXTHREAD_H
-#define __PXTHREAD_H
-
-
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-
-
-class Pxthread
-{
-public:
-
- Pxthread (void);
- virtual ~Pxthread (void);
- Pxthread (const Pxthread&);
- Pxthread& operator=(const Pxthread&);
-
- virtual void thr_main (void) = 0;
- virtual int thr_start (int policy, int priority, size_t stacksize = 0);
- virtual void thr_wait (void);
-
-private:
-
- pthread_t _thrid;
-};
-
-
-#endif
diff --git a/tools/zalsa/timers.h b/tools/zalsa/timers.h
deleted file mode 100644
index 267afa61..00000000
--- a/tools/zalsa/timers.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#ifndef __TIMERS_H
-#define __TIMERS_H
-
-
-#include <math.h>
-#include <sys/time.h>
-#include <jack/jack.h>
-
-
-#define tjack_mod ldexp (1e-6f, 32)
-
-
-
-inline double tjack_diff (double a, double b)
-{
- double d, m;
-
- d = a - b;
- m = tjack_mod;
- while (d < -m / 2) d += m;
- while (d >= m / 2) d -= m;
- return d;
-}
-
-
-inline double tjack (jack_time_t t, double dt = 0)
-{
- int32_t u = (int32_t)(t & 0xFFFFFFFFLL);
- return 1e-6 * u;
-}
-
-
-#endif
diff --git a/tools/zalsa/zita-a2j.cc b/tools/zalsa/zita-a2j.cc
deleted file mode 100644
index 1dbe1144..00000000
--- a/tools/zalsa/zita-a2j.cc
+++ /dev/null
@@ -1,409 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <signal.h>
-#include "alsathread.h"
-#include "jackclient.h"
-#include "lfqueue.h"
-#include "jack/control.h"
-
-static const char *clopt = "hvLSwj:d:r:p:n:c:Q:I:";
-
-static void help (void)
-{
- jack_info ("%s-%s", APPNAME, VERSION);
- jack_info ("(C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>");
- jack_info ("Use ALSA capture device as a Jack client.");
- jack_info ("Options:");
- jack_info (" -h Display this text");
- jack_info (" -j <jackname> Name as Jack client [%s]", APPNAME);
- jack_info (" -d <device> ALSA capture device [none]");
- jack_info (" -r <rate> Sample rate [48000]");
- jack_info (" -p <period> Period size [256]");
- jack_info (" -n <nfrags> Number of fragments [2]");
- jack_info (" -c <nchannels> Number of channels [2]");
- jack_info (" -S Word clock sync, no resampling");
- jack_info (" -Q <quality> Resampling quality, 16..96 [auto]");
- jack_info (" -I <samples> Latency adjustment [0]");
- jack_info (" -L Force 16-bit and 2 channels [off]");
- jack_info (" -w Wait until soundcard is available [off]");
- jack_info (" -v Print tracing information [off]");
-}
-
-class zita_a2j
-{
- Lfq_int32 *commq;
- Lfq_adata *alsaq;
- Lfq_jdata *infoq;
- Lfq_audio *audioq;
- bool stop;
- bool v_opt;
- bool L_opt;
- bool S_opt;
- bool w_opt;
- char *jname;
- char *device;
- int fsamp;
- int bsize;
- int nfrag;
- int nchan;
- int rqual;
- int ltcor;
-
-public:
-
- zita_a2j()
- {
- commq = new Lfq_int32(16);
- alsaq = new Lfq_adata(256);
- infoq = new Lfq_jdata(256);
- audioq = 0;
- stop = false;
- v_opt = false;
- L_opt = false;
- S_opt = false;
- w_opt = false;
- jname = strdup(APPNAME);
- device = 0;
- fsamp = 48000;
- bsize = 128;
- nfrag = 2;
- nchan = 2;
- rqual = 0;
- ltcor = 0;
- A = 0;
- C = 0;
- J = 0;
- t = 0;
- }
-
-private:
-
- int procoptions (int ac, const char *av [])
- {
- int k;
-
- optind = 1;
- opterr = 0;
- while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1)
- {
- if (optarg && (*optarg == '-'))
- {
- jack_error (APPNAME ": Missing argument for '-%c' option.", k);
- jack_error (APPNAME ": Use '-h' to see all options.");
- return 1;
- }
- switch (k)
- {
- case 'h' : help (); return 1;
- case 'v' : v_opt = true; break;
- case 'L' : L_opt = true; break;
- case 'S' : S_opt = true; break;
- case 'w' : w_opt = true; break;
- case 'j' : jname = optarg; break;
- case 'd' : device = optarg; break;
- case 'r' : fsamp = atoi (optarg); break;
- case 'p' : bsize = atoi (optarg); break;
- case 'n' : nfrag = atoi (optarg); break;
- case 'c' : nchan = atoi (optarg); break;
- case 'Q' : rqual = atoi (optarg); break;
- case 'I' : ltcor = atoi (optarg); break;
- case '?':
- if (optopt != ':' && strchr (clopt, optopt))
- {
- jack_error (APPNAME ": Missing argument for '-%c' option.", optopt);
- }
- else if (isprint (optopt))
- {
- jack_error (APPNAME ": Unknown option '-%c'.", optopt);
- }
- else
- {
- jack_error (APPNAME ": Unknown option character '0x%02x'.", optopt & 255);
- }
- jack_error (APPNAME ": Use '-h' to see all options.");
- return 1;
- default:
- return 1;
- }
- }
- return 0;
- }
-
- int parse_options (const char* load_init)
- {
- int argsz;
- int argc = 0;
- const char** argv;
- char* args = strdup (load_init);
- char* token;
- char* ptr = args;
- char* savep;
-
- if (!load_init) {
- return 0;
- }
-
- argsz = 8; /* random guess at "maxargs" */
- argv = (const char **) malloc (sizeof (char *) * argsz);
-
- argv[argc++] = APPNAME;
-
- while (1) {
-
- if ((token = strtok_r (ptr, " ", &savep)) == NULL) {
- break;
- }
-
- if (argc == argsz) {
- argsz *= 2;
- argv = (const char **) realloc (argv, sizeof (char *) * argsz);
- }
-
- argv[argc++] = token;
- ptr = NULL;
- }
-
- return procoptions (argc, argv);
- }
-
- void printinfo (void)
- {
- int n, k;
- double e, r;
- Jdata *J;
-
- n = 0;
- k = 99999;
- e = r = 0;
- while (infoq->rd_avail ())
- {
- J = infoq->rd_datap ();
- if (J->_state == Jackclient::TERM)
- {
- jack_error (APPNAME ": Fatal error condition, terminating.");
- stop = true;
- return;
- }
- else if (J->_state == Jackclient::WAIT)
- {
- jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds.");
- n = 0;
- }
- else if (J->_state == Jackclient::SYNC0)
- {
- jack_info (APPNAME ": Starting synchronisation.");
- }
- else if (v_opt)
- {
- n++;
- e += J->_error;
- r += J->_ratio;
- if (J->_bstat < k) k = J->_bstat;
- }
- infoq->rd_commit ();
- }
- if (n) jack_info (APPNAME ": %8.3lf %10.6lf %5d", e / n, r / n, k);
- }
-
-
- Alsa_pcmi *A;
- Alsathread *C;
- Jackclient *J;
-
- pthread_t t;
- int topts;
-
- static void* _retry_alsa_pcmi (void *arg)
- {
- ((zita_a2j*)arg)->retry_alsa_pcmi ();
- return NULL;
- }
-
- void retry_alsa_pcmi ()
- {
- Alsa_pcmi *a;
-
- while (! stop)
- {
- sleep(1);
-
- a = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, topts);
- if (a->state ())
- {
- delete a;
- continue;
- }
-
- A = a;
- if (v_opt) A->printinfo ();
- C = new Alsathread (A, Alsathread::CAPT);
- usleep (100*1000);
- jack_initialize_part2 ();
- jack_info (APPNAME ": Device is now available and has been activated");
- break;
- }
-
- t = 0;
- }
-
-public:
-
- int
- jack_initialize (jack_client_t* client, const char* load_init)
- {
- int opts;
-
- if (parse_options (load_init)) {
- jack_error (APPNAME ": parse options failed");
- delete this;
- return 1;
- }
-
- if (device == 0)
- {
- help ();
- delete this;
- return 1;
- }
- if (rqual < 16) rqual = 16;
- if (rqual > 96) rqual = 96;
- if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1))
- {
- jack_error (APPNAME ": Illegal parameter value(s).");
- delete this;
- return 1;
- }
-
- opts = 0;
- if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL;
- if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH;
- if (w_opt)
- {
- J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this);
- A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts);
-
- // if device is not available, spawn thread to keep trying
- if (A->state ())
- {
- delete A;
- A = NULL;
- topts = opts;
- pthread_create (&t, NULL, _retry_alsa_pcmi, this);
- jack_info (APPNAME ": Could not open device, will keep trying in new thread...");
- return 0;
- }
-
- // otherwise continue as normal
- if (v_opt) A->printinfo ();
- C = new Alsathread (A, Alsathread::CAPT);
- }
- else
- {
- A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts);
- if (A->state ())
- {
- jack_error (APPNAME ": Can't open ALSA capture device '%s'.", device);
- delete this;
- return 1;
- }
- if (v_opt) A->printinfo ();
- if (nchan > A->ncapt ())
- {
- nchan = A->ncapt ();
- jack_error (APPNAME ": Warning: only %d channels are available.", nchan);
- }
- C = new Alsathread (A, Alsathread::CAPT);
- J = new Jackclient (client, 0, Jackclient::CAPT, nchan, S_opt, this);
- }
-
- usleep (100*1000);
- jack_initialize_part2 ();
- return 0;
- }
-
- void jack_initialize_part2 ()
- {
- int k, k_del;
- double t_alsa;
- double t_jack;
- double t_del;
-
- t_alsa = (double) bsize / fsamp;
- if (t_alsa < 1e-3) t_alsa = 1e-3;
- t_jack = (double) J->bsize () / J->fsamp ();
- t_del = t_alsa + t_jack;
- k_del = (int)(t_del * fsamp);
- for (k = 256; k < 2 * k_del; k *= 2);
- audioq = new Lfq_audio (k, nchan);
-
- if (rqual == 0)
- {
- k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp ();
- if (k < 44100) k = 44100;
- rqual = (int)((6.7 * k) / (k - 38000));
- }
- if (rqual < 16) rqual = 16;
- if (rqual > 96) rqual = 96;
-
- C->start (audioq, commq, alsaq, J->rprio () + 10);
- J->start (audioq, commq, alsaq, infoq, J->fsamp () / (double) fsamp, k_del, ltcor, rqual);
- }
-
- void jack_finish (void* arg)
- {
- if (t != 0)
- {
- stop = true;
- pthread_join(t, NULL);
- }
-
- commq->wr_int32 (Alsathread::TERM);
- usleep (100000);
- delete C;
- delete A;
- delete J;
- delete audioq;
- }
-};
-
-extern "C" {
-
-int
-jack_initialize (jack_client_t* client, const char* load_init)
-{
- zita_a2j *c = new zita_a2j();
- return c->jack_initialize(client, load_init);
-}
-
-void jack_finish (void* arg)
-{
- if (!arg) return;
- Jackclient *J = (Jackclient *)arg;
- zita_a2j *c = (zita_a2j *)J->getarg();
- c->jack_finish(arg);
- delete c;
-}
-
-} /* extern "C" */
diff --git a/tools/zalsa/zita-j2a.cc b/tools/zalsa/zita-j2a.cc
deleted file mode 100644
index a341ab68..00000000
--- a/tools/zalsa/zita-j2a.cc
+++ /dev/null
@@ -1,408 +0,0 @@
-// ----------------------------------------------------------------------------
-//
-// Copyright (C) 2012 Fons Adriaensen <fons@linuxaudio.org>
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation; either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-//
-// ----------------------------------------------------------------------------
-
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <signal.h>
-#include "alsathread.h"
-#include "jackclient.h"
-#include "lfqueue.h"
-#include "jack/control.h"
-
-static const char *clopt = "hvLSwj:d:r:p:n:c:Q:O:";
-
-static void help (void)
-{
- jack_info ("%s-%s", APPNAME, VERSION);
- jack_info ("(C) 2012-2018 Fons Adriaensen <fons@linuxaudio.org>");
- jack_info ("Use ALSA playback device as a Jack client.");
- jack_info ("Options:");
- jack_info (" -h Display this text");
- jack_info (" -j <jackname> Name as Jack client [%s]", APPNAME);
- jack_info (" -d <device> ALSA playback device [none]");
- jack_info (" -r <rate> Sample rate [48000]");
- jack_info (" -p <period> Period size [256]");
- jack_info (" -n <nfrags> Number of fragments [2]");
- jack_info (" -c <nchannels> Number of channels [2]");
- jack_info (" -S Word clock sync, no resampling");
- jack_info (" -Q <quality> Resampling quality, 16..96 [auto]");
- jack_info (" -O <samples> Latency adjustment [0]");
- jack_info (" -L Force 16-bit and 2 channels [off]");
- jack_info (" -w Wait until soundcard is available [off]");
- jack_info (" -v Print tracing information [off]");
-}
-
-class zita_j2a
-{
- Lfq_int32 *commq;
- Lfq_adata *alsaq;
- Lfq_jdata *infoq;
- Lfq_audio *audioq;
- bool stop;
- bool v_opt;
- bool L_opt;
- bool S_opt;
- bool w_opt;
- char *jname;
- char *device;
- int fsamp;
- int bsize;
- int nfrag;
- int nchan;
- int rqual;
- int ltcor;
-
-public:
-
- zita_j2a()
- {
- commq = new Lfq_int32(16);
- alsaq = new Lfq_adata(256);
- infoq = new Lfq_jdata(256);
- audioq = 0;
- stop = false;
- v_opt = false;
- L_opt = false;
- S_opt = false;
- w_opt = false;
- jname = strdup(APPNAME);
- device = 0;
- fsamp = 48000;
- bsize = 128;
- nfrag = 2;
- nchan = 2;
- rqual = 0;
- ltcor = 0;
- A = 0;
- P = 0;
- J = 0;
- t = 0;
- }
-
-private:
-
- int procoptions (int ac, const char *av [])
- {
- int k;
-
- optind = 1;
- opterr = 0;
- while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1)
- {
- if (optarg && (*optarg == '-'))
- {
- jack_error (APPNAME ": Missing argument for '-%c' option.", k);
- jack_error (APPNAME ": Use '-h' to see all options.");
- return 1;
- }
- switch (k)
- {
- case 'h' : help (); return 1;
- case 'v' : v_opt = true; break;
- case 'L' : L_opt = true; break;
- case 'S' : S_opt = true; break;
- case 'w' : w_opt = true; break;
- case 'j' : jname = optarg; break;
- case 'd' : device = optarg; break;
- case 'r' : fsamp = atoi (optarg); break;
- case 'p' : bsize = atoi (optarg); break;
- case 'n' : nfrag = atoi (optarg); break;
- case 'c' : nchan = atoi (optarg); break;
- case 'Q' : rqual = atoi (optarg); break;
- case 'O' : ltcor = atoi (optarg); break;
- case '?':
- if (optopt != ':' && strchr (clopt, optopt))
- {
- jack_error (APPNAME ": Missing argument for '-%c' option.", optopt);
- }
- else if (isprint (optopt))
- {
- jack_error (APPNAME ": Unknown option '-%c'.", optopt);
- }
- else
- {
- jack_error (APPNAME ": Unknown option character '0x%02x'.", optopt & 255);
- }
- jack_error (APPNAME ": Use '-h' to see all options.");
- return 1;
- default:
- return 1;
- }
- }
-
- return 0;
- }
-
- int parse_options (const char* load_init)
- {
- int argsz;
- int argc = 0;
- const char** argv;
- char* args = strdup (load_init);
- char* token;
- char* ptr = args;
- char* savep;
-
- if (!load_init) {
- return 0;
- }
-
- argsz = 8; /* random guess at "maxargs" */
- argv = (const char **) malloc (sizeof (char *) * argsz);
-
- argv[argc++] = APPNAME;
-
- while (1) {
-
- if ((token = strtok_r (ptr, " ", &savep)) == NULL) {
- break;
- }
-
- if (argc == argsz) {
- argsz *= 2;
- argv = (const char **) realloc (argv, sizeof (char *) * argsz);
- }
-
- argv[argc++] = token;
- ptr = NULL;
- }
-
- return procoptions (argc, argv);
- }
-
- void printinfo (void)
- {
- int n, k;
- double e, r;
- Jdata *J;
-
- n = 0;
- k = 99999;
- e = r = 0;
- while (infoq->rd_avail ())
- {
- J = infoq->rd_datap ();
- if (J->_state == Jackclient::TERM)
- {
- jack_info (APPNAME ": Fatal error condition, terminating.");
- stop = true;
- return;
- }
- else if (J->_state == Jackclient::WAIT)
- {
- jack_info (APPNAME ": Detected excessive timing errors, waiting 10 seconds.");
- n = 0;
- }
- else if (J->_state == Jackclient::SYNC0)
- {
- jack_info (APPNAME ": Starting synchronisation.");
- }
- else if (v_opt)
- {
- n++;
- e += J->_error;
- r += J->_ratio;
- if (J->_bstat < k) k = J->_bstat;
- }
- infoq->rd_commit ();
- }
- if (n) jack_info ("%8.3lf %10.6lf %5d", e / n, r / n, k);
- }
-
- Alsa_pcmi *A;
- Alsathread *P;
- Jackclient *J;
-
- pthread_t t;
- int topts;
-
- static void* _retry_alsa_pcmi (void *arg)
- {
- ((zita_j2a*)arg)->retry_alsa_pcmi ();
- return NULL;
- }
-
- void retry_alsa_pcmi ()
- {
- Alsa_pcmi *a;
-
- while (! stop)
- {
- sleep(1);
-
- a = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, topts);
- if (a->state ())
- {
- delete a;
- continue;
- }
-
- A = a;
- if (v_opt) A->printinfo ();
- P = new Alsathread (A, Alsathread::PLAY);
- usleep (100*1000);
- jack_initialize_part2 ();
- jack_info (APPNAME ": Device is now available and has been activated");
- break;
- }
-
- t = 0;
- }
-
-public:
-
- int jack_initialize (jack_client_t* client, const char* load_init)
- {
- int opts;
-
- if (parse_options (load_init)) {
- delete this;
- return 1;
- }
-
- if (device == 0)
- {
- help ();
- delete this;
- return 1;
- }
- if (rqual < 16) rqual = 16;
- if (rqual > 96) rqual = 96;
- if ((fsamp < 8000) || (bsize < 16) || (nfrag < 2) || (nchan < 1))
- {
- jack_error (APPNAME ": Illegal parameter value(s).");
- delete this;
- return 1;
- }
-
- opts = 0;
- if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL;
- if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH;
- if (w_opt)
- {
- J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this);
-
- // if device is not available, spawn thread to keep trying
- A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts);
- if (A->state ())
- {
- delete A;
- A = NULL;
- topts = opts;
- pthread_create (&t, NULL, _retry_alsa_pcmi, this);
- jack_info (APPNAME ": Could not open device, will keep trying in new thread...");
- return 0;
- }
-
- // otherwise continue as normal
- if (v_opt) A->printinfo ();
- P = new Alsathread (A, Alsathread::PLAY);
- }
- else
- {
- A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts);
- if (A->state ())
- {
- jack_error (APPNAME ": Can't open ALSA playback device '%s'.", device);
- delete this;
- return 1;
- }
- if (v_opt) A->printinfo ();
- if (nchan > A->nplay ())
- {
- nchan = A->nplay ();
- jack_error (APPNAME ": Warning: only %d channels are available.", nchan);
- }
- P = new Alsathread (A, Alsathread::PLAY);
- J = new Jackclient (client, 0, Jackclient::PLAY, nchan, S_opt, this);
- }
-
- usleep (100*1000);
- jack_initialize_part2 ();
- return 0;
- }
-
- void jack_initialize_part2 ()
- {
- int k, k_del;
- double t_jack;
- double t_alsa;
- double t_del;
-
- t_alsa = (double) bsize / fsamp;
- if (t_alsa < 1e-3) t_alsa = 1e-3;
- t_jack = (double) J->bsize () / J->fsamp ();
- t_del = t_alsa + t_jack;
- k_del = (int)(t_del * fsamp);
- for (k = 256; k < 2 * k_del; k *= 2);
- audioq = new Lfq_audio (k, nchan);
-
- if (rqual == 0)
- {
- k = (fsamp < J->fsamp ()) ? fsamp : J->fsamp ();
- if (k < 44100) k = 44100;
- rqual = (int)((6.7 * k) / (k - 38000));
- }
- if (rqual < 16) rqual = 16;
- if (rqual > 96) rqual = 96;
-
- P->start (audioq, commq, alsaq, J->rprio () + 10);
- J->start (audioq, commq, alsaq, infoq, (double) fsamp / J->fsamp (), k_del, ltcor, rqual);
- }
-
- void jack_finish (void* arg)
- {
- if (t != 0)
- {
- stop = true;
- pthread_join(t, NULL);
- t = 0;
- }
-
- commq->wr_int32 (Alsathread::TERM);
- usleep (100*1000);
- delete P;
- delete A;
- delete J;
- delete audioq;
- }
-};
-
-extern "C" {
-
-int
-jack_initialize (jack_client_t* client, const char* load_init)
-{
- zita_j2a *c = new zita_j2a();
- return c->jack_initialize(client, load_init);
-}
-
-void jack_finish (void* arg)
-{
- if (!arg) return;
- Jackclient *J = (Jackclient *)arg;
- zita_j2a *c = (zita_j2a *)J->getarg();
- c->jack_finish(arg);
- delete c;
-}
-
-} /* extern "C" */