new fec modes and interleaver for 1600
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 18 Mar 2013 04:23:58 +0000 (04:23 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 18 Mar 2013 04:23:58 +0000 (04:23 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1210 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/Makefile.am
codec2-dev/src/fdmdv_interleave.c
codec2-dev/src/fec_dec.c
codec2-dev/src/fec_enc.c
codec2-dev/src/golay23.c
codec2-dev/src/insert_errors.c

index 1e856aaf047f94009d50bcdd2662d2e84efa4445..50370a80f725bba18fc0c5c82ab58ec355e092d8 100644 (file)
@@ -147,7 +147,7 @@ library_includedir = $(prefix)/include
 library_include_HEADERS        = codec2.h codec2_fdmdv.h codec2_fifo.h
 
 bin_PROGRAMS = c2demo c2enc c2dec c2sim fdmdv_get_test_bits fdmdv_mod fdmdv_demod \
-fdmdv_put_test_bits fdmdv_interleave insert_errors fec_enc fec_dec
+fdmdv_put_test_bits fdmdv_interleave insert_errors fec_enc fec_dec 
 
 c2demo_SOURCES = c2demo.c
 c2demo_LDADD = $(lib_LTLIBRARIES) 
@@ -190,3 +190,4 @@ fec_enc_LDFLAGS = $(LIBS)
 fec_dec_SOURCES =  fec_dec.c  golay23.c
 fec_dec_LDADD = $(lib_LTLIBRARIES) 
 fec_dec_LDFLAGS = $(LIBS)
+
index 5e3aa643b80201e045e602b8434602d1a24bd7ea..beb98ecba3c2f27c66c3f0fb08c304b95fbcd94b 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "codec2_fdmdv.h"
 
-#define MAX_INTERLEAVER 1024
+#define MAX_INTERLEAVER 10000
 
 int main(int argc, char *argv[])
 {
@@ -97,6 +97,7 @@ int main(int argc, char *argv[])
 
     m = src_bit;
     fprintf(stderr, "Interleaver size m = %d  interleave = %d\n", m, interleave);
+    assert((m%8) == 0);
     mpacked = m/8;
 
     packed_bits = (char*)malloc(mpacked*sizeof(char));
index 52912cbc6a46879090b7185a3ae5e7a32e549384..350b01196d3fb62e4a739be8155ab940a2fbbd03 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
 int main(int argc, char *argv[])
 {
     void          *codec2, *fdmdv;
@@ -47,12 +51,12 @@ int main(int argc, char *argv[])
     int            bits_per_output_frame, bytes_per_output_frame;
     unsigned char *packed_output_bits;
     int           *unpacked_output_bits;
-    int            mode, Nc, bit, byte;
-    int            i;
+    int            codec2_mode, mode, Nc, bit, byte;
+    int            i,j;
     int            recd_codeword, codeword1, codeword2;
 
     if (argc < 3) {
-       printf("%s InputFromModemWithFECFile OutputToCodec2File\n", argv[0]);
+       printf("%s InputFromModemWithFECFile OutputToCodec2File [2000|1600]\n", argv[0]);
        exit(1);
     }
 
@@ -73,7 +77,28 @@ int main(int argc, char *argv[])
     /* input parameters and buffers. Note data is split into two 20ms
        frames for transmission over modem. */
 
-    Nc = 20;
+    if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) {
+        /* 2000 bit/s with FEC */
+        mode = MODE_2000;
+       codec2_mode = CODEC2_MODE_1400;
+        Nc = 20;
+    } else if ((strcmp(argv[3],"1850") == 0)) {
+        /* 1850 bit/s with FEC */
+        mode = MODE_1850;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 20;
+    }
+    else if (strcmp(argv[3],"1600") == 0) {
+        /* 1600 bit/s with FEC (actually 1575 with one spare) */
+        mode = MODE_1600;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 16;
+    }
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2000 or 1600\n", argv[3]);
+       exit(1);
+    }
+
     fdmdv = fdmdv_create(Nc);
 
     bits_per_input_frame = 2*fdmdv_bits_per_frame(fdmdv);
@@ -89,20 +114,18 @@ int main(int argc, char *argv[])
        Output parameters and buffers.
     */
 
-    mode = CODEC2_MODE_1400;
-    codec2 = codec2_create(mode);
+    codec2 = codec2_create(codec2_mode);
 
     bits_per_output_frame = codec2_bits_per_frame(codec2);
-    bytes_per_output_frame = bits_per_output_frame/8;
-    assert((bits_per_output_frame % 8) == 0); /* make sure integer number of bytes per frame */
+    bytes_per_output_frame = (bits_per_output_frame+7)/8;
 
     packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char));
     assert(packed_output_bits != NULL);
     unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int));
     assert(unpacked_output_bits != NULL);
     
