3 This file is part of a program that implements a Software-Defined Radio.
5 Copyright (C) 2004-5 by Frank Brickle, AB2KT and Bob McGwier, N4HY
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 The authors can be reached by email at
29 The DTTS Microwave Society
36 /////////////////////////////////////////////////////////////////////////
40 PRIVATE CRITICAL_SECTION csobj;
41 PRIVATE CRITICAL_SECTION cs_updobj;
42 PRIVATE LPCRITICAL_SECTION cs;
43 PRIVATE LPCRITICAL_SECTION cs_upd;
44 PRIVATE BOOLEAN IC=FALSE;
46 // elementary defaults
49 /////////////////////////////////////////////////////////////////////////
50 // most of what little we know here about the inner loop,
51 // functionally speaking
53 extern void reset_meters(void);
54 extern void reset_spectrum(void);
55 extern void reset_counters(void);
56 extern void process_samples(float *, float *, float *, float *, int);
57 extern void setup_workspace(void);
58 extern void destroy_workspace(void);
60 //========================================================================
63 spectrum_thread(void) {
64 DWORD NumBytesWritten;
66 sem_wait(&top.sync.pws.sem);
67 compute_spectrum(&uni.spec);
68 WriteFile(top.meas.spec.fd,(LPVOID)&uni.spec.label,
69 sizeof(int),&NumBytesWritten,NULL);
70 WriteFile(top.meas.spec.fd,(LPVOID)uni.spec.output,
71 sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
78 DWORD NumBytesWritten;
80 sem_wait(&top.sync.scope.sem);
81 compute_spectrum(&uni.spec);
82 WriteFile(top.meas.scope.fd,(LPVOID)&uni.spec.label,
83 sizeof(int),&NumBytesWritten,NULL);
84 WriteFile(top.meas.scope.fd,(LPVOID)uni.spec.accum,
85 sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
92 DWORD NumBytesWritten;
94 sem_wait(&top.sync.mtr.sem);
95 WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.label, sizeof(int),&NumBytesWritten,NULL);
96 WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.snap.rx,sizeof(REAL)*MAXRX * RXMETERPTS,&NumBytesWritten,NULL);
97 WriteFile(top.meas.mtr.fd,(LPVOID)&uni.meter.snap.tx,sizeof(REAL)*TXMETERPTS,&NumBytesWritten,NULL);
102 //========================================================================
105 monitor_thread(void) {
106 while (top.running) {
107 sem_wait(&top.sync.mon.sem);
108 /* If there is anything that needs monitoring, do it here */
110 "@@@ mon [%d]: cb = %d rbi = %d rbo = %d xr = %d\n",
116 memset((char *) &top.jack.blow, 0, sizeof(top.jack.blow));
122 //========================================================================
125 process_updates_thread(void) {
127 while (top.running) {
129 pthread_testcancel();
130 while (ReadFile(top.parm.fd,top.parm.buff,256,&NumBytesRead,NULL))
132 fprintf(stderr,"Update Bytes:%lu Msg:%s\n",NumBytesRead,top.parm.buff),fflush(stderr);
133 if (NumBytesRead != 0) do_update(top.parm.buff, top.verbose ? stderr : 0);
139 //========================================================================
144 EnterCriticalSection(cs);
145 if (ringb_write_space(top.jack.ring.o.l)
146 < top.hold.size.bytes) {
148 ringb_reset(top.jack.ring.o.l);
149 ringb_reset(top.jack.ring.o.r);
150 top.jack.blow.rb.o++;
152 ringb_write(top.jack.ring.o.l,
153 (char *) top.hold.buf.l,
154 top.hold.size.bytes);
155 ringb_write(top.jack.ring.o.r,
156 (char *) top.hold.buf.r,
157 top.hold.size.bytes);
158 if (ringb_read_space(top.jack.ring.i.l)
159 < top.hold.size.bytes) {
161 ringb_reset(top.jack.ring.i.l);
162 ringb_reset(top.jack.ring.i.r);
163 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
164 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
165 ringb_reset(top.jack.auxr.i.l);
166 ringb_reset(top.jack.auxr.i.r);
167 memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
168 memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
169 top.jack.blow.rb.i++;
171 ringb_read(top.jack.ring.i.l,
172 (char *) top.hold.buf.l,
173 top.hold.size.bytes);
174 ringb_read(top.jack.ring.i.r,
175 (char *) top.hold.buf.r,
176 top.hold.size.bytes);
177 ringb_read(top.jack.auxr.i.l,
178 (char *) top.hold.aux.l,
179 top.hold.size.bytes);
180 ringb_read(top.jack.auxr.i.r,
181 (char *) top.hold.aux.r,
182 top.hold.size.bytes);
184 LeaveCriticalSection(cs);
190 EnterCriticalSection(cs);
191 answer = (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes);
192 LeaveCriticalSection(cs);
197 //------------------------------------------------------------------------
201 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
202 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
203 memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
204 memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
209 run_pass(void) { uni.tick++; }
213 process_samples(top.hold.buf.l, top.hold.buf.r,
214 top.hold.aux.l, top.hold.aux.r,
215 top.hold.size.frames);
218 // NB do not set RUN_SWCH directly via setRunState;
219 // use setSWCH instead
223 if (top.swch.bfct.have == 0) {
226 int i, m = top.swch.fade, n = top.swch.tail;
227 for (i = 0; i < m; i++) {
228 float w = (float) 1.0 - (float) i / m;
229 top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
231 memset((char *) (top.hold.buf.l + m), 0, n);
232 memset((char *) (top.hold.buf.r + m), 0, n);
233 top.swch.bfct.have++;
234 } else if (top.swch.bfct.have < top.swch.bfct.want) {
236 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
237 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
238 top.swch.bfct.have++;
242 int i, m = top.swch.fade, n = top.swch.tail;
243 for (i = 0; i < m; i++) {
244 float w = (float) i / m;
245 top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
247 uni.mode.trx = top.swch.trx.next;
248 switch (uni.mode.trx) {
251 tx.agc.gen->over = tx.tick + 3;
254 for(i=0;i<uni.multirx.nrx;i++) rx[i].agc.gen->over = rx[i].tick + 3;
258 top.state = top.swch.run.last;
259 top.swch.bfct.want = top.swch.bfct.have = 0;
261 ringb_reset(top.jack.ring.o.l);
262 ringb_reset(top.jack.ring.o.r);
263 ringb_clear(top.jack.ring.o.l,top.hold.size.bytes);
264 ringb_clear(top.jack.ring.o.r,top.hold.size.bytes);
271 process_samples(top.hold.buf.l, top.hold.buf.r,
272 top.hold.aux.l, top.hold.aux.r,
273 top.hold.size.frames);
276 //========================================================================
281 audio_callback(float *input_l, float *input_r, float *output_l, float *output_r,int nframes) {
282 size_t nbytes = sizeof(float)*nframes;
285 EnterCriticalSection(cs);
288 if (ringb_read_space(top.jack.ring.o.l) >= nbytes) {
289 ringb_read(top.jack.ring.o.l, (char *) output_l, nbytes);
290 ringb_read(top.jack.ring.o.r, (char *) output_r, nbytes);
291 } else { // rb pathology
292 memset((char *) output_l, 0, nbytes);
293 memset((char *) output_r, 0, nbytes);
294 ringb_restart(top.jack.ring.o.l, nbytes);
295 ringb_restart(top.jack.ring.o.r, nbytes);
296 top.jack.blow.rb.o++;
299 // input: copy from port to ring
300 if (ringb_write_space(top.jack.ring.i.l) >= nbytes) {
301 ringb_write(top.jack.ring.i.l, (char *) input_l, nbytes);
302 ringb_write(top.jack.ring.i.r, (char *) input_r, nbytes);
303 ringb_write(top.jack.auxr.i.l, (char *) input_l, nbytes);
304 ringb_write(top.jack.auxr.i.r, (char *) input_r, nbytes);
305 } else { // rb pathology
306 ringb_restart(top.jack.ring.i.l, nbytes);
307 ringb_restart(top.jack.ring.i.r, nbytes);
308 ringb_restart(top.jack.auxr.i.l, nbytes);
309 ringb_restart(top.jack.auxr.i.r, nbytes);
310 top.jack.blow.rb.i++;
312 LeaveCriticalSection(cs);
313 // if enough accumulated in ring, fire dsp
314 if (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes)
315 sem_post(&top.sync.buf.sem);
318 if ((top.jack.blow.cb > 0) ||
319 (top.jack.blow.rb.i > 0) ||
320 (top.jack.blow.rb.o > 0))
321 sem_post(&top.sync.mon.sem);
324 //========================================================================
327 process_samples_thread(void) {
328 while (top.running) {
329 sem_wait(&top.sync.buf.sem);
332 sem_wait(&top.sync.upd.sem);
334 case RUN_MUTE: run_mute(); break;
335 case RUN_PASS: run_pass(); break;
336 case RUN_PLAY: run_play(); break;
337 case RUN_SWCH: run_swch(); break;
339 sem_post(&top.sync.upd.sem);
349 safefree((char *)top.jack.ring.o.r);
350 safefree((char *)top.jack.ring.o.l);
351 safefree((char *)top.jack.ring.i.r);
352 safefree((char *)top.jack.ring.i.l);
353 safefree((char *)top.jack.auxr.i.l);
354 safefree((char *)top.jack.auxr.i.r);
355 safefree((char *)top.jack.auxr.o.l);
356 safefree((char *)top.jack.auxr.o.r);
358 CloseHandle(top.parm.fp);
359 DisconnectNamedPipe(top.parm.fd);
360 CloseHandle(top.parm.fd);
363 if (uni.meter.flag) {
364 CloseHandle(top.meas.mtr.fp);
365 DisconnectNamedPipe(top.meas.mtr.fd);
366 CloseHandle(top.meas.mtr.fd);
370 CloseHandle(top.meas.spec.fp);
371 DisconnectNamedPipe(top.meas.spec.fd);
372 CloseHandle(top.meas.spec.fd);
377 //........................................................................
380 setup_switching(void) {
381 top.swch.fade = (int) (0.1 * uni.buflen + 0.5);
382 top.swch.tail = (top.hold.size.frames - top.swch.fade) * sizeof(float);
386 setup_local_audio(void) {
387 top.hold.size.frames = uni.buflen;
388 top.hold.size.bytes = top.hold.size.frames * sizeof(float);
389 top.hold.buf.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
390 "main hold buffer left");
391 top.hold.buf.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
392 "main hold buffer right");
393 top.hold.aux.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
394 "aux hold buffer left");
395 top.hold.aux.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
396 "aux hold buffer right");
402 DisplayErrorText(DWORD dwLastError)
404 HMODULE hModule = NULL; // default to system source
406 DWORD dwBufferLength;
408 DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
409 FORMAT_MESSAGE_IGNORE_INSERTS |
410 FORMAT_MESSAGE_FROM_SYSTEM ;
413 // If dwLastError is in the network range,
414 // load the message source.
417 if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
418 hModule = LoadLibraryEx(
421 LOAD_LIBRARY_AS_DATAFILE
425 dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
429 // Call FormatMessage() to allow for message
430 // text to be acquired from the system
431 // or from the supplied module handle.
434 if(dwBufferLength = FormatMessageA(
436 hModule, // module to get message from (NULL == system)
438 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
439 (LPSTR) &MessageBuffer,
444 DWORD dwBytesWritten;
447 // Output message string on stderr.
450 GetStdHandle(STD_ERROR_HANDLE),
458 // Free the buffer allocated by the system.
460 LocalFree(MessageBuffer);
464 // If we loaded a message source, unload it.
467 FreeLibrary(hModule);
472 PRIVATE sem_t setup_update_sem;
474 PRIVATE void setup_update_server()
477 if (INVALID_HANDLE_VALUE == (top.parm.fd = CreateNamedPipe(top.parm.path,
479 PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
480 PIPE_UNLIMITED_INSTANCES,
486 fprintf(stderr,"Update server pipe setup failed:\n"),fflush(stderr);
487 DisplayErrorText(GetLastError());
489 // fprintf(stderr,"Update NamedPipe made\n"),fflush(stderr);
490 sem_post(&setup_update_sem);
491 if (ConnectNamedPipe(top.parm.fd,NULL))
493 // fprintf(stderr,"Connected the server to the Update pipe\n"),fflush(stderr);
495 fprintf(stderr,"Connected the server to the Update pipe failed\n"),fflush(stderr);
496 DisplayErrorText(GetLastError());
502 PRIVATE void setup_update_client()
504 // fprintf(stderr,"Looking for the Update server\n"),fflush(stderr);
505 WaitNamedPipe(top.parm.path,INFINITE);
506 // fprintf(stderr,"Found the Update server\n"),fflush(stderr);
507 if (INVALID_HANDLE_VALUE == (top.parm.fp = CreateFile(top.parm.path,
508 GENERIC_WRITE, 0, NULL,
509 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
511 fprintf(stderr,"The Update Client Open Failed\n"),fflush(stderr);
512 DisplayErrorText(GetLastError());
514 sem_post(&setup_update_sem);
517 WriteFile(top.parm.fp,"test",5,&numwritten,NULL);
518 fprintf(stderr,"Number written to server: %lu\n",numwritten),fflush(stderr);
523 PRIVATE void setup_meter_server()
525 top.meas.mtr.fd = CreateNamedPipe(top.meas.mtr.path,
526 PIPE_ACCESS_OUTBOUND,
527 PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
528 PIPE_UNLIMITED_INSTANCES,
533 // fprintf(stderr,"meter handle = %08X\n",(DWORD)top.meas.mtr.fd),fflush(stderr);
534 if (top.meas.mtr.fd == INVALID_HANDLE_VALUE)
536 fprintf(stderr,"Meter server pipe setup failed:\n"),fflush(stderr);
537 DisplayErrorText(GetLastError());
539 // fprintf(stderr,"Meter Pipe Connect succeeded\n"),fflush(stderr);
540 sem_post(&setup_update_sem);
541 if (ConnectNamedPipe(top.meas.mtr.fd,NULL)) {
542 // fprintf(stderr,"Connected the Meter Pooch\n"),fflush(stderr);
544 fprintf(stderr,"Meter Pipe Connect failed\n"),fflush(stderr);
545 DisplayErrorText(GetLastError());
551 PRIVATE void setup_meter_client()
553 // fprintf(stderr,"Looking for the meter server\n"),fflush(stderr);
554 if (WaitNamedPipe(top.meas.mtr.path,INFINITE)) {
555 // fprintf(stderr,"Found the Meter server\n"),fflush(stderr);
556 if (INVALID_HANDLE_VALUE == (top.meas.mtr.fp = CreateFile(top.meas.mtr.path,
557 GENERIC_READ, 0, NULL,
558 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
560 fprintf(stderr,"The Meter Client Open Failed\n"),fflush(stderr);
561 DisplayErrorText(GetLastError());
563 // fprintf(stderr,"The Meter Client Open Succeeded\n"),fflush(stderr);
566 fprintf(stderr,"Wait for meter pipe failed: Error message %d\n",GetLastError()),fflush(stderr);
568 sem_post(&setup_update_sem);
572 PRIVATE void setup_spec_server()
575 if (INVALID_HANDLE_VALUE == (top.meas.spec.fd = CreateNamedPipe(top.meas.spec.path,
576 PIPE_ACCESS_OUTBOUND,
577 PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
578 PIPE_UNLIMITED_INSTANCES,
584 fprintf(stderr,"Spectrum pipe create failed\n"),fflush(stderr);
585 DisplayErrorText(GetLastError());
587 // fprintf(stderr,"Spectrum Pipe %s Create succeeded\n",top.meas.spec.path),fflush(stderr);
588 sem_post(&setup_update_sem);
589 if (ConnectNamedPipe(top.meas.spec.fd,NULL))
591 // fprintf(stderr,"Connected to the Spectrum Pipe\n"),fflush(stderr);
593 fprintf(stderr,"Spectrum pipe connect failed\n"),fflush(stderr);
594 DisplayErrorText(GetLastError());
600 PRIVATE void setup_spec_client()
602 // fprintf(stderr,"Looking for the spectrum server\n"),fflush(stderr);
603 if (WaitNamedPipe(top.meas.spec.path,INFINITE)) {
604 // fprintf(stderr,"Found the server\n"),fflush(stderr);
605 if (INVALID_HANDLE_VALUE == (top.meas.spec.fp = CreateFile(top.meas.spec.path,
606 GENERIC_READ, 0, NULL,
607 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)))
609 fprintf(stderr,"The Spectrum Client Open Failed\n"),fflush(stderr);
610 DisplayErrorText(GetLastError());
612 // fprintf(stderr,"The Spectrum Client Open Succeeded\n");
613 // fprintf(stderr,"Spec Read handle = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
616 fprintf(stderr,"Wait for spec pipe failed\n"),fflush(stderr);
617 DisplayErrorText(GetLastError());
619 sem_post(&setup_update_sem);
622 PRIVATE pthread_t id1,id2,id3,id4,id5,id6;
624 setup_updates(void) {
626 char mesg[16384]="TEST TEST METER\n";
628 top.parm.path = loc.path.parm;
629 sem_init(&setup_update_sem, 0, 0);
632 if (uni.meter.flag) {
633 top.meas.mtr.path = loc.path.meter;
636 top.meas.spec.path = loc.path.spec;
640 // Do this STUPID stuff to make use of the Named Pipe Mechanism in Windows
641 // For the update server
644 pthread_create(&id1, NULL, (void *) setup_update_server, NULL);
645 sem_wait(&setup_update_sem);
646 pthread_create(&id2, NULL, (void *) setup_update_client, NULL);
647 sem_wait(&setup_update_sem);
648 if (uni.meter.flag) {
649 pthread_create(&id3, NULL, (void *) setup_meter_server, NULL);
650 sem_wait(&setup_update_sem);
651 pthread_create(&id4, NULL, (void *) setup_meter_client, NULL);
652 sem_wait(&setup_update_sem);
653 /* if (WriteFile(top.meas.mtr.fd,mesg,strlen(mesg)+1,&NumBytes,NULL))
655 fprintf(stderr,"Meter Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
657 fprintf(stderr,"Meter Pipe write failed\n"),fflush(stderr);
658 DisplayErrorText(GetLastError());
660 if (ReadFile(top.meas.mtr.fp,mesg,256,&NumBytes,NULL))
662 fprintf(stderr,"Meter Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
663 fprintf(stderr,"Meter message %s",mesg),fflush(stderr);
665 fprintf(stderr,"Meter Pipe read failed\n"),fflush(stderr);
666 DisplayErrorText(GetLastError());
672 memset(mesg,0,16384);
673 pthread_create(&id5, NULL, (void *) setup_spec_server, NULL);
674 sem_wait(&setup_update_sem);
675 pthread_create(&id6, NULL, (void *) setup_spec_client, NULL);
676 sem_wait(&setup_update_sem);
678 /* if (WriteFile(top.meas.spec.fd,mesg,16384,&NumBytes,NULL))
680 fprintf(stderr,"Spec Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
682 fprintf(stderr,"Spec Pipe write failed\n"),fflush(stderr);
683 DisplayErrorText(GetLastError());
685 fprintf(stderr,"Spec Read handle(2) = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
686 if (ReadFile(top.meas.spec.fp,mesg,16384,&NumBytes,NULL))
688 fprintf(stderr,"Spec Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
690 fprintf(stderr,"Spec Pipe read failed\n"),fflush(stderr);
691 DisplayErrorText(GetLastError());
694 sem_destroy(&setup_update_sem);
697 setup_system_audio(void) {
700 sprintf(top.jack.name, "sdr-%d", top.pid);
701 top.jack.size = uni.buflen;
702 ringsize = top.hold.size.bytes * loc.mult.ring+sizeof(ringb_t);
703 usemem = safealloc(ringsize,1,"Ring Input Left");
704 top.jack.ring.i.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
706 usemem = safealloc(ringsize,1,"Ring Input Right");
707 top.jack.ring.i.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
709 usemem = safealloc(ringsize,1,"Ring Output Left");
710 top.jack.ring.o.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
712 usemem = safealloc(ringsize,1,"Ring Output Right");
713 top.jack.ring.o.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
715 usemem = safealloc(ringsize,1,"Ring Input Left Auxiliary");
716 top.jack.auxr.i.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
718 usemem = safealloc(ringsize,1,"Ring Input Right Auxiliary");
719 top.jack.auxr.i.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
721 usemem = safealloc(ringsize,1,"Ring Output Left Auxiliary");
722 top.jack.auxr.o.l = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
724 usemem = safealloc(ringsize,1,"Ring Output Right Auxiliary");
725 top.jack.auxr.o.r = ringb_create(usemem,top.hold.size.bytes * loc.mult.ring);
727 ringb_clear(top.jack.ring.o.l, top.jack.size * sizeof(float));
728 ringb_clear(top.jack.ring.o.r, top.jack.size * sizeof(float));
729 ringb_clear(top.jack.auxr.o.l, top.jack.size * sizeof(float));
730 ringb_clear(top.jack.auxr.o.r, top.jack.size * sizeof(float));
734 setup_threading(void) {
735 sem_init(&top.sync.upd.sem, 0, 0);
736 pthread_create(&top.thrd.upd.id, NULL, (void *) process_updates_thread, NULL);
737 sem_init(&top.sync.buf.sem, 0, 0);
738 pthread_create(&top.thrd.trx.id, NULL, (void *) process_samples_thread, NULL);
739 sem_init(&top.sync.mon.sem, 0, 0);
740 pthread_create(&top.thrd.mon.id, NULL, (void *) monitor_thread, NULL);
741 if (uni.meter.flag) {
742 sem_init(&top.sync.mtr.sem, 0, 0);
743 pthread_create(&top.thrd.mtr.id, NULL, (void *) meter_thread, NULL);
746 sem_init(&top.sync.pws.sem, 0, 0);
747 pthread_create(&top.thrd.pws.id, NULL, (void *) spectrum_thread, NULL);
750 InitializeCriticalSection(cs);
753 //========================================================================
754 // hard defaults, then environment
757 setup_defaults(void) {
758 loc.name[0] = 0; // no default name for jack client
759 strcpy(loc.path.rcfile, RCBASE);
760 strcpy(loc.path.parm, PARMPATH);
761 strcpy(loc.path.meter, METERPATH);
762 strcpy(loc.path.spec, SPECPATH);
763 strcpy(loc.path.wisdom, WISDOMPATH);
764 loc.def.rate = DEFRATE;
765 loc.def.size = DEFSIZE;
767 loc.def.mode = DEFMODE;
768 loc.def.spec = DEFSPEC;
769 loc.mult.ring = RINGMULT;
772 //========================================================================
777 top.pid = GetCurrentThreadId();
779 top.start_tv = now_tv();
782 top.state = RUN_PLAY;
786 uni.meter.flag = TRUE;
787 uni.spec.flag = TRUE;
793 setup_system_audio();
797 uni.spec.flag = TRUE;
798 uni.spec.type = SPEC_POST_FILT;
799 uni.spec.scale = SPEC_PWR;