From 5994f02143b8ecdc92433c4f7e47ed47bf8460b2 Mon Sep 17 00:00:00 2001
From: dttsp <dttsp>
Date: Mon, 2 May 2005 04:25:14 +0000
Subject: [PATCH] Minor fix to keyb, added hash function to banal.h, added aux
 input ports with settable mix levels to DSP

---
 jDttSP/banal.c            |  8 +++++++
 jDttSP/banal.h            |  2 ++
 jDttSP/command-vocabulary |  2 ++
 jDttSP/keyb.c             |  5 +++-
 jDttSP/main.c             | 50 ++++++++++++++++++++++++++++++++++++---
 jDttSP/sdr.c              | 20 +++++++++++++++-
 jDttSP/sdrexport.h        | 21 +++++++++++++++-
 jDttSP/update.c           | 20 ++++++++++++++++
 8 files changed, 122 insertions(+), 6 deletions(-)

diff --git a/jDttSP/banal.c b/jDttSP/banal.c
index 8bc08f1..b62cec9 100644
--- a/jDttSP/banal.c
+++ b/jDttSP/banal.c
@@ -197,3 +197,11 @@ find_rcfile(char *base) {
 
 //------------------------------------------------------------------------
 
+unsigned long
+hash(unsigned char *str) {
+  unsigned long hash = 5381;
+  int c;
+  while (c = *str++)
+    hash = ((hash << 5) + hash) + c; // (hash * 33 + c) better
+  return hash;
+}
diff --git a/jDttSP/banal.h b/jDttSP/banal.h
index 3aca035..e6af09b 100644
--- a/jDttSP/banal.h
+++ b/jDttSP/banal.h
@@ -79,4 +79,6 @@ extern void status_message(char *msg);
 
 extern FILE *find_rcfile(char *base);
 
+extern unsigned long hash(unsigned char *str);
+
 #endif
diff --git a/jDttSP/command-vocabulary b/jDttSP/command-vocabulary
index 2655e4c..93128ea 100644
--- a/jDttSP/command-vocabulary
+++ b/jDttSP/command-vocabulary
@@ -55,3 +55,5 @@ setRXListen rx		// tell receiver rx to listen to commands to follow
 setRXOn [rx]		// turn currently listening receiver on, or receiver rx
 setRXOff [rx]		// turn currently listening receiver off, or receiver rx
 setRXPan pos		// set azimuth for currently listening receiver to pos (0...1)
+setAuxMix [gain [trx]]	// set mixing level for aux inputs
+
diff --git a/jDttSP/keyb.c b/jDttSP/keyb.c
index 14e128b..824a947 100644
--- a/jDttSP/keyb.c
+++ b/jDttSP/keyb.c
@@ -354,11 +354,14 @@ main(int argc, char **argv) {
       case 'w':
 	wpm = atof(argv[++i]);
 	break;
+      case 'g':
+	gain = atof(argv[++i]);
+	break;
       case 'r':
 	ramp = atof(argv[++i]);
 	break;
       default:
-	fprintf(stderr, "keyd [-w wpm] [-f freq] [-r ramp_ms] [infile]\n");
+	fprintf(stderr, "keyb [-w wpm] [-f freq] [-g gain_dB] [-r ramp_ms] [infile]\n");
 	exit(1);
       }
     else break;
diff --git a/jDttSP/main.c b/jDttSP/main.c
index b68ba95..b74e9df 100644
--- a/jDttSP/main.c
+++ b/jDttSP/main.c
@@ -42,7 +42,7 @@ struct _loc loc;
 // most of what little we know here about the inner loop,
 // functionally speaking
 
-extern void process_samples(float *, float *, int);
+extern void process_samples(float *, float *, float *, float *, int);
 extern void setup_workspace(void);
 extern void destroy_workspace(void);
 
@@ -108,6 +108,10 @@ gethold(void) {
     jack_ringbuffer_reset(top.jack.ring.i.r);
     memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
     memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+    jack_ringbuffer_reset(top.jack.auxr.i.l);
+    jack_ringbuffer_reset(top.jack.auxr.i.r);
+    memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+    memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
     top.jack.blow.rb.i++;
   } else {
     jack_ringbuffer_read(top.jack.ring.i.l,
@@ -116,6 +120,12 @@ gethold(void) {
     jack_ringbuffer_read(top.jack.ring.i.r,
 			 (char *) top.hold.buf.r,
 			 top.hold.size.bytes);
+    jack_ringbuffer_read(top.jack.auxr.i.l,
+			 (char *) top.hold.aux.l,
+			 top.hold.size.bytes);
+    jack_ringbuffer_read(top.jack.auxr.i.r,
+			 (char *) top.hold.aux.r,
+			 top.hold.size.bytes);
   }
 }
 
@@ -130,6 +140,8 @@ PRIVATE void
 run_mute(void) {
   memset((char *) top.hold.buf.l, 0, top.hold.size.bytes);
   memset((char *) top.hold.buf.r, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.l, 0, top.hold.size.bytes);
+  memset((char *) top.hold.aux.r, 0, top.hold.size.bytes);
   uni.tick++;
 }
 
@@ -138,7 +150,9 @@ run_pass(void) { uni.tick++; }
 
 PRIVATE void 
 run_play(void) {
-  process_samples(top.hold.buf.l, top.hold.buf.r, top.hold.size.frames);
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r,
+		  top.hold.size.frames);
 } 
 
 // NB do not set RUN_SWCH directly via setRunState;
@@ -187,7 +201,9 @@ run_swch(void) {
     jack_ringbuffer_reset(top.jack.ring.o.r);
   }
 
-  process_samples(top.hold.buf.l, top.hold.buf.r, top.hold.size.frames);
+  process_samples(top.hold.buf.l, top.hold.buf.r,
+		  top.hold.aux.l, top.hold.aux.r,
+		  top.hold.size.frames);
 } 
 
 //========================================================================
