From 363d827f9683627b493065c90f5ec2dc8141340e Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 5 Mar 2014 19:40:47 +0000 Subject: [PATCH 1/3] Fix incorrect thread priority which prevent the ALSA thread from running unless ulimit -r was 99. --- zalsa/pxthread.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/zalsa/pxthread.cc b/zalsa/pxthread.cc index e3e8849..21bc872 100644 --- a/zalsa/pxthread.cc +++ b/zalsa/pxthread.cc @@ -47,7 +47,6 @@ int Pxthread::thr_start (int policy, int priority, size_t stacksize) 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; From c6a34b92c522d38b5cf5a6e1090375480bb8db8c Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 5 Mar 2014 21:18:37 +0000 Subject: [PATCH 2/3] Fix for jack_internal_client_handle API change. --- ipunload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ipunload.c b/ipunload.c index de18795..cc311f9 100644 --- a/ipunload.c +++ b/ipunload.c @@ -50,7 +50,7 @@ main (int argc, char *argv[]) /* then, get the internal client handle */ client_name = argv[1]; - if (jack_internal_client_handle (client, client_name, &status, intclient) != 0) { + if (jack_internal_client_handle (client, client_name, &status, &intclient) != 0) { if (status & JackFailure) { fprintf (stderr, "client %s not found.\n", client_name); } From 76056b1332d26a3f457a7cd7fd4a4e1a74701d2a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 5 Mar 2014 21:19:29 +0000 Subject: [PATCH 3/3] Fix static variables permitting only one instance of each of zita-a2j/zita-j2a internal clients. --- zalsa/jackclient.cc | 3 +- zalsa/jackclient.h | 4 +- zalsa/zita-a2j.cc | 417 ++++++++++++++++++++++++-------------------- zalsa/zita-j2a.cc | 404 +++++++++++++++++++++++------------------- 4 files changed, 459 insertions(+), 369 deletions(-) diff --git a/zalsa/jackclient.cc b/zalsa/jackclient.cc index a7f9389..5675412 100644 --- a/zalsa/jackclient.cc +++ b/zalsa/jackclient.cc @@ -25,8 +25,9 @@ #include "alsathread.h" -Jackclient::Jackclient (jack_client_t* cl, const char*jserv, int mode, int nchan) : +Jackclient::Jackclient (jack_client_t* cl, const char*jserv, int mode, int nchan, void *arg) : _client (cl), + _arg (arg), _mode (mode), _nchan (nchan), _state (INIT), diff --git a/zalsa/jackclient.h b/zalsa/jackclient.h index f392f17..919f366 100644 --- a/zalsa/jackclient.h +++ b/zalsa/jackclient.h @@ -31,7 +31,7 @@ class Jackclient { public: - Jackclient (jack_client_t*, const char *jserv, int mode, int nchan); + Jackclient (jack_client_t*, const char *jserv, int mode, int nchan, void *arg); virtual ~Jackclient (void); enum { PLAY, CAPT }; @@ -51,6 +51,7 @@ public: int bsize (void) const { return _bsize; } int rprio (void) const { return _rprio; } void register_ports (int nports); + void *getarg(void) const { return _arg; } private: @@ -80,6 +81,7 @@ private: jack_client_t *_client; jack_port_t *_ports [256]; + void *_arg; const char *_jname; int _mode; int _nchan; diff --git a/zalsa/zita-a2j.cc b/zalsa/zita-a2j.cc index bca856f..46b31d9 100644 --- a/zalsa/zita-a2j.cc +++ b/zalsa/zita-a2j.cc @@ -27,25 +27,7 @@ #include "jackclient.h" #include "lfqueue.h" - -static Lfq_int32 commq (16); -static Lfq_adata alsaq (256); -static Lfq_jdata infoq (256); -static Lfq_audio *audioq = 0; -static bool stop = false; - -static const char *clopt = "hvLj:d:r:p:n:c:Q:I:"; -static bool v_opt = false; -static bool L_opt = false; -static const char *jname = APPNAME; -static const char *device = 0; -static int fsamp = 0; // try to get from server if unspecified -static int bsize = 0; // try to get from server if unspecified -static int nfrag = 2; -static int nchan = 2; -static int rqual = 48; -static int ltcor = 0; - +static const char *clopt = "hvLj:d:r:p:n:c:Q:I:"; static void help (void) { @@ -68,57 +50,101 @@ static void help (void) exit (1); } -static int procoptions (int ac, const char *av []) +class zita_a2j { - int k; - - optind = 1; - opterr = 0; - while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) + Lfq_int32 *commq; + Lfq_adata *alsaq; + Lfq_jdata *infoq; + Lfq_audio *audioq; + bool stop; + bool v_opt; + bool L_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; + jname = strdup(APPNAME); + device = 0; + fsamp = 0; + bsize = 0; + nfrag = 2; + nchan = 2; + rqual = 48; + ltcor = 0; + A = 0; + C = 0; + J = 0; + } + +private: + + int procoptions (int ac, const char *av []) { - if (optarg && (*optarg == '-')) + int k; + + optind = 1; + opterr = 0; + while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) { - fprintf (stderr, " Missing argument for '-%c' option.\n", k); - fprintf (stderr, " Use '-h' to see all options.\n"); - exit (1); + if (optarg && (*optarg == '-')) + { + fprintf (stderr, " Missing argument for '-%c' option.\n", k); + fprintf (stderr, " Use '-h' to see all options.\n"); + exit (1); + } + switch (k) + { + case 'h' : help (); exit (0); + case 'v' : v_opt = true; break; + case 'L' : L_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)) + { + fprintf (stderr, " Missing argument for '-%c' option.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, " Unknown option '-%c'.\n", optopt); + } + else + { + fprintf (stderr, " Unknown option character '0x%02x'.\n", optopt & 255); + } + fprintf (stderr, " Use '-h' to see all options.\n"); + return 1; + default: + return 1; + } } - switch (k) - { - case 'h' : help (); exit (0); - case 'v' : v_opt = true; break; - case 'L' : L_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)) - { - fprintf (stderr, " Missing argument for '-%c' option.\n", optopt); - } - else if (isprint (optopt)) - { - fprintf (stderr, " Unknown option '-%c'.\n", optopt); - } - else - { - fprintf (stderr, " Unknown option character '0x%02x'.\n", optopt & 255); - } - fprintf (stderr, " Use '-h' to see all options.\n"); - return 1; - default: - return 1; - } + return 0; } - return 0; -} -static int parse_options (const char* load_init) -{ + int parse_options (const char* load_init) + { int argsz; int argc = 0; const char** argv; @@ -127,8 +153,8 @@ static int parse_options (const char* load_init) char* ptr = args; char* savep; - if (!load_init) { - return 0; + if (!load_init) { + return 0; } argsz = 8; /* random guess at "maxargs" */ @@ -137,149 +163,166 @@ static int parse_options (const char* load_init) 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; + + 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); -} - -static void printinfo (void) -{ - int n; - double e, r; - Jdata *J; + } - n = 0; - e = r = 0; - while (infoq.rd_avail ()) + void printinfo (void) { - J = infoq.rd_datap (); - if (J->_state == Jackclient::TERM) - { - printf ("Fatal error condition, terminating.\n"); - stop = true; - return; - } - else if (J->_state == Jackclient::WAIT) - { - printf ("Detected excessive timing errors, waiting 15 seconds.\n"); - printf ("This may happen with current Jack1 after freewheeling.\n"); - n = 0; - } - else if (J->_state == Jackclient::SYNC0) - { - printf ("Starting synchronisation.\n"); - } - else if (v_opt) - { - n++; - e += J->_error; - r += J->_ratio; - } - infoq.rd_commit (); - } - if (n) printf ("%8.3lf %10.6lf\n", e / n, r / n); -} + int n; + double e, r; + Jdata *J; + n = 0; + e = r = 0; + while (infoq->rd_avail ()) + { + J = infoq->rd_datap (); + if (J->_state == Jackclient::TERM) + { + printf ("Fatal error condition, terminating.\n"); + stop = true; + return; + } + else if (J->_state == Jackclient::WAIT) + { + printf ("Detected excessive timing errors, waiting 15 seconds.\n"); + printf ("This may happen with current Jack1 after freewheeling.\n"); + n = 0; + } + else if (J->_state == Jackclient::SYNC0) + { + printf ("Starting synchronisation.\n"); + } + else if (v_opt) + { + n++; + e += J->_error; + r += J->_ratio; + } + infoq->rd_commit (); + } + if (n) printf ("%8.3lf %10.6lf\n", e / n, r / n); + } -static Alsa_pcmi *A = 0; -static Alsathread *C = 0; -static Jackclient *J = 0; -extern "C" { + Alsa_pcmi *A; + Alsathread *C; + Jackclient *J; -int -jack_initialize (jack_client_t* client, const char* load_init) -{ - int k, k_del, opts; - double t_jack; - double t_alsa; - double t_del; - - if (parse_options (load_init)) { - fprintf (stderr, "parse options failed\n"); - return 1; - } +public: - if (device == 0) help (); - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - if ((fsamp && fsamp < 8000) || (bsize && bsize < 16) || (nfrag < 2) || (nchan < 1)) + int + jack_initialize (jack_client_t* client, const char* load_init) { - fprintf (stderr, "Illegal parameter value(s).\n"); - return 1; - } + int k, k_del, opts; + double t_jack; + double t_alsa; + double t_del; + + if (parse_options (load_init)) { + fprintf (stderr, "parse options failed\n"); + return 1; + } - J = new Jackclient (client, 0, Jackclient::CAPT, 0); - usleep (100000); + if (device == 0) help (); + if (rqual < 16) rqual = 16; + if (rqual > 96) rqual = 96; + if ((fsamp && fsamp < 8000) || (bsize && bsize < 16) || (nfrag < 2) || (nchan < 1)) + { + fprintf (stderr, "Illegal parameter value(s).\n"); + return 1; + } - /* if SR and/or bufsize are unspecified, use the same values - as the JACK server. - */ - - if (fsamp == 0) - { - fsamp = J->fsamp(); - } + J = new Jackclient (client, 0, Jackclient::CAPT, 0, this); + usleep (100000); - if (bsize == 0) - { - bsize = J->bsize(); - } + /* if SR and/or bufsize are unspecified, use the same values + as the JACK server. + */ + + if (fsamp == 0) + { + fsamp = J->fsamp(); + } - opts = 0; - if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; - if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; - A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts); - if (A->state ()) - { - fprintf (stderr, "Can't open ALSA capture device '%s'.\n", device); - return 1; + if (bsize == 0) + { + bsize = J->bsize(); + } + + opts = 0; + if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; + if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; + A = new Alsa_pcmi (0, device, 0, fsamp, bsize, nfrag, opts); + if (A->state ()) + { + fprintf (stderr, "Can't open ALSA capture device '%s'.\n", device); + return 1; + } + if (v_opt) A->printinfo (); + if (nchan > A->ncapt ()) + { + nchan = A->ncapt (); + fprintf (stderr, "Warning: only %d channels are available.\n", nchan); + } + C = new Alsathread (A, Alsathread::CAPT); + + J->register_ports (nchan); + + t_alsa = (double) bsize / fsamp; + if (t_alsa < 1e-3) t_alsa = 1e-3; + t_jack = (double) J->bsize () / J->fsamp (); + t_del = 1.5 * t_alsa + t_jack; + k_del = (int)(t_del * fsamp); + for (k = 256; k < k_del + J->bsize (); k *= 2); + audioq = new Lfq_audio (k, nchan); + + C->start (audioq, commq, alsaq, J->rprio () + 10); + J->start (audioq, commq, alsaq, infoq, J->fsamp () / (double) fsamp, k_del, ltcor, rqual); + + return 0; } - if (v_opt) A->printinfo (); - if (nchan > A->ncapt ()) + + void jack_finish (void* arg) { - nchan = A->ncapt (); - fprintf (stderr, "Warning: only %d channels are available.\n", nchan); + commq->wr_int32 (Alsathread::TERM); + usleep (100000); + delete C; + delete A; + delete J; + delete audioq; } - C = new Alsathread (A, Alsathread::CAPT); - - J->register_ports (nchan); - - t_alsa = (double) bsize / fsamp; - if (t_alsa < 1e-3) t_alsa = 1e-3; - t_jack = (double) J->bsize () / J->fsamp (); - t_del = 1.5 * t_alsa + t_jack; - k_del = (int)(t_del * fsamp); - for (k = 256; k < k_del + J->bsize (); k *= 2); - audioq = new Lfq_audio (k, nchan); - - C->start (audioq, &commq, &alsaq, J->rprio () + 10); - J->start (audioq, &commq, &alsaq, &infoq, J->fsamp () / (double) fsamp, k_del, ltcor, rqual); - - return 0; +}; + +extern "C" { + +int +jack_initialize (jack_client_t* client, const char* load_init) +{ + zita_a2j *c = new zita_a2j(); + c->jack_initialize(client, load_init); } void jack_finish (void* arg) { - - commq.wr_int32 (Alsathread::TERM); - usleep (100000); - delete C; - delete A; - delete J; - delete audioq; + Jackclient *J = (Jackclient *)arg; + zita_a2j *c = (zita_a2j *)J->getarg(); + c->jack_finish(arg); + delete c; } } /* extern "C" */ diff --git a/zalsa/zita-j2a.cc b/zalsa/zita-j2a.cc index b75b631..86bfcaf 100644 --- a/zalsa/zita-j2a.cc +++ b/zalsa/zita-j2a.cc @@ -27,25 +27,7 @@ #include "jackclient.h" #include "lfqueue.h" - -static Lfq_int32 commq (16); -static Lfq_adata alsaq (256); -static Lfq_jdata infoq (256); -static Lfq_audio *audioq = 0; -static bool stop = false; - -static const char *clopt = "hvLj:d:r:p:n:c:Q:O:"; -static bool v_opt = false; -static bool L_opt = false; -static const char *jname = APPNAME; -static const char *device = 0; -static int fsamp = 0; -static int bsize = 0; -static int nfrag = 2; -static int nchan = 2; -static int rqual = 48; -static int ltcor = 0; - +static const char *clopt = "hvLj:d:r:p:n:c:Q:I:"; static void help (void) { @@ -68,58 +50,102 @@ static void help (void) exit (1); } -static int procoptions (int ac, const char *av []) +class zita_j2a { - int k; - - optind = 1; - opterr = 0; - while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) + Lfq_int32 *commq; + Lfq_adata *alsaq; + Lfq_jdata *infoq; + Lfq_audio *audioq; + bool stop; + bool v_opt; + bool L_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; + jname = strdup(APPNAME); + device = 0; + fsamp = 0; + bsize = 0; + nfrag = 2; + nchan = 2; + rqual = 48; + ltcor = 0; + A = 0; + P = 0; + J = 0; + } + +private: + + int procoptions (int ac, const char *av []) { - if (optarg && (*optarg == '-')) + int k; + + optind = 1; + opterr = 0; + while ((k = getopt (ac, (char **) av, (char *) clopt)) != -1) { - fprintf (stderr, " Missing argument for '-%c' option.\n", k); - fprintf (stderr, " Use '-h' to see all options.\n"); - exit (1); + if (optarg && (*optarg == '-')) + { + fprintf (stderr, " Missing argument for '-%c' option.\n", k); + fprintf (stderr, " Use '-h' to see all options.\n"); + exit (1); + } + switch (k) + { + case 'h' : help (); exit (0); + case 'v' : v_opt = true; break; + case 'L' : L_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)) + { + fprintf (stderr, " Missing argument for '-%c' option.\n", optopt); + } + else if (isprint (optopt)) + { + fprintf (stderr, " Unknown option '-%c'.\n", optopt); + } + else + { + fprintf (stderr, " Unknown option character '0x%02x'.\n", optopt & 255); + } + fprintf (stderr, " Use '-h' to see all options.\n"); + return 1; + default: + return 1; + } } - switch (k) - { - case 'h' : help (); exit (0); - case 'v' : v_opt = true; break; - case 'L' : L_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)) - { - fprintf (stderr, " Missing argument for '-%c' option.\n", optopt); - } - else if (isprint (optopt)) - { - fprintf (stderr, " Unknown option '-%c'.\n", optopt); - } - else - { - fprintf (stderr, " Unknown option character '0x%02x'.\n", optopt & 255); - } - fprintf (stderr, " Use '-h' to see all options.\n"); - return 1; - default: - return 1; - } - } - return 0; -} + return 0; + } -static int parse_options (const char* load_init) -{ + int parse_options (const char* load_init) + { int argsz; int argc = 0; const char** argv; @@ -128,8 +154,8 @@ static int parse_options (const char* load_init) char* ptr = args; char* savep; - if (!load_init) { - return 0; + if (!load_init) { + return 0; } argsz = 8; /* random guess at "maxargs" */ @@ -138,144 +164,162 @@ static int parse_options (const char* load_init) 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; + + 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); -} - -static void printinfo (void) -{ - int n; - double e, r; - Jdata *J; + } - n = 0; - e = r = 0; - while (infoq.rd_avail ()) + void printinfo (void) { - J = infoq.rd_datap (); - if (J->_state == Jackclient::TERM) - { - printf ("Fatal error condition, terminating.\n"); - stop = true; - return; - } - else if (J->_state == Jackclient::WAIT) - { - printf ("Detected excessive timing errors, waiting 15 seconds.\n"); - printf ("This may happen with current Jack1 after freewheeling.\n"); - n = 0; - } - else if (J->_state == Jackclient::SYNC0) - { - printf ("Starting synchronisation.\n"); - } - else if (v_opt) - { - n++; - e += J->_error; - r += J->_ratio; - } - infoq.rd_commit (); + int n; + double e, r; + Jdata *J; + + n = 0; + e = r = 0; + while (infoq->rd_avail ()) + { + J = infoq->rd_datap (); + if (J->_state == Jackclient::TERM) + { + printf ("Fatal error condition, terminating.\n"); + stop = true; + return; + } + else if (J->_state == Jackclient::WAIT) + { + printf ("Detected excessive timing errors, waiting 15 seconds.\n"); + printf ("This may happen with current Jack1 after freewheeling.\n"); + n = 0; + } + else if (J->_state == Jackclient::SYNC0) + { + printf ("Starting synchronisation.\n"); + } + else if (v_opt) + { + n++; + e += J->_error; + r += J->_ratio; + } + infoq->rd_commit (); + } + if (n) printf ("%8.3lf %10.6lf\n", e / n, r / n); } - if (n) printf ("%8.3lf %10.6lf\n", e / n, r / n); -} -Alsa_pcmi *A = 0; -Alsathread *P = 0; -Jackclient *J = 0; + Alsa_pcmi *A; + Alsathread *P; + Jackclient *J; + +public: -extern "C" { + int jack_initialize (jack_client_t* client, const char* load_init) + { + int k, k_del, opts; + double t_jack; + double t_alsa; + double t_del; -int jack_initialize (jack_client_t* client, const char* load_init) -{ - int k, k_del, opts; - double t_jack; - double t_alsa; - double t_del; + if (parse_options (load_init)) { + return 1; + } - if (parse_options (load_init)) { + if (device == 0) help (); + if (rqual < 16) rqual = 16; + if (rqual > 96) rqual = 96; + if ((fsamp && fsamp < 8000) || (bsize && bsize < 16) || (nfrag < 2) || (nchan < 1)) + { + fprintf (stderr, "Illegal parameter value(s).\n"); return 1; - } + } - if (device == 0) help (); - if (rqual < 16) rqual = 16; - if (rqual > 96) rqual = 96; - if ((fsamp && fsamp < 8000) || (bsize && bsize < 16) || (nfrag < 2) || (nchan < 1)) - { - fprintf (stderr, "Illegal parameter value(s).\n"); - return 1; - } + J = new Jackclient (client, 0, Jackclient::PLAY, 0, this); + usleep (100000); - J = new Jackclient (client, 0, Jackclient::PLAY, 0); - usleep (100000); + /* if SR and/or bufsize are unspecified, use the same values + as the JACK server. + */ - /* if SR and/or bufsize are unspecified, use the same values - as the JACK server. - */ - - if (fsamp == 0) - { - fsamp = J->fsamp(); - } + if (fsamp == 0) + { + fsamp = J->fsamp(); + } - if (bsize == 0) - { - bsize = J->bsize(); - } + if (bsize == 0) + { + bsize = J->bsize(); + } - opts = 0; - if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; - if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; - A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts); - if (A->state ()) - { - fprintf (stderr, "Can't open ALSA playback device '%s'.\n", device); - return 1; + opts = 0; + if (v_opt) opts |= Alsa_pcmi::DEBUG_ALL; + if (L_opt) opts |= Alsa_pcmi::FORCE_16B | Alsa_pcmi::FORCE_2CH; + A = new Alsa_pcmi (device, 0, 0, fsamp, bsize, nfrag, opts); + if (A->state ()) + { + fprintf (stderr, "Can't open ALSA playback device '%s'.\n", device); + return 1; + } + if (v_opt) A->printinfo (); + if (nchan > A->nplay ()) + { + nchan = A->nplay (); + fprintf (stderr, "Warning: only %d channels are available.\n", nchan); + } + P = new Alsathread (A, Alsathread::PLAY); + J->register_ports (nchan); + + t_alsa = (double) bsize / fsamp; + if (t_alsa < 1e-3) t_alsa = 1e-3; + t_jack = (double) J->bsize () / J->fsamp (); + t_del = 1.5 * t_alsa + t_jack; + k_del = (int)(t_del * fsamp); + for (k = 256; k < k_del + J->bsize (); k *= 2); + audioq = new Lfq_audio (k, nchan); + + P->start (audioq, commq, alsaq, J->rprio () + 10); + J->start (audioq, commq, alsaq, infoq, (double) fsamp / J->fsamp (), k_del, ltcor, rqual); + + return 0; } - if (v_opt) A->printinfo (); - if (nchan > A->nplay ()) + + void jack_finish (void* arg) { - nchan = A->nplay (); - fprintf (stderr, "Warning: only %d channels are available.\n", nchan); + commq->wr_int32 (Alsathread::TERM); + usleep (100000); + delete P; + delete A; + delete J; + delete audioq; } - P = new Alsathread (A, Alsathread::PLAY); - J->register_ports (nchan); - - t_alsa = (double) bsize / fsamp; - if (t_alsa < 1e-3) t_alsa = 1e-3; - t_jack = (double) J->bsize () / J->fsamp (); - t_del = 1.5 * t_alsa + t_jack; - k_del = (int)(t_del * fsamp); - for (k = 256; k < k_del + J->bsize (); k *= 2); - audioq = new Lfq_audio (k, nchan); +}; - P->start (audioq, &commq, &alsaq, J->rprio () + 10); - J->start (audioq, &commq, &alsaq, &infoq, (double) fsamp / J->fsamp (), k_del, ltcor, rqual); +extern "C" { - return 0; +int +jack_initialize (jack_client_t* client, const char* load_init) +{ + zita_j2a *c = new zita_j2a(); + c->jack_initialize(client, load_init); } void jack_finish (void* arg) { - commq.wr_int32 (Alsathread::TERM); - usleep (100000); - delete P; - delete A; - delete J; - delete audioq; + Jackclient *J = (Jackclient *)arg; + zita_j2a *c = (zita_j2a *)J->getarg(); + c->jack_finish(arg); + delete c; } } /* extern "C" */