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 //========================================================================
65 DWORD NumBytesWritten;
67 sem_wait(&top.sync.pws.sem);
68 compute_spectrum(&uni.spec);
69 WriteFile(top.meas.spec.fd, (LPVOID) & uni.spec.label,
70 sizeof(int), &NumBytesWritten, NULL);
71 WriteFile(top.meas.spec.fd, (LPVOID) uni.spec.output,
72 sizeof(float) * uni.spec.size, &NumBytesWritten, NULL);
79 DWORD NumBytesWritten;
81 sem_wait(&top.sync.scope.sem);
82 compute_spectrum(&uni.spec);
83 WriteFile(top.meas.scope.fd,(LPVOID)&uni.spec.label,
84 sizeof(int),&NumBytesWritten,NULL);
85 WriteFile(top.meas.scope.fd,(LPVOID)uni.spec.accum,
86 sizeof(float)*uni.spec.size,&NumBytesWritten,NULL);
94 DWORD NumBytesWritten;
96 sem_wait(&top.sync.mtr.sem);
97 WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.label, sizeof(int),
98 &NumBytesWritten, NULL);
99 WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.snap.rx,
100 sizeof(REAL) * MAXRX * RXMETERPTS, &NumBytesWritten, NULL);
101 WriteFile(top.meas.mtr.fd, (LPVOID) & uni.meter.snap.tx,
102 sizeof(REAL) * TXMETERPTS, &NumBytesWritten, NULL);
107 //========================================================================
112 while (top.running) {
113 sem_wait(&top.sync.mon.sem);
114 /* If there is anything that needs monitoring, do it here */
116 "@@@ mon [%d]: cb = %d rbi = %d rbo = %d xr = %d\n",
119 top.jack.blow.rb.i, top.jack.blow.rb.o, top.jack.blow.xr);
120 memset((char *) &top.jack.blow, 0, sizeof(top.jack.blow));
126 //========================================================================
129 process_updates_thread(void)
132 while (top.running) {
134 pthread_testcancel();
135 while (ReadFile(top.parm.fd, top.parm.buff, 256, &NumBytesRead, NULL)) {
136 fprintf(stderr, "Update Bytes:%lu Msg:%s\n", NumBytesRead,
137 top.parm.buff), fflush(stderr);
138 if (NumBytesRead != 0)
139 do_update(top.parm.buff, top.verbose ? stderr : 0);
145 //========================================================================
151 EnterCriticalSection(cs);
152 if (ringb_write_space(top.jack.ring.o.l)
153 < top.hold.size.bytes) {
155 ringb_reset(top.jack.ring.o.l);
156 ringb_reset(top.jack.ring.o.r);
157 top.jack.blow.rb.o++;
159 ringb_write(top.jack.ring.o.l,
160 (char *) top.hold.buf.l, top.hold.size.bytes);
161 ringb_write(top.jack.ring.o.r,
162 (char *) top.hold.buf.r, top.hold.size.bytes);
163 if (ringb_read_space(top.jack.ring.i.l)
164 < top.hold.size.bytes) {
166 ringb_reset(top.jack.ring.i.l);
167 ringb_reset(top.jack.ring.i.r);
168 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
169 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
170 ringb_reset(top.jack.auxr.i.l);
171 ringb_reset(top.jack.auxr.i.r);
172 memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
173 memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
174 top.jack.blow.rb.i++;
176 ringb_read(top.jack.ring.i.l,
177 (char *) top.hold.buf.l, top.hold.size.bytes);
178 ringb_read(top.jack.ring.i.r,
179 (char *) top.hold.buf.r, top.hold.size.bytes);
180 ringb_read(top.jack.auxr.i.l,
181 (char *) top.hold.aux.l, top.hold.size.bytes);
182 ringb_read(top.jack.auxr.i.r,
183 (char *) top.hold.aux.r, top.hold.size.bytes);
185 LeaveCriticalSection(cs);
192 EnterCriticalSection(cs);
193 answer = (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes);
194 LeaveCriticalSection(cs);
199 //------------------------------------------------------------------------
204 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
205 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
206 memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
207 memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
220 process_samples(top.hold.buf.l, top.hold.buf.r,
221 top.hold.aux.l, top.hold.aux.r, top.hold.size.frames);
224 // NB do not set RUN_SWCH directly via setRunState;
225 // use setSWCH instead
230 if (top.swch.bfct.have == 0) {
233 int i, m = top.swch.fade, n = top.swch.tail;
234 for (i = 0; i < m; i++) {
235 float w = (float) 1.0 - (float) i / m;
236 top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
238 memset((char *) (top.hold.buf.l + m), 0, n);
239 memset((char *) (top.hold.buf.r + m), 0, n);
240 top.swch.bfct.have++;
241 } else if (top.swch.bfct.have < top.swch.bfct.want) {
243 memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
244 memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
245 top.swch.bfct.have++;
249 int i, m = top.swch.fade, n = top.swch.tail;
250 for (i = 0; i < m; i++) {
251 float w = (float) i / m;
252 top.hold.buf.l[i] *= w, top.hold.buf.r[i] *= w;
254 uni.mode.trx = top.swch.trx.next;
255 switch (uni.mode.trx) {
258 tx.agc.gen->over = tx.tick + 3;
261 for (i = 0; i < uni.multirx.nrx; i++)
262 rx[i].agc.gen->over = rx[i].tick + 3;
266 top.state = top.swch.run.last;
267 top.swch.bfct.want = top.swch.bfct.have = 0;
269 ringb_reset(top.jack.ring.o.l);
270 ringb_reset(top.jack.ring.o.r);
271 ringb_clear(top.jack.ring.o.l, top.hold.size.bytes);
272 ringb_clear(top.jack.ring.o.r, top.hold.size.bytes);
279 process_samples(top.hold.buf.l, top.hold.buf.r,
280 top.hold.aux.l, top.hold.aux.r, top.hold.size.frames);
283 //========================================================================
288 audio_callback(float *input_l, float *input_r, float *output_l,
289 float *output_r, int nframes)
291 size_t nbytes = sizeof(float) * nframes;
294 EnterCriticalSection(cs);
297 if (ringb_read_space(top.jack.ring.o.l) >= nbytes) {
298 ringb_read(top.jack.ring.o.l, (char *) output_l, nbytes);
299 ringb_read(top.jack.ring.o.r, (char *) output_r, nbytes);
300 } else { // rb pathology
301 memset((char *) output_l, 0, nbytes);
302 memset((char *) output_r, 0, nbytes);
303 ringb_restart(top.jack.ring.o.l, nbytes);
304 ringb_restart(top.jack.ring.o.r, nbytes);
305 top.jack.blow.rb.o++;
308 // input: copy from port to ring
309 if (ringb_write_space(top.jack.ring.i.l) >= nbytes) {
310 ringb_write(top.jack.ring.i.l, (char *) input_l, nbytes);
311 ringb_write(top.jack.ring.i.r, (char *) input_r, nbytes);
312 ringb_write(top.jack.auxr.i.l, (char *) input_l, nbytes);
313 ringb_write(top.jack.auxr.i.r, (char *) input_r, nbytes);
314 } else { // rb pathology
315 ringb_restart(top.jack.ring.i.l, nbytes);
316 ringb_restart(top.jack.ring.i.r, nbytes);
317 ringb_restart(top.jack.auxr.i.l, nbytes);
318 ringb_restart(top.jack.auxr.i.r, nbytes);
319 top.jack.blow.rb.i++;
321 LeaveCriticalSection(cs);
322 // if enough accumulated in ring, fire dsp
323 if (ringb_read_space(top.jack.ring.i.l) >= top.hold.size.bytes)
324 sem_post(&top.sync.buf.sem);
327 if ((top.jack.blow.cb > 0) ||
328 (top.jack.blow.rb.i > 0) || (top.jack.blow.rb.o > 0))
329 sem_post(&top.sync.mon.sem);
332 //========================================================================
335 process_samples_thread(void)
337 while (top.running) {
338 sem_wait(&top.sync.buf.sem);
341 sem_wait(&top.sync.upd.sem);
356 sem_post(&top.sync.upd.sem);
367 safefree((char *) top.jack.ring.o.r);
368 safefree((char *) top.jack.ring.o.l);
369 safefree((char *) top.jack.ring.i.r);
370 safefree((char *) top.jack.ring.i.l);
371 safefree((char *) top.jack.auxr.i.l);
372 safefree((char *) top.jack.auxr.i.r);
373 safefree((char *) top.jack.auxr.o.l);
374 safefree((char *) top.jack.auxr.o.r);
376 CloseHandle(top.parm.fp);
377 DisconnectNamedPipe(top.parm.fd);
378 CloseHandle(top.parm.fd);
381 if (uni.meter.flag) {
382 CloseHandle(top.meas.mtr.fp);
383 DisconnectNamedPipe(top.meas.mtr.fd);
384 CloseHandle(top.meas.mtr.fd);
388 CloseHandle(top.meas.spec.fp);
389 DisconnectNamedPipe(top.meas.spec.fd);
390 CloseHandle(top.meas.spec.fd);
395 //........................................................................
398 setup_switching(void)
400 top.swch.fade = (int) (0.1 * uni.buflen + 0.5);
401 top.swch.tail = (top.hold.size.frames - top.swch.fade) * sizeof(float);
405 setup_local_audio(void)
407 top.hold.size.frames = uni.buflen;
408 top.hold.size.bytes = top.hold.size.frames * sizeof(float);
409 top.hold.buf.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
410 "main hold buffer left");
411 top.hold.buf.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
412 "main hold buffer right");
413 top.hold.aux.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
414 "aux hold buffer left");
415 top.hold.aux.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
416 "aux hold buffer right");
422 DisplayErrorText(DWORD dwLastError)
424 HMODULE hModule = NULL; // default to system source
426 DWORD dwBufferLength;
428 DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
429 FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM;
432 // If dwLastError is in the network range,
433 // load the message source.
436 if (dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
437 hModule = LoadLibraryEx(TEXT("netmsg.dll"),
438 NULL, LOAD_LIBRARY_AS_DATAFILE);
441 dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
444 // Call FormatMessage() to allow for message
445 // text to be acquired from the system
446 // or from the supplied module handle.
449 if (dwBufferLength = FormatMessageA(dwFormatFlags, hModule, // module to get message from (NULL == system)
450 dwLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
451 (LPSTR) & MessageBuffer, 0, NULL)) {
452 DWORD dwBytesWritten;
455 // Output message string on stderr.
457 WriteFile(GetStdHandle(STD_ERROR_HANDLE),
458 MessageBuffer, dwBufferLength, &dwBytesWritten, NULL);
461 // Free the buffer allocated by the system.
463 LocalFree(MessageBuffer);
466 // If we loaded a message source, unload it.
469 FreeLibrary(hModule);
474 PRIVATE sem_t setup_update_sem;
477 setup_update_server()
480 if (INVALID_HANDLE_VALUE == (top.parm.fd = CreateNamedPipe(top.parm.path,
485 PIPE_READMODE_MESSAGE,
486 PIPE_UNLIMITED_INSTANCES,
490 fprintf(stderr, "Update server pipe setup failed:\n"), fflush(stderr);
491 DisplayErrorText(GetLastError());
493 // fprintf(stderr,"Update NamedPipe made\n"),fflush(stderr);
494 sem_post(&setup_update_sem);
495 if (ConnectNamedPipe(top.parm.fd, NULL)) {
496 // fprintf(stderr,"Connected the server to the Update pipe\n"),fflush(stderr);
498 fprintf(stderr, "Connected the server to the Update pipe failed\n"),
500 DisplayErrorText(GetLastError());
507 setup_update_client()
509 // fprintf(stderr,"Looking for the Update server\n"),fflush(stderr);
510 WaitNamedPipe(top.parm.path, INFINITE);
511 // fprintf(stderr,"Found the Update server\n"),fflush(stderr);
512 if (INVALID_HANDLE_VALUE == (top.parm.fp = CreateFile(top.parm.path,
515 FILE_ATTRIBUTE_NORMAL,
517 fprintf(stderr, "The Update Client Open Failed\n"), fflush(stderr);
518 DisplayErrorText(GetLastError());
520 sem_post(&setup_update_sem);
523 WriteFile(top.parm.fp,"test",5,&numwritten,NULL);
524 fprintf(stderr,"Number written to server: %lu\n",numwritten),fflush(stderr);
532 top.meas.mtr.fd = CreateNamedPipe(top.meas.mtr.path,
533 PIPE_ACCESS_OUTBOUND,
534 PIPE_WAIT | PIPE_TYPE_MESSAGE |
535 PIPE_READMODE_MESSAGE,
536 PIPE_UNLIMITED_INSTANCES, 512, 512,
538 // fprintf(stderr,"meter handle = %08X\n",(DWORD)top.meas.mtr.fd),fflush(stderr);
539 if (top.meas.mtr.fd == INVALID_HANDLE_VALUE) {
540 fprintf(stderr, "Meter server pipe setup failed:\n"), fflush(stderr);
541 DisplayErrorText(GetLastError());
543 // fprintf(stderr,"Meter Pipe Connect succeeded\n"),fflush(stderr);
544 sem_post(&setup_update_sem);
545 if (ConnectNamedPipe(top.meas.mtr.fd, NULL)) {
546 // fprintf(stderr,"Connected the Meter Pooch\n"),fflush(stderr);
548 fprintf(stderr, "Meter Pipe Connect failed\n"), fflush(stderr);
549 DisplayErrorText(GetLastError());
558 // fprintf(stderr,"Looking for the meter server\n"),fflush(stderr);
559 if (WaitNamedPipe(top.meas.mtr.path, INFINITE)) {
560 // fprintf(stderr,"Found the Meter server\n"),fflush(stderr);
561 if (INVALID_HANDLE_VALUE ==
563 CreateFile(top.meas.mtr.path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
564 FILE_ATTRIBUTE_NORMAL, NULL))) {
565 fprintf(stderr, "The Meter Client Open Failed\n"), fflush(stderr);
566 DisplayErrorText(GetLastError());
568 // fprintf(stderr,"The Meter Client Open Succeeded\n"),fflush(stderr);
571 fprintf(stderr, "Wait for meter pipe failed: Error message %d\n",
572 GetLastError()), fflush(stderr);
574 sem_post(&setup_update_sem);
582 if (INVALID_HANDLE_VALUE ==
584 CreateNamedPipe(top.meas.spec.path, PIPE_ACCESS_OUTBOUND,
585 PIPE_WAIT | PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
586 PIPE_UNLIMITED_INSTANCES, 32768, 32768, INFINITE,
588 fprintf(stderr, "Spectrum pipe create failed\n"), fflush(stderr);
589 DisplayErrorText(GetLastError());
591 // fprintf(stderr,"Spectrum Pipe %s Create succeeded\n",top.meas.spec.path),fflush(stderr);
592 sem_post(&setup_update_sem);
593 if (ConnectNamedPipe(top.meas.spec.fd, NULL)) {
594 // fprintf(stderr,"Connected to the Spectrum Pipe\n"),fflush(stderr);
596 fprintf(stderr, "Spectrum pipe connect failed\n"), fflush(stderr);
597 DisplayErrorText(GetLastError());
606 // fprintf(stderr,"Looking for the spectrum server\n"),fflush(stderr);
607 if (WaitNamedPipe(top.meas.spec.path, INFINITE)) {
608 // fprintf(stderr,"Found the server\n"),fflush(stderr);
609 if (INVALID_HANDLE_VALUE ==
611 CreateFile(top.meas.spec.path, GENERIC_READ, 0, NULL, OPEN_EXISTING,
612 FILE_ATTRIBUTE_NORMAL, NULL))) {
613 fprintf(stderr, "The Spectrum Client Open Failed\n"), fflush(stderr);
614 DisplayErrorText(GetLastError());
616 // fprintf(stderr,"The Spectrum Client Open Succeeded\n");
617 // fprintf(stderr,"Spec Read handle = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
620 fprintf(stderr, "Wait for spec pipe failed\n"), fflush(stderr);
621 DisplayErrorText(GetLastError());
623 sem_post(&setup_update_sem);
626 PRIVATE pthread_t id1, id2, id3, id4, id5, id6;
631 char mesg[16384] = "TEST TEST METER\n";
633 top.parm.path = loc.path.parm;
634 sem_init(&setup_update_sem, 0, 0);
637 if (uni.meter.flag) {
638 top.meas.mtr.path = loc.path.meter;
641 top.meas.spec.path = loc.path.spec;
644 // Do this STUPID stuff to make use of the Named Pipe Mechanism in Windows
645 // For the update server
648 pthread_create(&id1, NULL, (void *) setup_update_server, NULL);
649 sem_wait(&setup_update_sem);
650 pthread_create(&id2, NULL, (void *) setup_update_client, NULL);
651 sem_wait(&setup_update_sem);
652 if (uni.meter.flag) {
653 pthread_create(&id3, NULL, (void *) setup_meter_server, NULL);
654 sem_wait(&setup_update_sem);
655 pthread_create(&id4, NULL, (void *) setup_meter_client, NULL);
656 sem_wait(&setup_update_sem);
657 /* if (WriteFile(top.meas.mtr.fd,mesg,strlen(mesg)+1,&NumBytes,NULL))
659 fprintf(stderr,"Meter Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
661 fprintf(stderr,"Meter Pipe write failed\n"),fflush(stderr);
662 DisplayErrorText(GetLastError());
664 if (ReadFile(top.meas.mtr.fp,mesg,256,&NumBytes,NULL))
666 fprintf(stderr,"Meter Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
667 fprintf(stderr,"Meter message %s",mesg),fflush(stderr);
669 fprintf(stderr,"Meter Pipe read failed\n"),fflush(stderr);
670 DisplayErrorText(GetLastError());
676 memset(mesg, 0, 16384);
677 pthread_create(&id5, NULL, (void *) setup_spec_server, NULL);
678 sem_wait(&setup_update_sem);
679 pthread_create(&id6, NULL, (void *) setup_spec_client, NULL);
680 sem_wait(&setup_update_sem);
682 /* if (WriteFile(top.meas.spec.fd,mesg,16384,&NumBytes,NULL))
684 fprintf(stderr,"Spec Pipe write succeeded and wrote %lu bytes\n",NumBytes),fflush(stderr);
686 fprintf(stderr,"Spec Pipe write failed\n"),fflush(stderr);
687 DisplayErrorText(GetLastError());
689 fprintf(stderr,"Spec Read handle(2) = %08X\n",(DWORD)top.meas.spec.fp),fflush(stderr);
690 if (ReadFile(top.meas.spec.fp,mesg,16384,&NumBytes,NULL))
692 fprintf(stderr,"Spec Pipe read succeeded and %lu bytes read\n",NumBytes),fflush(stderr);
694 fprintf(stderr,"Spec Pipe read failed\n"),fflush(stderr);
695 DisplayErrorText(GetLastError());
698 sem_destroy(&setup_update_sem);
701 setup_system_audio(void)
705 sprintf(top.jack.name, "sdr-%d", top.pid);
706 top.jack.size = uni.buflen;
707 ringsize = top.hold.size.bytes * loc.mult.ring + sizeof(ringb_t);
708 usemem = safealloc(ringsize, 1, "Ring Input Left");
710 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
712 usemem = safealloc(ringsize, 1, "Ring Input Right");
714 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
716 usemem = safealloc(ringsize, 1, "Ring Output Left");
718 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
720 usemem = safealloc(ringsize, 1, "Ring Output Right");
722 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
724 usemem = safealloc(ringsize, 1, "Ring Input Left Auxiliary");
726 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
728 usemem = safealloc(ringsize, 1, "Ring Input Right Auxiliary");
730 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
732 usemem = safealloc(ringsize, 1, "Ring Output Left Auxiliary");
734 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
736 usemem = safealloc(ringsize, 1, "Ring Output Right Auxiliary");
738 ringb_create(usemem, top.hold.size.bytes * loc.mult.ring);
740 ringb_clear(top.jack.ring.o.l, top.jack.size * sizeof(float));
741 ringb_clear(top.jack.ring.o.r, top.jack.size * sizeof(float));
742 ringb_clear(top.jack.auxr.o.l, top.jack.size * sizeof(float));
743 ringb_clear(top.jack.auxr.o.r, top.jack.size * sizeof(float));
747 setup_threading(void)
749 sem_init(&top.sync.upd.sem, 0, 0);
750 pthread_create(&top.thrd.upd.id, NULL, (void *) process_updates_thread,
752 sem_init(&top.sync.buf.sem, 0, 0);
753 pthread_create(&top.thrd.trx.id, NULL, (void *) process_samples_thread,
755 sem_init(&top.sync.mon.sem, 0, 0);
756 pthread_create(&top.thrd.mon.id, NULL, (void *) monitor_thread, NULL);
757 if (uni.meter.flag) {
758 sem_init(&top.sync.mtr.sem, 0, 0);
759 pthread_create(&top.thrd.mtr.id, NULL, (void *) meter_thread, NULL);
762 sem_init(&top.sync.pws.sem, 0, 0);
763 pthread_create(&top.thrd.pws.id, NULL, (void *) spectrum_thread, NULL);
766 InitializeCriticalSection(cs);
769 //========================================================================
770 // hard defaults, then environment
775 loc.name[0] = 0; // no default name for jack client
776 strcpy(loc.path.rcfile, RCBASE);
777 strcpy(loc.path.parm, PARMPATH);
778 strcpy(loc.path.meter, METERPATH);
779 strcpy(loc.path.spec, SPECPATH);
780 strcpy(loc.path.wisdom, WISDOMPATH);
781 loc.def.rate = DEFRATE;
782 loc.def.size = DEFSIZE;
784 loc.def.mode = DEFMODE;
785 loc.def.spec = DEFSPEC;
786 loc.mult.ring = RINGMULT;
789 //========================================================================
795 top.pid = GetCurrentThreadId();
797 top.start_tv = now_tv();
800 top.state = RUN_PLAY;
804 uni.meter.flag = TRUE;
805 uni.spec.flag = TRUE;
811 setup_system_audio();
815 uni.spec.flag = TRUE;
816 uni.spec.type = SPEC_POST_FILT;
817 uni.spec.scale = SPEC_PWR;