@@ -223,11 +239,19 @@ audio_callback(jack_nframes_t nframes, void *arg) {
       rp = (float *) jack_port_get_buffer(top.jack.port.i.r, nframes);
       jack_ringbuffer_write(top.jack.ring.i.l, (char *) lp, nbytes);
       jack_ringbuffer_write(top.jack.ring.i.r, (char *) rp, nbytes);
+      lp = (float *) jack_port_get_buffer(top.jack.auxp.i.l, nframes);
+      rp = (float *) jack_port_get_buffer(top.jack.auxp.i.r, nframes);
+      jack_ringbuffer_write(top.jack.auxr.i.l, (char *) lp, nbytes);
+      jack_ringbuffer_write(top.jack.auxr.i.r, (char *) rp, nbytes);
     } else { // rb pathology
       jack_ringbuffer_reset(top.jack.ring.i.l);
       jack_ringbuffer_reset(top.jack.ring.i.r);
       clear_jack_ringbuffer(top.jack.ring.i.l, nbytes);
       clear_jack_ringbuffer(top.jack.ring.i.r, nbytes);
+      jack_ringbuffer_reset(top.jack.auxr.i.l);
+      jack_ringbuffer_reset(top.jack.auxr.i.r);
+      clear_jack_ringbuffer(top.jack.auxr.i.l, nbytes);
+      clear_jack_ringbuffer(top.jack.auxr.i.r, nbytes);
       top.jack.blow.rb.i++;
     }
 
@@ -303,6 +327,8 @@ execute(void) {
 
 PRIVATE void 
 closeup(void) {
+  jack_ringbuffer_free(top.jack.auxr.i.r);
+  jack_ringbuffer_free(top.jack.auxr.i.l);
   jack_ringbuffer_free(top.jack.ring.o.r);
   jack_ringbuffer_free(top.jack.ring.o.l);
   jack_ringbuffer_free(top.jack.ring.i.r);
@@ -310,6 +336,8 @@ closeup(void) {
 
   safefree((char *) top.hold.buf.r);
   safefree((char *) top.hold.buf.l);
+  safefree((char *) top.hold.aux.r);
+  safefree((char *) top.hold.aux.l);
 
   destroy_workspace();
 
@@ -362,6 +390,10 @@ setup_local_audio(void) {
 				       "main hold buffer left");
   top.hold.buf.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
 				       "main hold buffer right");
+  top.hold.aux.l = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer left");
+  top.hold.aux.r = (float *) safealloc(top.hold.size.frames, sizeof(float),
+				       "aux hold buffer right");
 } 
 
 PRIVATE void 
@@ -417,10 +449,22 @@ setup_system_audio(void) {
 					 JACK_DEFAULT_AUDIO_TYPE,
 					 JackPortIsOutput,
 					 0);
+  top.jack.auxp.i.l = jack_port_register(top.jack.client,
+					 "al",
+					 JACK_DEFAULT_AUDIO_TYPE,
+					 JackPortIsInput,
+					 0);
+  top.jack.auxp.i.r = jack_port_register(top.jack.client,
+					 "ar",
+					 JACK_DEFAULT_AUDIO_TYPE,
+					 JackPortIsInput,
+					 0);
   top.jack.ring.i.l = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
   top.jack.ring.i.r = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
   top.jack.ring.o.l = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
   top.jack.ring.o.r = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
+  top.jack.auxr.i.l = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
+  top.jack.auxr.i.r = jack_ringbuffer_create(top.hold.size.bytes * loc.mult.ring);
   clear_jack_ringbuffer(top.jack.ring.o.l, top.jack.size * sizeof(float));
   clear_jack_ringbuffer(top.jack.ring.o.r, top.jack.size * sizeof(float));
 }