-    // fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
-    //        bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
+    fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
+            bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
 
     /* main loop */
 
@@ -121,7 +144,6 @@ int main(int argc, char *argv[])
                byte++;
            }
        }
-       assert(byte == bytes_per_input_frame);
 
         #ifdef TEST
         /* Some test bit errors (not comprehesnive) */
@@ -129,47 +151,125 @@ int main(int argc, char *argv[])
         unpacked_input_bits[23] = (unpacked_input_bits[23] ^ 1) & 0x1;
         #endif
 
-        /* decode first codeword */
+        if (mode == MODE_2000) {
+            /* decode first codeword */
 
-        recd_codeword = 0;
-        for(i=0; i<12; i++) {
-            recd_codeword <<= 1;
-            recd_codeword |= unpacked_input_bits[i];
-        }
-        for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
-            recd_codeword <<= 1;
-            recd_codeword |= unpacked_input_bits[i];
-        }
-        codeword1 = golay23_decode(recd_codeword);
-        //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+            recd_codeword = 0;
+            for(i=0; i<12; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
 
-        for(i=0; i<12; i++) {
-            unpacked_output_bits[i] = codeword1 >> (22-i);
-        }
+            for(i=0; i<12; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+
+            /* decode second codeword */
 
-        /* decode second codeword */
+            recd_codeword = 0;
+            for(i=12; i<24; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_decode(recd_codeword);
+            //codeword2 = recd_codeword;
+            //fprintf(stderr, "received codeword2: 0x%x  decoded codeword2: 0x%x\n", recd_codeword, codeword2);
+
+            for(i=0; i<12; i++) {
+                unpacked_output_bits[12+i] = (codeword2 >> (22-i)) & 0x1;
+            }
 
-        recd_codeword = 0;
-        for(i=12; i<24; i++) {
-            recd_codeword <<= 1;
-            recd_codeword |= unpacked_input_bits[i];
+            /* unprotected bits */
+
+            for(i=24; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
         }
-        for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
-            recd_codeword <<= 1;
-            recd_codeword |= unpacked_input_bits[i];
+        if (mode == MODE_1600) {
+            recd_codeword = 0;
+            for(i=0; i<8; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+           
+            for(i=0; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+
+            for(i=0; i<8; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=8,j=11; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1;
+            }
         }
-        codeword2 = golay23_decode(recd_codeword);
-        //fprintf(stderr, "received codeword2: 0x%x  decoded codeword2: 0x%x\n", recd_codeword, codeword2);
 
-        for(i=0; i<12; i++) {
-            unpacked_output_bits[12+i] = codeword2 >> (22-i);
+        if (mode == MODE_1850) {
+            recd_codeword = 0;
+            for(i=0; i<8; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+           
+            recd_codeword = 0;
+            for(i=16; i<28; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_decode(recd_codeword);
+            fprintf(stderr, "received codeword2: 0x%x  decoded codeword2: 0x%x\n", recd_codeword, codeword2);
+          
+            for(i=0; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            
+            for(i=0; i<8; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=8,j=11; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=0,j=16; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword2 >> (22-i)) & 0x1;
+            }
+            
         }
 
-        /* unprotected bits */
-
-        for(i=24; i<bits_per_output_frame; i++)
-            unpacked_output_bits[i] = unpacked_input_bits[i];
-
         /* pack bits, MSB first  */
 
         bit = 7; byte = 0;
@@ -182,7 +282,6 @@ int main(int argc, char *argv[])
                 byte++;
             }
         }
-        assert(byte == bytes_per_output_frame);
         
        fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
 
index 26c4d11589a9cd706e6a3179f1d291a26d9e867c..3bf177751440a7997e57a0579a7143b3ccea03dd 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
 int main(int argc, char *argv[])
 {
     void          *codec2, *fdmdv;
@@ -49,12 +53,12 @@ int main(int argc, char *argv[])
     int            bits_per_output_frame, bytes_per_output_frame;
     unsigned char *packed_output_bits;
     int           *unpacked_output_bits;
-    int            mode, Nc, bit, byte;
+    int            codec2_mode, mode, Nc, bit, byte;
     int            i,j;
     int            data, codeword1, codeword2;
 
     if (argc < 3) {
-       printf("%s InputFromCodecFile OutputToModemWithFECFile\n", argv[0]);
+       printf("%s InputFromCodecFile OutputToModemWithFECFile [2000|1850|1600]\n", argv[0]);
        exit(1);
     }
 
@@ -72,14 +76,34 @@ int main(int argc, char *argv[])
        exit(1);
     }
 
+    if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) {
+        /* 2000 bit/s with FEC */
+        mode = MODE_2000;
+       codec2_mode = CODEC2_MODE_1400;
+        Nc = 20;
+    } else if ((strcmp(argv[3],"1850") == 0)) {
+        /* 1850 bit/s with FEC */
+        mode = MODE_1850;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 20;
+    }
+    else if (strcmp(argv[3],"1600") == 0) {
+        /* 1600 bit/s with FEC (actually 1575 with one spare) */
+        mode = MODE_1600;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 16;
+    }
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2000, 1850, or 1600\n", argv[3]);
+       exit(1);
+    }
+    
     /* input parameters and buffers */
 
-    mode = CODEC2_MODE_1400;
-    codec2 = codec2_create(mode);
+    codec2 = codec2_create(codec2_mode);
 
     bits_per_input_frame = codec2_bits_per_frame(codec2);
-    bytes_per_input_frame = bits_per_input_frame / 8;
-    assert((bits_per_input_frame % 8) == 0); /* make sure integer number of bytes per frame */
+    bytes_per_input_frame = (bits_per_input_frame + 7)/8;
 
     packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char));
     assert(packed_input_bits != NULL);
@@ -92,20 +116,19 @@ int main(int argc, char *argv[])
        bother us here, as fdmdv_mod takes care of that.
     */
 
-    Nc = 20;
     fdmdv = fdmdv_create(Nc);
 
     bits_per_output_frame = 2*fdmdv_bits_per_frame(fdmdv);
-    bytes_per_output_frame = bits_per_output_frame/8;
-    assert((bits_per_output_frame % 8) == 0); /* make sure integer number of bytes per frame */
+    bytes_per_output_frame = (bits_per_output_frame+7)/8;
 
     packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char));
     assert(packed_output_bits != NULL);
     unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int));
     assert(unpacked_output_bits != NULL);
     
