3 common defs and code for parm update
5 This file is part of a program that implements a Software-Defined Radio.
7 Copyright (C) 2004-5 by Frank Brickle, AB2KT and Bob McGwier, N4HY
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 The authors can be reached by email at
31 The DTTS Microwave Society
38 ////////////////////////////////////////////////////////////////////////////
39 // for commands affecting RX, which RX is Listening
41 #define RL (uni.multirx.lis)
43 ////////////////////////////////////////////////////////////////////////////
46 dB2lin(REAL dB) { return pow(10.0, dB / 20.0); }
49 setRXFilter(int n, char **p) {
50 REAL low_frequency = atof(p[0]),
51 high_frequency = atof(p[1]);
52 int ncoef = uni.buflen + 1;
53 int i, fftlen = 2 * uni.buflen;
57 if (fabs(low_frequency) >= 0.5 * uni.samplerate) return -1;
58 if (fabs(high_frequency) >= 0.5 * uni.samplerate) return -2;
59 if ((low_frequency + 10) >= high_frequency) return -3;
60 delFIR_COMPLEX(rx[RL].filt.coef);
62 rx[RL].filt.coef = newFIR_Bandpass_COMPLEX(low_frequency,
67 zcvec = newvec_COMPLEX(fftlen, "filter z vec in setFilter");
68 ptmp = fftw_create_plan(fftlen, FFTW_FORWARD, uni.wisdom.bits);
70 for (i = 0; i < ncoef; i++)
71 zcvec[i] = rx[RL].filt.coef->coef[i];
73 for (i = 0; i < ncoef; i++)
74 zcvec[fftlen - ncoef + i] = rx[RL].filt.coef->coef[i];
77 (fftw_complex *) zcvec,
78 (fftw_complex *) rx[RL].filt.ovsv->zfvec);
79 fftw_destroy_plan(ptmp);
80 delvec_COMPLEX(zcvec);
81 normalize_vec_COMPLEX(rx[RL].filt.ovsv->zfvec,
82 rx[RL].filt.ovsv->fftlen);
83 memcpy((char *) rx[RL].filt.save,
84 (char *) rx[RL].filt.ovsv->zfvec,
85 rx[RL].filt.ovsv->fftlen * sizeof(COMPLEX));
92 setTXFilter(int n, char **p) {
93 REAL low_frequency = atof(p[0]),
94 high_frequency = atof(p[1]);
95 int ncoef = uni.buflen + 1;
96 int i, fftlen = 2 * uni.buflen;
100 if (fabs(low_frequency) >= 0.5 * uni.samplerate) return -1;
101 if (fabs(high_frequency) >= 0.5 * uni.samplerate) return -2;
102 if ((low_frequency + 10) >= high_frequency) return -3;
103 delFIR_COMPLEX(tx.filt.coef);
104 tx.filt.coef = newFIR_Bandpass_COMPLEX(low_frequency,
109 zcvec = newvec_COMPLEX(fftlen, "filter z vec in setFilter");
110 ptmp = fftw_create_plan(fftlen, FFTW_FORWARD, uni.wisdom.bits);
112 for (i = 0; i < ncoef; i++)
113 zcvec[i] = tx.filt.coef->coef[i];
115 for (i = 0; i < ncoef; i++)
116 zcvec[fftlen - ncoef + i] = tx.filt.coef->coef[i];
119 (fftw_complex *) zcvec,
120 (fftw_complex *) tx.filt.ovsv->zfvec);
121 fftw_destroy_plan(ptmp);
122 delvec_COMPLEX(zcvec);
123 normalize_vec_COMPLEX(tx.filt.ovsv->zfvec,
124 tx.filt.ovsv->fftlen);
125 memcpy((char *) tx.filt.save,
126 (char *) tx.filt.ovsv->zfvec,
127 tx.filt.ovsv->fftlen * sizeof(COMPLEX));
133 setFilter(int n, char **p) {
134 if (n == 2) return setRXFilter(n, p);
136 int trx = atoi(p[2]);
137 if (trx == RX) return setRXFilter(n, p);
138 else if (trx == TX) return setTXFilter(n, p);
143 // setMode <mode> [TRX]
145 setMode(int n, char **p) {
146 int mode = atoi(p[0]);
148 int trx = atoi(p[1]);
150 case TX: tx.mode = mode; break;
152 default: rx[RL].mode = mode; break;
155 tx.mode = rx[RL].mode = uni.mode.sdr = mode;
156 if (rx[RL].mode == AM) rx[RL].am.gen->mode = AMdet;
157 if (rx[RL].mode == SAM) rx[RL].am.gen->mode = SAMdet;
161 // setOsc <freq> [TRX]
163 setOsc(int n, char **p) {
164 REAL newfreq = atof(p[0]);
165 if (fabs(newfreq) >= 0.5 * uni.samplerate) return -1;
166 newfreq *= 2.0 * M_PI / uni.samplerate;
168 int trx = atoi(p[1]);
170 case TX: tx.osc.gen->Frequency = newfreq; break;
172 default: rx[RL].osc.gen->Frequency = newfreq; break;
175 tx.osc.gen->Frequency = rx[RL].osc.gen->Frequency = newfreq;
180 setSampleRate(int n, char **p) {
181 REAL samplerate = atof(p[0]);
182 uni.samplerate = samplerate;
187 setNR(int n, char **p) {
188 rx[RL].anr.flag = atoi(p[0]);
193 setANF(int n, char **p) {
194 rx[RL].anf.flag = atoi(p[0]);
199 setNB(int n, char **p) {
200 rx[RL].nb.flag = atoi(p[0]);
205 setNBvals(int n, char **p) {
206 REAL threshold = atof(p[0]);
207 rx[RL].nb.gen->threshold = rx[RL].nb.thresh = threshold;
212 setSDROM(int n, char **p) {
213 rx[RL].nb_sdrom.flag = atoi(p[0]);
218 setSDROMvals(int n, char **p) {
219 REAL threshold = atof(p[0]);
220 rx[RL].nb_sdrom.gen->threshold = rx[RL].nb_sdrom.thresh = threshold;
225 setBIN(int n, char **p) {
226 rx[RL].bin.flag = atoi(p[0]);
230 // setfixedAGC <gain> [TRX]
232 setfixedAGC(int n, char **p) {
233 REAL gain = atof(p[0]);
235 int trx = atoi(p[1]);
237 case TX: tx.agc.gen->gain.now = gain; break;
239 default: rx[RL].agc.gen->gain.now = gain; break;
242 tx.agc.gen->gain.now = rx[RL].agc.gen->gain.now = gain;
247 setRXAGC(int n, char **p) {
248 int setit = atoi(p[0]);
251 rx[RL].agc.gen->mode = agcOFF;
252 rx[RL].agc.flag = TRUE;
255 rx[RL].agc.gen->mode = agcSLOW;
256 rx[RL].agc.gen->hang = 10;
257 rx[RL].agc.flag = TRUE;
260 rx[RL].agc.gen->mode = agcMED;
261 rx[RL].agc.gen->hang = 6;
262 rx[RL].agc.flag = TRUE;
265 rx[RL].agc.gen->mode = agcFAST;
266 rx[RL].agc.gen->hang = 3;
267 rx[RL].agc.flag = TRUE;
270 rx[RL].agc.gen->mode = agcLONG;
271 rx[RL].agc.gen->hang = 23;
272 rx[RL].agc.flag = TRUE;
279 setRXAGCCompression(int n, char **p) {
280 REAL rxcompression = atof(p[0]);
281 rx[RL].agc.gen->gain.top = pow(10.0 , rxcompression * 0.05);
286 setRXAGCHang(int n, char **p) {
287 int hang = atoi(p[0]);
288 rx[RL].agc.gen->hang =
291 hang * uni.samplerate / (1e3 * uni.buflen)));
296 setRXAGCLimit(int n, char **p) {
297 REAL limit = atof(p[0]);
298 rx[RL].agc.gen->gain.lim = 0.001 * limit;
303 setTXAGC(int n, char **p) {
304 int setit = atoi(p[0]);
307 tx.agc.gen->mode = agcOFF;
311 tx.agc.gen->mode = agcSLOW;
312 tx.agc.gen->hang = 10;
316 tx.agc.gen->mode = agcMED;
317 tx.agc.gen->hang = 6;
321 tx.agc.gen->mode = agcFAST;
322 tx.agc.gen->hang = 3;
326 tx.agc.gen->mode = agcLONG;
327 tx.agc.gen->hang = 23;
335 setTXAGCCompression(int n, char **p) {
336 REAL txcompression = atof(p[0]);
337 tx.agc.gen->gain.top = pow(10.0 , txcompression * 0.05);
342 setTXAGCFF(int n, char **p) {
343 tx.spr.flag = atoi(p[0]);
348 setTXAGCFFCompression(int n, char **p) {
349 REAL txcompression = atof(p[0]);
350 tx.spr.gen->MaxGain = pow(10.0 , txcompression * 0.05);
355 setTXAGCHang(int n, char **p) {
356 int hang = atoi(p[0]);
360 hang * uni.samplerate / (1e3 * uni.buflen)));
365 setTXAGCLimit(int n, char **p) {
366 REAL limit = atof(p[0]);
367 tx.agc.gen->gain.lim = 0.001 * limit;
372 setTXSpeechCompression(int n, char **p) {
373 tx.spr.flag = atoi(p[0]);
378 setTXSpeechCompressionGain(int n, char **p) {
379 tx.spr.gen->MaxGain = dB2lin(atof(p[0]));
383 //============================================================
384 // some changes have been made to a transfer function in vec;
385 // apply time-domain window to counter possible artifacts
388 re_window(COMPLEX *vec, int len) {
390 REAL *win = newvec_REAL(len, "re_window win vec");
391 COMPLEX *ztmp = newvec_COMPLEX(len, "re_window z buf");
393 fftw_plan ptmp = fftw_create_plan(len, FFTW_BACKWARD, uni.wisdom.bits);
394 fftw_one(ptmp, (fftw_complex *) vec, (fftw_complex *) ztmp);
395 fftw_destroy_plan(ptmp);
397 (void) makewindow(BLACKMANHARRIS_WINDOW, len, win);
399 for (i = 0; i < len; i++)
400 ztmp[i] = Cscl(ztmp[i], win[i]);
402 ptmp = fftw_create_plan(len, FFTW_FORWARD, uni.wisdom.bits);
403 fftw_one(ptmp, (fftw_complex *) ztmp, (fftw_complex *) vec);
404 fftw_destroy_plan(ptmp);
406 delvec_COMPLEX(ztmp);
409 normalize_vec_COMPLEX(vec, len);
412 //============================================================
416 REAL fix = tx.filt.ovsv->fftlen * f / uni.samplerate;
417 return (int) (fix + 0.5);
420 //------------------------------------------------------------
423 apply_txeq_band(REAL lof, REAL dB, REAL hif) {
427 l = tx.filt.ovsv->fftlen;
429 COMPLEX *src = tx.filt.save,
430 *trg = tx.filt.ovsv->zfvec;
431 for (i = lox; i < hix; i++) {
432 trg[i] = Cscl(src[i], g);
435 trg[j] = Cscl(src[j], g);
441 // 0 dB1 75 dB2 150 dB3 300 dB4 600 dB5 1200 dB6 2000 dB7 2800 dB8 3600
442 // approximates W2IHY bandcenters.
443 // no args, revert to no EQ.
444 // NB these are shelves, not linear or other splines
447 setTXEQ(int n, char **p) {
450 memcpy((char *) tx.filt.ovsv->zfvec,
451 (char *) tx.filt.save,
452 tx.filt.ovsv->fftlen * sizeof(COMPLEX));
456 REAL lof = atof(p[0]);
457 for (i = 0; i < n - 2; i += 2) {
458 REAL dB = atof(p[i + 1]),
459 hif = atof(p[i + 2]);
460 if (lof < 0.0 || hif <= lof) return -1;
461 apply_txeq_band(lof, dB, hif);
464 re_window(rx[RL].filt.ovsv->zfvec, rx[RL].filt.ovsv->fftlen);
469 //------------------------------------------------------------
472 apply_rxeq_band(REAL lof, REAL dB, REAL hif) {
476 l = rx[RL].filt.ovsv->fftlen;
478 COMPLEX *src = rx[RL].filt.save,
479 *trg = rx[RL].filt.ovsv->zfvec;
480 for (i = lox; i < hix; i++) {
481 trg[i] = Cscl(src[i], g);
484 trg[j] = Cscl(src[j], g);
490 setRXEQ(int n, char **p) {
493 memcpy((char *) rx[RL].filt.ovsv->zfvec,
494 (char *) rx[RL].filt.save,
495 rx[RL].filt.ovsv->fftlen * sizeof(COMPLEX));
499 REAL lof = atof(p[0]);
500 for (i = 0; i < n - 2; i += 2) {
501 REAL dB = atof(p[i + 1]),
502 hif = atof(p[i + 2]);
503 if (lof < 0.0 || hif <= lof) return -1;
504 apply_rxeq_band(lof, dB, hif);
507 re_window(rx[RL].filt.ovsv->zfvec, rx[RL].filt.ovsv->fftlen);
512 //============================================================
515 setANFvals(int n, char **p) {
516 int taps = atoi(p[0]),
518 REAL gain = atof(p[2]),
520 rx[RL].anf.gen->adaptive_filter_size = taps;
521 rx[RL].anf.gen->delay = delay;
522 rx[RL].anf.gen->adaptation_rate = gain;
523 rx[RL].anf.gen->leakage = leak;
528 setNRvals(int n, char **p) {
529 int taps = atoi(p[0]),
531 REAL gain = atof(p[2]),
533 rx[RL].anr.gen->adaptive_filter_size = taps;
534 rx[RL].anr.gen->delay = delay;
535 rx[RL].anr.gen->adaptation_rate = gain;
536 rx[RL].anr.gen->leakage = leak;
541 setcorrectIQ(int n, char **p) {
542 int phaseadjustment = atoi(p[0]),
543 gainadjustment = atoi(p[1]);
544 rx[RL].iqfix->phase = 0.001 * (REAL) phaseadjustment;
545 rx[RL].iqfix->gain = 1.0+ 0.001 * (REAL) gainadjustment;
550 setcorrectIQphase(int n, char **p) {
551 int phaseadjustment = atoi(p[0]);
552 rx[RL].iqfix->phase = 0.001 * (REAL) phaseadjustment;
557 setcorrectIQgain(int n, char **p) {
558 int gainadjustment = atoi(p[0]);
559 rx[RL].iqfix->gain = 1.0 + 0.001 * (REAL) gainadjustment;
564 setSquelch(int n, char **p) {
565 rx[RL].squelch.thresh = atof(p[0]);
570 setSquelchSt(int n, char **p) {
571 rx[RL].squelch.flag = atoi(p[0]);
576 setTRX(int n, char **p) {
577 uni.mode.trx = atoi(p[0]);
582 setRunState(int n, char **p) {
583 RUNMODE rs = (RUNMODE) atoi(p[0]);
589 setSpotToneVals(int n, char **p) {
590 REAL gain = atof(p[0]),
594 setSpotToneGenVals(rx[RL].spot.gen, gain, freq, rise, fall);
599 setSpotTone(int n, char **p) {
601 SpotToneOn(rx[RL].spot.gen);
602 rx[RL].spot.flag = TRUE;
604 SpotToneOff(rx[RL].spot.gen);
609 setRXPreScl(int n, char **p) {
610 rx[RL].scl.pre.flag = atoi(p[0]);
615 setRXPreSclVal(int n, char **p) {
616 rx[RL].scl.pre.val = dB2lin(atof(p[0]));
621 setTXPreScl(int n, char **p) {
622 tx.scl.pre.flag = atoi(p[0]);
627 setTXPreSclVal(int n, char **p) {
628 tx.scl.pre.val = dB2lin(atof(p[0]));
633 setRXPostScl(int n, char **p) {
634 rx[RL].scl.post.flag = atoi(p[0]);
639 setRXPostSclVal(int n, char **p) {
640 rx[RL].scl.post.val = dB2lin(atof(p[0]));
645 setTXPostScl(int n, char **p) {
646 tx.scl.post.flag = atoi(p[0]);
651 setTXPostSclVal(int n, char **p) {
652 tx.scl.post.val = dB2lin(atof(p[0]));
657 setFinished(int n, char **p) {
659 pthread_cancel(top.thrd.trx.id);
660 pthread_cancel(top.thrd.mon.id);
661 pthread_cancel(top.thrd.pws.id);
662 pthread_cancel(top.thrd.mtr.id);
663 pthread_cancel(top.thrd.upd.id);
667 // next-trx-mode [nbufs-to-zap]
669 setSWCH(int n, char **p) {
670 top.swch.trx.next = atoi(p[0]);
671 if (n > 1) top.swch.bfct.want = atoi(p[1]);
672 else top.swch.bfct.want = 0;
673 top.swch.bfct.have = 0;
674 top.swch.run.last = top.state;
675 top.state = RUN_SWCH;
680 setMonDump(int n, char **p) {
681 sem_post(&top.sync.mon.sem);
686 setRingBufferReset(int n, char **p) {
687 extern void clear_jack_ringbuffer(jack_ringbuffer_t *rb, int nbytes);
688 jack_ringbuffer_reset(top.jack.ring.i.l);
689 jack_ringbuffer_reset(top.jack.ring.i.r);
690 jack_ringbuffer_reset(top.jack.ring.o.l);
691 jack_ringbuffer_reset(top.jack.ring.o.r);
692 clear_jack_ringbuffer(top.jack.ring.o.l, top.hold.size.bytes);
693 clear_jack_ringbuffer(top.jack.ring.o.r, top.hold.size.bytes);
698 setRXListen(int n, char **p) {
699 int lis = atoi(p[0]);
700 if (lis < 0 || lis >= uni.multirx.nrx)
703 uni.multirx.lis = lis;
709 setRXOn(int n, char **p) {
711 if (uni.multirx.act[RL])
714 uni.multirx.act[RL] = TRUE;
721 if (k < 0 || k >= uni.multirx.nrx)
724 if (uni.multirx.act[k])
727 uni.multirx.act[k] = TRUE;
737 setRXOff(int n, char **p) {
739 if (!uni.multirx.act[RL])
742 uni.multirx.act[RL] = FALSE;
748 if (k < 0 || k >= uni.multirx.nrx)
751 if (!uni.multirx.act[k])
754 uni.multirx.act[k] = FALSE;
762 // [pos] 0.0 <= pos <= 1.0
764 setRXPan(int n, char **p) {
768 theta = (1.0 - pos) * M_PI / 2.0;
769 rx[RL].azim = Cmplx(cos(theta), sin(theta));
772 if ((pos = atof(p[0])) < 0.0 || pos > 1.0)
774 theta = (1.0 - pos) * M_PI / 2.0;
775 rx[RL].azim = Cmplx(cos(theta), sin(theta));
781 setAuxMixSt(int n, char **p) {
783 uni.mix.rx.flag = uni.mix.tx.flag = FALSE;
786 BOOLEAN flag = atoi(p[0]);
788 switch (atoi(p[1])) {
789 case TX: uni.mix.tx.flag = flag; break;
791 default: uni.mix.rx.flag = flag; break;
794 uni.mix.rx.flag = uni.mix.tx.flag = flag;
799 // [dB] NB both channels
801 setAuxMixGain(int n, char **p) {
803 uni.mix.rx.gain = uni.mix.tx.gain = 1.0;
806 REAL gain = dB2lin(atof(p[0]));
808 switch (atoi(p[1])) {
809 case TX: uni.mix.tx.gain = gain; break;
811 default: uni.mix.rx.gain = gain; break;
814 uni.mix.rx.gain = uni.mix.tx.gain = gain;
820 setCompandSt(int n, char **p) {
825 BOOLEAN flag = atoi(p[0]);
827 switch (atoi(p[1])) {
828 case RX: rx[RL].cpd.flag = flag; break;
830 default: tx.cpd.flag = flag; break;
839 setCompand(int n, char **p) {
843 REAL fac = atof(p[0]);
845 switch (atoi(p[1])) {
846 case RX: WSCReset(rx[RL].cpd.gen, fac); break;
848 default: WSCReset(tx.cpd.gen, fac); break;
851 WSCReset(tx.cpd.gen, fac);
856 //------------------------------------------------------------------------
860 setMeterType(int n, char **p) {
862 uni.meter.rx.type = SIGNAL_STRENGTH;
864 METERTYPE type = (METERTYPE) atoi(p[0]);
866 int trx = atoi(p[1]);
868 case TX: uni.meter.tx.type = type; break;
870 default: uni.meter.rx.type = type; break;
873 uni.meter.rx.type = type;
878 // setSpectrumType [type [scale [rx]]]
880 setSpectrumType(int n, char **p) {
881 uni.spec.type = SPEC_POST_FILT;
882 uni.spec.scale = SPEC_PWR;
886 uni.spec.rxk = atoi(p[2]);
888 uni.spec.scale = atoi(p[1]);
891 uni.spec.type = atoi(p[0]);
898 return uni.spec.type;
902 setDCBlockSt(int n, char **p) {
907 tx.dcb.flag = atoi(p[0]);
913 setDCBlock(int n, char **p) {
917 resetDCBlocker(tx.dcb.gen, atoi(p[0]));
922 //========================================================================
924 // save current state while guarded by upd sem
926 reqMeter(int n, char **p) {
927 snap_meter(&uni.meter, n > 0 ? atoi(p[0]) : 0);
928 sem_post(&top.sync.mtr.sem);
934 reqSpectrum(int n, char **p) {
935 snap_spectrum(&uni.spec, n > 0 ? atoi(p[0]) : 0);
936 sem_post(&top.sync.pws.sem);
940 //========================================================================
944 CTE update_cmds[] = {
945 {"reqMeter", reqMeter},
946 {"reqSpectrum", reqSpectrum},
948 {"setANFvals", setANFvals},
950 {"setFilter", setFilter},
951 {"setFinished", setFinished},
952 {"setMode", setMode},
954 {"setNBvals", setNBvals},
956 {"setNRvals", setNRvals},
958 {"setRXAGC", setRXAGC},
959 {"setRXAGCCompression", setRXAGCCompression},
960 {"setRXAGCHang", setRXAGCHang},
961 {"setRXAGCLimit", setRXAGCLimit},
962 {"setRXEQ", setRXEQ},
963 {"setRXPostScl", setRXPostScl},
964 {"setRXPostSclVal", setRXPostSclVal},
965 {"setRXPreScl", setRXPreScl},
966 {"setRXPreSclVal", setRXPreSclVal},
967 {"setRunState", setRunState},
968 {"setSDROM", setSDROM},
969 {"setSDROMvals",setSDROMvals},
970 {"setSWCH", setSWCH},
971 {"setSampleRate", setSampleRate},
972 {"setSpotTone", setSpotTone},
973 {"setSpotToneVals", setSpotToneVals},
974 {"setSquelch", setSquelch},
975 {"setSquelchSt", setSquelchSt},
977 {"setTXAGC", setTXAGC},
978 {"setTXAGCCompression", setTXAGCCompression},
979 {"setTXAGCFFCompression",setTXAGCFFCompression},
980 {"setTXAGCHang", setTXAGCHang},
981 {"setTXAGCLimit", setTXAGCLimit},
982 {"setTXEQ", setTXEQ},
983 {"setTXPostScl", setTXPostScl},
984 {"setTXPostSclVal", setTXPostSclVal},
985 {"setTXPreScl", setTXPreScl},
986 {"setTXPreSclVal", setTXPreSclVal},
987 {"setTXSpeechCompression", setTXSpeechCompression},
988 {"setTXSpeechCompressionGain", setTXSpeechCompressionGain},
989 {"setcorrectIQ", setcorrectIQ},
990 {"setcorrectIQgain", setcorrectIQgain},
991 {"setcorrectIQphase", setcorrectIQphase},
992 {"setfixedAGC", setfixedAGC},
993 {"setMonDump", setMonDump},
994 {"setRingBufferReset", setRingBufferReset},
995 {"setRXListen", setRXListen},
996 {"setRXOn", setRXOn},
997 {"setRXOff", setRXOff},
998 {"setRXPan", setRXPan},
999 {"setAuxMixSt", setAuxMixSt},
1000 {"setAuxMixGain", setAuxMixGain},
1001 {"setCompandSt", setCompandSt},
1002 {"setCompand", setCompand},
1003 {"setMeterType", setMeterType},
1004 {"setSpectrumType", setSpectrumType},
1005 {"setDCBlockSt", setDCBlockSt},
1006 {"setDCBlock", setDCBlock},
1010 //........................................................................
1013 do_update(char *str, FILE *log) {
1014 BOOLEAN quiet = FALSE;
1015 SPLIT splt = &uni.update.splt;
1024 if (NF(splt) < 1) return -1;
1027 Thunk thk = Thunk_lookup(update_cmds, F(splt, 0));
1028 if (!thk) return -1;
1032 sem_wait(&top.sync.upd.sem);
1033 val = (*thk)(NF(splt) - 1, Fptr(splt, 1));
1034 sem_post(&top.sync.upd.sem);
1036 if (log && !quiet) {
1038 char *s = since(&top.start_tv);
1039 fprintf(log, "update[%s]: returned %d from", s, val);
1040 for (i = 0; i < NF(splt); i++)
1041 fprintf(log, " %s", F(splt, i));