diff --git a/jDttSP/sdr.c b/jDttSP/sdr.c
index d500676..8201b9d 100644
--- a/jDttSP/sdr.c
+++ b/jDttSP/sdr.c
@@ -75,6 +75,9 @@ setup_all(void) {
 
   uni.multirx.lis = 0;
   uni.multirx.nrx = loc.def.nrx;
+
+  uni.mix.rx = uni.mix.tx = 1.0;
+
   uni.tick = 0;
 }
 
@@ -205,6 +208,7 @@ setup_rx(int k) {
     REAL pos = 0.5, // 0 <= pos <= 1, left->right
          theta = (1.0 - pos) * M_PI / 2.0;
     rx[k].azim = Cmplx(cos(theta), sin(theta));
+    fprintf(stderr, "azim %f %f\n", rx[k].azim.re, rx[k].azim.im);
   }
 
   rx[k].tick = 0;
@@ -703,7 +707,9 @@ do_tx(void) {
    come here when there are buffers to work on */
 
 void
-process_samples(float *bufl, float *bufr, int n) {
+process_samples(float *bufl, float *bufr,
+		float *auxl, float *auxr,
+		int n) {
   int i, k;
 
   switch (uni.mode.trx) {
@@ -733,16 +739,28 @@ process_samples(float *bufl, float *bufr, int n) {
 	CXBhave(rx[k].buf.o) = n;
       }
 
+    for (i = 0; i < n; i++)
+      bufl[i] += auxl[i] * uni.mix.rx,
+      bufr[i] += auxr[i] * uni.mix.rx;
+
     break;
 
   case TX:
+
+    for (i = 0; i < n; i++)
+      bufl[i] += auxl[i] * uni.mix.tx,
+      bufr[i] += auxr[i] * uni.mix.tx;
+
     for (i = 0; i < n; i++)
       CXBimag(tx.buf.i, i) = bufl[i], CXBreal(tx.buf.i, i) = bufr[i];
     CXBhave(tx.buf.i) = n;
+
     do_tx(), tx.tick++;
+
     for (i = 0; i < n; i++)
       bufl[i] = (float) CXBimag(tx.buf.o, i), bufr[i] = (float) CXBreal(tx.buf.o, i);
     CXBhave(tx.buf.o) = n;
+
     break;
   }
 
diff --git a/jDttSP/sdrexport.h b/jDttSP/sdrexport.h
index 4802d5b..477f112 100644
--- a/jDttSP/sdrexport.h
+++ b/jDttSP/sdrexport.h
@@ -101,6 +101,10 @@ extern struct _uni {
     int lis, nac, nrx;
   } multirx;
 
+  struct {
+    REAL rx, tx;
+  } mix;
+
   long tick;
   
 } uni;
@@ -226,7 +230,7 @@ extern struct _top {
   struct {
     struct {
       float *l, *r;
-    } buf;
+    } aux, buf;
     struct {
       unsigned int frames, bytes;
     } size;
@@ -246,11 +250,26 @@ extern struct _top {
 	jack_port_t *l, *r;
       } i, o;
     } port;
+
+    // input only
+    struct {
+      struct {
+	jack_port_t *l, *r;
+      } i;
+    } auxp;
+
     struct {
       struct {
 	jack_ringbuffer_t *l, *r;
       } i, o;
     } ring;
+
+    struct {
+      struct {
+	jack_ringbuffer_t *l, *r;
+      } i, o;
+    } auxr;
+
     jack_nframes_t size;
     struct {
       int cb;
diff --git a/jDttSP/update.c b/jDttSP/update.c
index aeed07b..5962cb1 100644
--- a/jDttSP/update.c
+++ b/jDttSP/update.c
@@ -743,6 +743,25 @@ setRXPan(int n, char **p) {
   }
 }
 
+PRIVATE int
+setAuxMix(int n, char **p) {
+  if (n < 1) {
+    uni.mix.rx = uni.mix.tx = 1.0;
+    return 0;
+  } else {
+    REAL gain = dB2lin(atof(p[0]));
+    if (n > 1) {
+      switch (atoi(p[1])) {
+      case TX: uni.mix.tx = gain; break;
+      case RX:
+      default: uni.mix.rx = gain; break;
+      }
+    } else
+      uni.mix.rx = uni.mix.tx = gain;
+    return 0;
+  }
+}
+
 //========================================================================
 
 #include <thunk.h>
@@ -800,6 +819,7 @@ CTE update_cmds[] = {
   {"setRXOn", setRXOn},
   {"setRXOff", setRXOff},
   {"setRXPan", setRXPan},
+  {"setAuxMix", setAuxMix},
   { 0, 0 }
 };
 
-- 
2.45.2