optional Fs/4 freq shift and some optimisation of tlininterp
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Jan 2017 23:27:21 +0000 (23:27 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 30 Jan 2017 23:27:21 +0000 (23:27 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3009 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/unittest/tdec.c
codec2-dev/unittest/tlininterp.c

index 6b1f245f7c6b50d7b8df0c480133e1f0eb0dbb23..9addcfe977230637e700e8f9d02a6988d4754473 100644 (file)
 #define SIGNED_16BIT   0
 #define SIGNED_8BIT    1
 
+void freq_shift_complex_buf(short buf[], int n, int lo_i[], int lo_q[]);
+
 void display_help(void) {
     fprintf(stderr, "\nusage: tdec inputRawFile OutputRawFile DecimationRatio [-c]\n");
     fprintf(stderr, "\nUse - for stdin/stdout\n\n");
     fprintf(stderr, "-c complex signed 16 bit input and output\n");
     fprintf(stderr, "-d complex signed 8 bit input, complex signed 16 bit output\n\n");
+    fprintf(stderr, "-f -Fs/4 freq shift\n\n");
 }
 
 int main(int argc, char *argv[]) {
     FILE       *fin, *fout;
     short       dec;
+    int         lo_i[3], lo_q[3];
 
     if (argc < 3) {
        display_help();
@@ -50,12 +54,16 @@ int main(int argc, char *argv[]) {
     dec = atoi(argv[3]);
 
     int channels = 1;
+    int freq_shift = 0;
+    lo_i[0] = -1; lo_i[1] =  0;
+    lo_q[0] =  0; lo_q[1] = -1;
     int opt;
     int format = SIGNED_16BIT;
-    while ((opt = getopt(argc, argv, "cd")) != -1) {
+    while ((opt = getopt(argc, argv, "cdf")) != -1) {
         switch (opt) {
         case 'c': channels = 2; break;
         case 'd': channels = 2; format = SIGNED_8BIT; break;
+        case 'f': freq_shift = 1; break;
         default:
             display_help();
             exit(1);
@@ -65,20 +73,25 @@ int main(int argc, char *argv[]) {
     if (format == SIGNED_16BIT) {
         short buf[dec*channels];
         while(fread(buf, sizeof(short)*channels, dec, fin) == dec) {
+            if (freq_shift)            
+                freq_shift_complex_buf(buf, dec*channels, lo_i, lo_q);
+            exit(0);
             fwrite(buf, sizeof(short), channels, fout);
         }
     }
     else {
         uint8_t inbuf[dec*channels];
-        short   outbuf[channels];
+        short   outbuf[dec*channels];
         short   sam, i;
         
         while(fread(inbuf, sizeof(uint8_t)*channels, dec, fin) == dec) {
-            for (i=0; i<channels; i++) {
+            for (i=0; i<dec*channels; i++) {
                 sam = (short)inbuf[i];
                 sam <<= 8;
                 outbuf[i] = sam;
             }
+            if (freq_shift)
+                freq_shift_complex_buf(outbuf, dec*channels, lo_i, lo_q);
             fwrite(outbuf, sizeof(short), channels, fout);
         }
 
@@ -89,3 +102,32 @@ int main(int argc, char *argv[]) {
 
     return 0;
 }
+                
+
+void freq_shift_complex_buf(short buf[], int n, int lo_i[], int lo_q[]) {
+    int i;
+
+    for (i=0; i<n; i+=2) {
+        /* update local osc recursion */
+
+        lo_i[2] = -lo_i[0]; lo_q[2] = -lo_q[0];
+
+        /* freq shift down input samples */
+
+        int a = buf[i];
+        int b = buf[i+1];
+        int c = lo_i[2];
+        int d = -lo_q[2];  /* conj LO as down shift */
+
+        buf[i]   = a*c - b*d;
+        buf[i+1] = b*c + a*d;
+
+        //fprintf(stderr, "% d % d % 5d % 5d\n", lo_i[2], lo_q[2], buf[i], buf[i+1]);
+
+        /* update LO memory */
+
+        lo_i[0] = lo_i[1]; lo_i[1] = lo_i[2]; 
+        lo_q[0] = lo_q[1]; lo_q[1] = lo_q[2]; 
+    }
+}
+
index 8ec89b46bdb3caad36b13f53735427173e9f7401..fe0373cd36ebbdd2e0b5b5167c1a637bcdb8d1eb 100644 (file)
 #include <stdio.h>
 #include <stdint.h>
 
-#define SIGNED_16BIT   0
-#define SIGNED_8BIT    1
+#define NBUF         1000
+#define SIGNED_16BIT    0
+#define SIGNED_8BIT     1
 
 void display_help(void) {
     fprintf(stderr, "\nusage: tlininterp inputRawFile OutputRawFile OverSampleRatio [-c]\n");
     fprintf(stderr, "\nUse - for stdin/stdout\n\n");
     fprintf(stderr, "-c complex signed 16 bit input and output\n");
     fprintf(stderr, "-d complex signed 16 bit input, complex signed 8 bit output\n\n");
+    fprintf(stderr, "-d complex signed 16 bit input, complex signed 8 bit output\n\n");
+    fprintf(stderr, "-f +Fs/4 freq shift\n\n");
 }
 
 int main(int argc, char *argv[]) {
     FILE       *fin, *fout;
-    short       left[2], right[2], out[2], i;
+    short       left[2], right[2], out[2*NBUF], i;
     float       oversample, t;
-    int8_t      out_s8[2];
+    int8_t      out_s8[2*NBUF];
+    int         lo_i[3], lo_q[3];
 
     if (argc < 3) {
        display_help();
@@ -54,12 +58,16 @@ int main(int argc, char *argv[]) {
     oversample = atof(argv[3]);
 
     int channels = 1;
+    int freq_shift = 0;
+    lo_i[0] = -1; lo_i[1] =  0;
+    lo_q[0] =  0; lo_q[1] = -1;
     int format = SIGNED_16BIT;
     int opt;
-    while ((opt = getopt(argc, argv, "cd")) != -1) {
+    while ((opt = getopt(argc, argv, "cdf")) != -1) {
         switch (opt) {
         case 'c': channels = 2; break;
         case 'd': channels = 2; format = SIGNED_8BIT; break;
+        case 'f': freq_shift = 1; break;
         default:
             display_help();
             exit(1);
@@ -69,30 +77,72 @@ int main(int argc, char *argv[]) {
     for (i=0; i<channels; i++)
         left[i] = 0;
     t = 0.0;
+    int j = 0;
     while(fread(&right, sizeof(short)*channels, 1, fin) == 1) {
         while (t < 1.0) {
 
             for (i=0; i<channels; i++) {
-                out[i] = (1.0 - t)*left[i] + t*right[i];
+                out[j+i] = (1.0 - t)*left[i] + t*right[i];
+            }
+
+            if (freq_shift) {
+
+                /* update local osc recursion */
+
+                lo_i[2] = -lo_i[0]; lo_q[2] = -lo_q[0];
+
+                /* complex mixer to up-shift complex samples */
+
+                int a = out[0];
+                int b = out[1];
+                int c = lo_i[2];
+                int d = lo_q[2];
+
+                out[j]   = a*c - b*d;
+                out[j+1] = b*c + a*d;
+
+                //fprintf(stderr, "% d % d % 5d % 5d\n", lo_i[2], lo_q[2], out[0], out[1]);
+
+                /* update LO memory */
+
+                lo_i[0] = lo_i[1]; lo_i[1] = lo_i[2]; 
+                lo_q[0] = lo_q[1]; lo_q[1] = lo_q[2]; 
             }
 
-            if (format == SIGNED_16BIT) {
-                fwrite(&out, sizeof(short), channels, fout);
-            } else {
-                //fprintf(stderr,"8 bit out\n");
-                for (i=0; i<channels; i++) {
-                    out_s8[i] = out[i] >> 8;
+            /* once we have enough samples write to disk */
+
+            j++;
+            if (j == NBUF) {
+                if (format == SIGNED_16BIT) {
+                    fwrite(&out, sizeof(short)*channels, NBUF, fout);
+                } else {
+                    for (i=0; i<channels*NBUF; i++) {
+                        out_s8[i] = out[i] >> 8;
+                    }
+                    fwrite(&out_s8, sizeof(int8_t)*channels, NBUF, fout);
                 }
-                fwrite(&out_s8, sizeof(int8_t), channels, fout);
+                j = 0;
             }
 
             t += 1.0/oversample;
         }
+
         t -= 1.0;
         for (i=0; i<channels; i++)
             left[i] = right[i];
     }
 
+    /* write remaining samples to disk */
+
+    if (format == SIGNED_16BIT) {
+        fwrite(&out, sizeof(short)*channels, j, fout);
+    } else {
+        for (i=0; i<channels*j; i++) {
+            out_s8[i] = out[i] >> 8;
+        }
+        fwrite(&out_s8, sizeof(int8_t)*channels, j, fout);
+    }
+
     fclose(fout);
     fclose(fin);