Added header handling for .c2 files as discussed on mailing list
authornivex <nivex@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 1 Aug 2017 21:27:33 +0000 (21:27 +0000)
committernivex <nivex@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 1 Aug 2017 21:27:33 +0000 (21:27 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3341 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/src/c2dec.c
codec2-dev/src/c2enc.c
codec2-dev/src/c2file.h [new file with mode: 0644]

index 1a590ef4eae20aa1fd5aafe22180cf8e4e18f2cf..9092fd2045c26ef0b88b0e3ffd9845861a4cd3eb 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "codec2.h"
 #include "dump.h"
+#include "c2file.h"
 
 #include <assert.h>
 #include <stdio.h>
@@ -83,32 +84,6 @@ int main(int argc, char *argv[])
     if (argc < 4)
         print_help(long_options, num_opts, argv);
 
-    if (strcmp(argv[1],"3200") == 0)
-       mode = CODEC2_MODE_3200;
-    else if (strcmp(argv[1],"2400") == 0)
-       mode = CODEC2_MODE_2400;
-    else if (strcmp(argv[1],"1600") == 0)
-       mode = CODEC2_MODE_1600;
-    else if (strcmp(argv[1],"1400") == 0)
-       mode = CODEC2_MODE_1400;
-    else if (strcmp(argv[1],"1300") == 0)
-       mode = CODEC2_MODE_1300;
-    else if (strcmp(argv[1],"1200") == 0)
-       mode = CODEC2_MODE_1200;
-    else if (strcmp(argv[1],"700") == 0)
-       mode = CODEC2_MODE_700;
-    else if (strcmp(argv[1],"700B") == 0)
-       mode = CODEC2_MODE_700B; 
-    else if (strcmp(argv[1],"700C") == 0)
-       mode = CODEC2_MODE_700C;
-    else if (strcmp(argv[1],"WB") == 0)
-       mode = CODEC2_MODE_WB;
-   else {
-       fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400, 1300, 1200, 700, 700B, 700C or WB\n", argv[1]);
-       exit(1);
-    }
-    bit_rate = atoi(argv[1]);
-
     if (strcmp(argv[2], "-")  == 0) fin = stdin;
     else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
        fprintf(stderr, "Error opening input bit file: %s: %s.\n",
@@ -123,6 +98,56 @@ int main(int argc, char *argv[])
        exit(1);
     }
 
+    // Attempt to detect a .c2 file with a header
+    struct c2_header in_hdr;
+    char *ext = strrchr(argv[2], '.');
+    if (ext != NULL) {
+        if (strcmp(ext, ".c2") == 0) {
+            fread(&in_hdr,sizeof(in_hdr),1,fin);
+                
+            if (memcmp(in_hdr.magic, c2_file_magic, sizeof(c2_file_magic)) == 0) {
+                fprintf(stderr, "Detected Codec2 file version %d.%d in mode %d\n",
+                        in_hdr.version_major,
+                        in_hdr.version_minor,
+                        in_hdr.mode);
+                            
+                mode = in_hdr.mode;
+            } else {
+                fprintf(stderr, "Codec2 file specified but no header detected\n");
+                // Rewind the input file so we can try to decode
+                // based on command line mode selection
+                fseek(fin,0,SEEK_SET);
+            } /* end if - magic detection */
+        };
+    } else {
+        // If we got here, we need to honor the command line mode
+        if (strcmp(argv[1],"3200") == 0)
+        mode = CODEC2_MODE_3200;
+        else if (strcmp(argv[1],"2400") == 0)
+        mode = CODEC2_MODE_2400;
+        else if (strcmp(argv[1],"1600") == 0)
+        mode = CODEC2_MODE_1600;
+        else if (strcmp(argv[1],"1400") == 0)
+        mode = CODEC2_MODE_1400;
+        else if (strcmp(argv[1],"1300") == 0)
+        mode = CODEC2_MODE_1300;
+        else if (strcmp(argv[1],"1200") == 0)
+        mode = CODEC2_MODE_1200;
+        else if (strcmp(argv[1],"700") == 0)
+        mode = CODEC2_MODE_700;
+        else if (strcmp(argv[1],"700B") == 0)
+        mode = CODEC2_MODE_700B; 
+        else if (strcmp(argv[1],"700C") == 0)
+        mode = CODEC2_MODE_700C;
+        else if (strcmp(argv[1],"WB") == 0)
+        mode = CODEC2_MODE_WB;
+    else {
+        fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400, 1300, 1200, 700, 700B, 700C or WB\n", argv[1]);
+        exit(1);
+        }
+        bit_rate = atoi(argv[1]);
+    }; /* end if - extension / header detection */
+
     error_mode = NONE;
     ber = 0.0;
     burst_length = burst_period = 0.0;
index a1eeb9ae095e85a6950a5f88f596a05ede5c2711..66f94a95954e3f3286b03158aa417ab71439168e 100644 (file)
@@ -27,6 +27,7 @@
 */
 
 #include "codec2.h"
+#include "c2file.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -90,6 +91,22 @@ int main(int argc, char *argv[])
          argv[3], strerror(errno));
        exit(1);
     }
+    
+    // Write a header if we're writing to a .c2 file
+    char *ext = strrchr(argv[3], '.');
+    if (ext != NULL) {
+        if (strcmp(ext, ".c2") == 0) {
+            struct c2_header out_hdr;
+            memcpy(out_hdr.magic,c2_file_magic,sizeof(c2_file_magic));
+            out_hdr.mode = mode;
+            // TODO: Get these values from somewhere
+            out_hdr.version_major = 0;
+            out_hdr.version_minor = 0;
+            out_hdr.flags = 0;
+                
+            fwrite(&out_hdr,sizeof(out_hdr),1,fout);
+        };
+    };
 
     codec2 = codec2_create(mode);
     nsam = codec2_samples_per_frame(codec2);
diff --git a/codec2-dev/src/c2file.h b/codec2-dev/src/c2file.h
new file mode 100644 (file)
index 0000000..fccf95f
--- /dev/null
@@ -0,0 +1,19 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2file.h
+  AUTHOR......: Kevin Otte
+  DATE CREATED: 2017-08-01
+
+  Header structures for Codec2 file storage
+
+\*---------------------------------------------------------------------------*/
+
+const char c2_file_magic[3] = {0xc0, 0xde, 0xc2};
+
+struct c2_header {
+    char magic[3];
+    char version_major;
+    char version_minor;
+    char mode;
+    char flags;
+};