slight changes to type-in keyer, autoconnect to playback for type-in and iambic keyers
authordttsp <dttsp>
Wed, 27 Apr 2005 15:12:43 +0000 (15:12 +0000)
committerdttsp <dttsp>
Wed, 27 Apr 2005 15:12:43 +0000 (15:12 +0000)
jDttSP/keyb.c

index 591fbb6e58d6fda6903d2123be2fc2fbfb27e2e5..158b18f7a75506ad52e388661b145c62b1d74c02 100644 (file)
@@ -39,7 +39,7 @@ Bridgewater, NJ 08807
 #include <cxops.h>
 
 #define SAMP_RATE (48000)
-#define HUGE_PHASE 1256637061.43593
+#define HUGE_PHASE (1256637061.43593)
 
 #define RING_SIZE (01 << 020)
 
@@ -52,7 +52,7 @@ jack_ringbuffer_t *lring, *rring;
 jack_nframes_t size;
 
 BOOLEAN playing = FALSE;
-double wpm = 18.0, freq = 750.0, gain = -6.0;
+double wpm = 18.0, freq = 750.0, gain = -6.0, ramp = 5.0;
 
 COMPLEX *zout = 0;
 
@@ -82,10 +82,13 @@ void send_sound(COMPLEX *, int);
 
 //------------------------------------------------------------
 
-// map char -> morse string
+// try to map char -> morse string
 char *
 get_morse(int c) { return morse_table[c & 0x7F]; }
 
+// translate text input to timed, sub-morse-element
+// audio segment specs; parcel the segments out
+// one at a time to the sound player
 void
 reader_thread(void) {
   BOOLEAN b = TRUE; // we're coming from silence
@@ -99,21 +102,23 @@ reader_thread(void) {
     if (m = get_morse(c)) {
       
       // yup
-      // for each sub-element (dit/dah)
+      // for each element in morse string
+      // (dit/dah, doesn't matter)
       while (e = *m++) {
-       // first segment is slew in...
+       // first segment is ramp up...
        sem_wait(&reader);
        morsel.type = ME_RAMP, morsel.size = risesize;
        morsel.curr = 0.0, morsel.incr = riseincr;
        sem_post(&writer);
        
        // ...then steady state...
+       // (choose dit/dah here)
        sem_wait(&reader);
        morsel.type = ME_STDY;
        morsel.size = e == '.' ? ditstdysize : dahstdysize;
        sem_post(&writer);
        
-       // ...then slew out...
+       // ...then ramp down...
        sem_wait(&reader);
        morsel.type = ME_RAMP, morsel.size = fallsize;
        morsel.curr = 1.0, morsel.incr = fallincr;
@@ -137,7 +142,8 @@ reader_thread(void) {
       b = FALSE;
 
     } else {
-      // anything else treated as interword space
+      // anything else treated as interword space,
+      // which has only one segment (silence)
       sem_wait(&reader);
       morsel.type = ME_ZERO;
       // was previous output also interword space?
@@ -167,25 +173,25 @@ sound_thread(void) {
          scale = pow(10.0, gain / 20.0);
   COMPLEX z, delta_z;
 
-  // as long as there's been no EOF on the input...
+  // keep looking for sub-element segments, one at a time
   for (;;) {
 
-    // pause for next sub-element
+    // pause for next sub-element segment
     sem_post(&reader);
     sem_wait(&writer);
 
     // no more data?
     if (morsel.type == ME_EOF) break;
 
-    // interword space == silence?
+    // requires playing some tone?
     if (morsel.type != ME_ZERO) {
-      // no, set up CORDIC tone generation
+      // yes, set up CORDIC tone generation
       if (phase > HUGE_PHASE) phase -= HUGE_PHASE;
       z = Cmplx(cos(phase), sin(phase));
       delta_z = Cmplx(cos(ofreq), sin(ofreq));
     }
 
-    // play out this sub-segment
+    // play out this segment
     for (i = 0; i < morsel.size; i++) {
 
       // make silence
@@ -195,7 +201,7 @@ sound_thread(void) {
       else {
        z = Cmul(z, delta_z);
        phase += ofreq;
-       // slewing segment?
+       // is this a ramping segment?
        if (morsel.type == ME_RAMP) {
          morsel.curr += morsel.incr;
          zout[k] = Cscl(z, scale * sin(morsel.curr * M_PI / 2.0));
@@ -203,15 +209,15 @@ sound_thread(void) {
          zout[k] = Cscl(z, scale);
       }
 
-      // one jack bufferful yet?
+      // have we played enough to fill a jack buffer?
       if (++k >= size) {
        // yes, send to output
        send_sound(zout, k);
-       // wait until it's been taken away
+       // wait until some audio has been drained
        sem_wait(&ready);
        k = 0;
-       // reset CORDIC
        if (morsel.type != ME_ZERO) {
+         // reset CORDIC
          if (phase > HUGE_PHASE) phase -= HUGE_PHASE;
          z = Cmplx(cos(phase), sin(phase));
          delta_z = Cmplx(cos(ofreq), sin(ofreq));
@@ -220,7 +226,7 @@ sound_thread(void) {
     }
   }
 
-  // anything left unsent in buffer?
+  // anything left unsent?
   if (k > 0) send_sound(zout, k);
 
   pthread_exit(0);
@@ -298,8 +304,11 @@ main(int argc, char **argv) {
       case 'w':
        wpm = atof(argv[++i]);
        break;
+      case 'r':
+       ramp = atof(argv[++i]);
+       break;
       default:
-       fprintf(stderr, "keyd [-w wpm] [-f freq] [infile]\n");
+       fprintf(stderr, "keyd [-w wpm] [-f freq] [-r ramp_ms] [infile]\n");
        exit(1);
       }
     else break;
@@ -313,7 +322,7 @@ main(int argc, char **argv) {
   //------------------------------------------------------------
 
   morsel.wpm = wpm;
-  morsel.rise = morsel.fall = 5.0; // ms
+  morsel.rise = morsel.fall = ramp;
   morsel.rate = SAMP_RATE;
 
   ditspacesize = SAMP_RATE * 1.2 / morsel.wpm + 0.5;
@@ -386,7 +395,7 @@ main(int argc, char **argv) {
       exit(1);
     }
     if (jack_connect(client, jack_port_name(rport), ports[1])) {
-      fprintf(stderr, "can't connect left output\n");
+      fprintf(stderr, "can't connect right output\n");
       exit(1);
     }
     free(ports);