]> git.rkrishnan.org Git - dttsp.git/blobdiff - jDttSP/main.c
Major changes. Added metering and power spectrum, other fixes. Rearranged headers...
[dttsp.git] / jDttSP / main.c
index b74e9df0bd52285ebc92813bd158223df582b7b2..7575afbd679f1189533fb1cbf378acc0a912e2d6 100644 (file)
@@ -2,7 +2,7 @@
 
 This file is part of a program that implements a Software-Defined Radio.
 
-Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
+Copyright (C) 2004-5 by Frank Brickle, AB2KT and Bob McGwier, N4HY
 
 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
@@ -42,18 +42,69 @@ struct _loc loc;
 // most of what little we know here about the inner loop,
 // functionally speaking
 
+extern void reset_meters(void);
+extern void reset_spectrum(void);
+extern void reset_counters(void);
 extern void process_samples(float *, float *, float *, float *, int);
 extern void setup_workspace(void);
 extern void destroy_workspace(void);
 
 //========================================================================
 
-void
-clear_jack_ringbuffer(jack_ringbuffer_t *rb, int nbytes) {
-  int i;
-  char zero = 0;
-  for (i = 0; i < nbytes; i++)
-    jack_ringbuffer_write(rb, &zero, 1);
+PRIVATE void
+spectrum_thread(void) {
+
+  while (top.running) {
+    sem_wait(&top.sync.pws.sem);
+
+    compute_spectrum(&uni.spec);
+
+    if (fwrite((char *) &uni.spec.label, sizeof(int), 1, top.meas.spec.fp)
+       != 1) {
+      fprintf(stderr, "error writing spectrum label\n");
+      exit(1);
+    }
+
+    if (fwrite((char *) uni.spec.output, sizeof(float), uni.spec.size, top.meas.spec.fp)
+       != uni.spec.size) {
+      fprintf(stderr, "error writing spectrum\n");
+      exit(1);
+    }
+
+    fflush(top.meas.spec.fp);
+  }
+
+  pthread_exit(0);
+}
+
+PRIVATE void
+meter_thread(void) {
+
+  while (top.running) {
+    sem_wait(&top.sync.mtr.sem);
+
+    if (fwrite((char *) &uni.meter.label, sizeof(int), 1, top.meas.mtr.fp)
+       != 1) {
+      fprintf(stderr, "error writing meter label\n");
+      exit(1);
+    }
+
+    if (fwrite((char *) uni.meter.snap.rx, sizeof(REAL), MAXRX * RXMETERPTS, top.meas.mtr.fp)
+       != MAXRX * RXMETERPTS) {
+      fprintf(stderr, "error writing rx meter\n");
+      exit(1);
+    }
+
+    if (fwrite((char *) uni.meter.snap.tx, sizeof(REAL), TXMETERPTS, top.meas.mtr.fp)
+       != TXMETERPTS) {
+      fprintf(stderr, "error writing tx meter\n");
+      exit(1);
+    }
+
+    fflush(top.meas.mtr.fp);
+  }
+
+  pthread_exit(0);
 }
 
 //========================================================================
@@ -86,6 +137,8 @@ process_updates_thread(void) {
   pthread_exit(0);
 }
 
+//========================================================================
+
 PRIVATE void 
 gethold(void) {
   if (jack_ringbuffer_write_space(top.jack.ring.o.l)
@@ -136,6 +189,8 @@ canhold(void) {
     >= top.hold.size.bytes;
 }
 
+//------------------------------------------------------------------------
+
 PRIVATE void 
 run_mute(void) {
   memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
@@ -186,19 +241,15 @@ run_swch(void) {
     }
     uni.mode.trx = top.swch.trx.next;
 
-    // move this out of main! -----------------------------
-    {
-      int k;
-      for (k = 0; k < uni.multirx.nrx; k++) rx[k].tick = 0;
-    }
-    tx.tick = 0;
-    //-----------------------------------------------------
-
     top.state = top.swch.run.last;
     top.swch.bfct.want = top.swch.bfct.have = 0;
 
     jack_ringbuffer_reset(top.jack.ring.o.l);
     jack_ringbuffer_reset(top.jack.ring.o.r);
+
+    reset_meters();
+    reset_spectrum();
+    reset_counters();
   }
 
   process_samples(top.hold.buf.l, top.hold.buf.r,
@@ -208,6 +259,13 @@ run_swch(void) {
 
 //========================================================================
 
+void
+clear_jack_ringbuffer(jack_ringbuffer_t *rb, int nbytes) {
+  int i;
+  char zero = 0;
+  for (i = 0; i < nbytes; i++)
+    jack_ringbuffer_write(rb, &zero, 1);
+}
 
 PRIVATE void 
 audio_callback(jack_nframes_t nframes, void *arg) {
@@ -276,6 +334,8 @@ audio_callback(jack_nframes_t nframes, void *arg) {
     sem_post(&top.sync.mon.sem);
 }
 
+//========================================================================
+
 PRIVATE void 
 process_samples_thread(void) {
   while (top.running) {
@@ -320,6 +380,10 @@ execute(void) {
   pthread_join(top.thrd.trx.id, 0);
   pthread_join(top.thrd.upd.id, 0);
   pthread_join(top.thrd.mon.id, 0);
+  if (uni.meter.flag)
+    pthread_join(top.thrd.mtr.id, 0);
+  if (uni.spec.flag)
+    pthread_join(top.thrd.pws.id, 0);
   
   // stop audio processing
   jack_client_close(top.jack.client);
@@ -339,6 +403,13 @@ closeup(void) {
   safefree((char *) top.hold.aux.r);
   safefree((char *) top.hold.aux.l);
 
+  fclose(top.parm.fp);
+
+  if (uni.meter.flag)
+    fclose(top.meas.mtr.fp);
+  if (uni.spec.flag)
+    fclose(top.meas.spec.fp);
+
   destroy_workspace();
 
   exit(0);
@@ -351,15 +422,8 @@ usage(void) {
   fprintf(stderr, "flags:\n");
   fprintf(stderr, "    -v              verbose commentary\n");
   fprintf(stderr, "    -m              do metering\n");
+  fprintf(stderr, "    -s              do spectrum\n");
   fprintf(stderr, "    -l file         execute update commands in file at startup\n");
-  fprintf(stderr, "    -P cmdpath      path to command/update pipe\n");
-  fprintf(stderr, "    -S s-mtrpath    path to S-meter output channel\n");
-  fprintf(stderr, "    -W wispath      path to FFTW wisdom file\n");
-  fprintf(stderr, "    -R rate         sampling rate\n");
-  fprintf(stderr, "    -B bufsize      internal DSP buffer size\n");
-  fprintf(stderr, "    -M mode         start up in mode (SAM, USB, LCW, etc.)\n");
-  fprintf(stderr, "    -G num          use num as ringbuffer mult\n");
-  fprintf(stderr, "    -E num          use num as meter chan mult\n");
   fprintf(stderr, "'file' arg unused, but available\n");
   exit(1);
 }
@@ -405,6 +469,16 @@ setup_updates(void) {
     fprintf(stderr, "can't fdopen parm pipe %s\n", loc.path.parm);
     exit(1);
   }
+
+  // do this here 'cuz the update thread is controlling the action
+  if (uni.meter.flag) {
+    top.meas.mtr.path = loc.path.meter;
+    top.meas.mtr.fp = efopen(top.meas.mtr.path, "r+");
+  }
+  if (uni.spec.flag) {
+    top.meas.spec.path = loc.path.spec;
+    top.meas.spec.fp = efopen(top.meas.spec.path, "r+");
+  }
 }
 
 PRIVATE void
@@ -477,6 +551,14 @@ setup_threading(void) {
   pthread_create(&top.thrd.trx.id, NULL, (void *) process_samples_thread, NULL);
   sem_init(&top.sync.mon.sem, 0, 0);
   pthread_create(&top.thrd.mon.id, NULL, (void *) monitor_thread, NULL);
+  if (uni.meter.flag) {
+    sem_init(&top.sync.mtr.sem, 0, 0);
+    pthread_create(&top.thrd.mtr.id, NULL, (void *) meter_thread, NULL);
+  }
+  if (uni.spec.flag) {
+    sem_init(&top.sync.pws.sem, 0, 0);
+    pthread_create(&top.thrd.pws.id, NULL, (void *) spectrum_thread, NULL);
+  }
 } 
 
 //========================================================================
@@ -488,13 +570,14 @@ setup_defaults(void) {
   strcpy(loc.path.rcfile, RCBASE);
   strcpy(loc.path.parm, PARMPATH);
   strcpy(loc.path.meter, METERPATH);
+  strcpy(loc.path.spec, SPECPATH);
   strcpy(loc.path.wisdom, WISDOMPATH);
   loc.def.rate = DEFRATE;
   loc.def.size = DEFSIZE;
   loc.def.mode = DEFMODE;
+  loc.def.spec = DEFSPEC;
   loc.def.nrx = MAXRX;
   loc.mult.ring = RINGMULT;
-  loc.mult.meter = METERMULT;
 
   {
     char *ep;
@@ -502,9 +585,9 @@ setup_defaults(void) {
     if ((ep = getenv("SDR_RCBASE"))) strcpy(loc.path.rcfile, ep);
     if ((ep = getenv("SDR_PARMPATH"))) strcpy(loc.path.parm, ep);
     if ((ep = getenv("SDR_METERPATH"))) strcpy(loc.path.meter, ep);
+    if ((ep = getenv("SDR_SPECPATH"))) strcpy(loc.path.spec, ep);
     if ((ep = getenv("SDR_WISDOMPATH"))) strcpy(loc.path.wisdom, ep);
     if ((ep = getenv("SDR_RINGMULT"))) loc.mult.ring = atoi(ep);
-    if ((ep = getenv("SDR_METERMULT"))) loc.mult.meter = atoi(ep);
     if ((ep = getenv("SDR_DEFRATE"))) loc.def.rate = atof(ep);
     if ((ep = getenv("SDR_DEFSIZE"))) loc.def.size = atoi(ep);
     if ((ep = getenv("SDR_DEFMODE"))) loc.def.mode = atoi(ep);
@@ -531,35 +614,14 @@ setup(int argc, char **argv) {
       case 'v':
        top.verbose = TRUE;
        break;
-      case 'l':
-       strcpy(loc.path.rcfile, argv[++i]);
-       break;
       case 'm':
        uni.meter.flag = TRUE;
        break;
-      case 'P':
-       strcpy(loc.path.parm, argv[++i]);
+      case 's':
+       uni.spec.flag = TRUE;
        break;
-      case 'S':
-       strcpy(loc.path.meter, argv[++i]);
-       break;
-      case 'W':
-       strcpy(loc.path.wisdom, argv[++i]);
-       break;
-      case 'R':
-       loc.def.rate = atof(argv[++i]);
-       break;
-      case 'B':
-       loc.def.size = atoi(argv[++i]);
-       break;
-      case 'M':
-       loc.def.mode = atoi(argv[++i]);
-       break;
-      case 'G':
-       loc.mult.ring = atoi(argv[++i]);
-       break;
-      case 'E':
-       loc.mult.meter = atoi(argv[++i]);
+      case 'l':
+       strcpy(loc.path.rcfile, argv[++i]);
        break;
       default:
        usage();