-    //fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
-    //        bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
+    fprintf(stderr, "mode: %d  Nc: %d\n", mode, Nc);
+    fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
+            bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
 
     /* main loop */
 
@@ -124,47 +147,126 @@ int main(int argc, char *argv[])
                byte++;
            }
        }
-       assert(byte == bytes_per_input_frame);
 
-        /* add FEC  ----------------------------------*/
+        /* add FEC  ---------------------------------------------------------*/
 
-        /* Protect first 24 bits with (23,12) Golay Code.  The first
-           24 bits are the most sensitive, as they contain the
-           pitch/energy VQ and voicing bits. This uses 56 + 11 + 11 =
-           78 bits, so we have two spare in 80 bit frame sent to
-           modem. */
+        if (mode == MODE_2000) {
+            /* Protect first 24 bits with (23,12) Golay Code.  The first
+               24 bits are the most sensitive, as they contain the
+               pitch/energy VQ and voicing bits. This uses 56 + 11 + 11 =
+               78 bits, so we have two spare in 80 bit frame sent to
+               modem. */
 
-        /* first codeword */
+            /* first codeword */
 
-        data = 0;
-        for(i=0; i<12; i++) {
-            data <<= 1;
-            data |= unpacked_input_bits[i];
-        }
-        codeword1 = golay23_encode(data);
-        //fprintf(stderr, "data1: 0x%x codeword1: 0x%x\n", data, codeword1);
+            data = 0;
+            for(i=0; i<12; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+            //fprintf(stderr, "data1: 0x%x codeword1: 0x%x\n", data, codeword1);
 
-        /* second codeword */
+            /* second codeword */
 
-        data = 0;
-        for(i=12; i<24; i++) {
-            data <<= 1;
-            data |= unpacked_input_bits[i];
+            data = 0;
+            for(i=12; i<24; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_encode(data);
+            //fprintf(stderr, "data: 0x%x codeword2: 0x%x\n", data, codeword2);
+
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data the protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+            }
+            for(j=0; i<bits_per_input_frame+11+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword2 >> (10-j)) & 0x1;
+            }
         }
-        codeword2 = golay23_encode(data);
-        //fprintf(stderr, "data: 0x%x codeword2: 0x%x\n", data, codeword2);
 
-        /* now pack output frame with parity bits at end to make them
-           as far apart as possible from the data the protect.  Parity
-           bits are LSB of the Golay codeword */
+        if (mode == MODE_1850) {
 
-        for(i=0; i<bits_per_input_frame; i++)
-            unpacked_output_bits[i] = unpacked_input_bits[i];
-        for(j=0; i<bits_per_input_frame+11; i++,j++) {
-            unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+            /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code:
+
+               0,1,2,3: v[0]..v[1]
+               4,5,6,7: MSB of pitch
+               11,12,13,14: MSB of energy
+
+            */
+
+            data = 0;
+            for(i=0; i<8; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+
+            /* Protect first 12 LSP bits with (23,12) Golay Code */
+
+            data = 0;
+            for(i=16; i<28; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_encode(data);
+            fprintf(stderr, "codeword2: 0x0%x\n", codeword2);
+            
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data they protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+                unpacked_output_bits[i+11] = (codeword2 >> (10-j)) & 0x1;
+            }
+            for(i=bits_per_input_frame+11+11; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = 0;
         }
-        for(j=0; i<bits_per_input_frame+11+11; i++,j++) {
-            unpacked_output_bits[i] = (codeword2 >> (10-j)) & 0x1;
+
+        if (mode == MODE_1600) {
+
+            /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code:
+
+               0,1,2,3: v[0]..v[1]
+               4,5,6,7: MSB of pitch
+               11,12,13,14: MSB of energy
+
+            */
+
+
+            data = 0;
+            for(i=0; i<8; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data they protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+            }
         }
 
         /* pack bits, MSB first  */
index da681b936287c0a210a27ca0c97fea9b78bdfdf7..e325786a1c5f0f2eab792d803383bd64e867e347 100644 (file)
@@ -263,6 +263,7 @@ int golay23_encode(int data) {
 int golay23_decode(int received_codeword) {
     assert(inited);
 
+    //printf("syndrome: 0x%x\n", get_syndrome(received_codeword));
     return received_codeword ^= decoding_table[get_syndrome(received_codeword)];
 }
 
index 1d51db81861d0f9c7495a1f66e60a41a468948e5..2a1877b1b1ca1da2fa104f3080b114bcb1379ef2 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-// This just assumes 1400 bit/s mode for now
-
-#define BITS_PER_FRAME  56
-#define BYTES_PER_FRAME  7
-   
 int main(int argc, char *argv[])
 {
     FILE          *fin;
@@ -50,9 +45,11 @@ int main(int argc, char *argv[])
     unsigned char  byte;
     short          error;
     int            errors, bits;
+    int            bits_per_frame, bytes_per_frame;
 
-    if (argc < 3) {
-       printf("%s InputBitFile OutputBitFile ErrorFile [startBit endBit]\n", argv[0]);
+    if (argc < 4) {
+       printf("%s InputBitFile OutputBitFile ErrorFile bitsPerFrame [startBit endBit]\n", argv[0]);
+       printf("%s InputBitFile OutputBitFile BER\n", argv[0]);
        exit(1);
     }
 
@@ -76,10 +73,14 @@ int main(int argc, char *argv[])
        exit(1);
     }
 
-    start_bit = 0; end_bit = BITS_PER_FRAME;
-    if (argc == 6) {
-       start_bit = atoi(argv[4]);
-       end_bit = atoi(argv[5]);   
+    bits_per_frame = atoi(argv[4]);
+    assert((bits_per_frame % 8) == 0);
+    bytes_per_frame = bits_per_frame/8;
+
+    start_bit = 0; end_bit = bits_per_frame;
+    if (argc == 7) {
+       start_bit = atoi(argv[5]);
+       end_bit = atoi(argv[6]);   
     }
         
     bit = 0;
@@ -102,10 +103,13 @@ int main(int argc, char *argv[])
                 exit(0);
             }
             bit++;
-            if (bit == BITS_PER_FRAME)
+            if (bit == bits_per_frame)
                 bit = 0;
         }
         fwrite(&byte, sizeof(char), 1, fout);
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);         
     }
 
     fclose(fin);