1 /*
2  * Copyright (c) 2014-2016 Sippy Software, Inc., http://www.sippysoft.com
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  */
27 
28 #include <sys/endian.h>
29 #include <getopt.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 
34 #include "g722_encoder.h"
35 #include "g722_decoder.h"
36 
37 #define BUFFER_SIZE 10
38 
39 static void
usage(const char * argv0)40 usage(const char *argv0)
41 {
42 
43     fprintf(stderr, "usage: %s [--sln16k] [--bend] file.g722 file.raw\n"
44       "       %s --encode [--sln16k] [--bend] file.raw file.g722\n", argv0,
45       argv0);
46     exit (1);
47 }
48 
49 int
main(int argc,char ** argv)50 main(int argc, char **argv)
51 {
52     FILE *fi, *fo;
53     uint8_t ibuf[BUFFER_SIZE];
54     int16_t obuf[BUFFER_SIZE * 2];
55     G722_DEC_CTX *g722_dctx;
56     G722_ENC_CTX *g722_ectx;
57     int i, srate, ch, enc, bend;
58     size_t oblen;
59 
60     /* options descriptor */
61     static struct option longopts[] = {
62         { "sln16k", no_argument, NULL, 256 },
63         { "encode", no_argument, NULL, 257 },
64         { "bend",   no_argument, NULL, 258 },
65         { NULL,     0,           NULL,  0  }
66    };
67 
68    srate = G722_SAMPLE_RATE_8000;
69    oblen = sizeof(obuf) / 2;
70    enc = bend = 0;
71    while ((ch = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
72        switch (ch) {
73        case 256:
74            srate &= ~G722_SAMPLE_RATE_8000;
75            oblen *= 2;
76            break;
77        case 257:
78            enc = 1;
79            break;
80        case 258:
81            bend = 1;
82            break;
83        default:
84            usage(argv[0]);
85        }
86     }
87     argc -= optind;
88     argv += optind;
89 
90     if (argc != 2) {
91         usage(argv[-optind]);
92     }
93 
94     fi = fopen(argv[0], "r");
95     if (fi == NULL) {
96         fprintf(stderr, "cannot open %s\n", argv[0]);
97         exit (1);
98     }
99     fo = fopen(argv[1], "w");
100     if (fo == NULL) {
101         fprintf(stderr, "cannot open %s\n", argv[1]);
102         exit (1);
103     }
104 
105     if (enc == 0) {
106         g722_dctx = g722_decoder_new(64000, srate);
107         if (g722_dctx == NULL) {
108             fprintf(stderr, "g722_decoder_new() failed\n");
109             exit (1);
110         }
111 
112         while (fread(ibuf, sizeof(ibuf), 1, fi) == 1) {
113             g722_decode(g722_dctx, ibuf, sizeof(ibuf), obuf);
114             for (i = 0; i < (oblen / sizeof(obuf[0])); i++) {
115                 if (bend == 0) {
116                     obuf[i] = htole16(obuf[i]);
117                 } else {
118                     obuf[i] = htobe16(obuf[i]);
119                 }
120             }
121             fwrite(obuf, oblen, 1, fo);
122             fflush(fo);
123         }
124     } else {
125         g722_ectx = g722_encoder_new(64000, srate);
126         if (g722_ectx == NULL) {
127             fprintf(stderr, "g722_encoder_new() failed\n");
128             exit (1);
129         }
130         while (fread(obuf, oblen, 1, fi) == 1) {
131             for (i = 0; i < (oblen / sizeof(obuf[0])); i++) {
132                 if (bend == 0) {
133                     obuf[i] = le16toh(obuf[i]);
134                 } else {
135                     obuf[i] = be16toh(obuf[i]);
136                 }
137             }
138             g722_encode(g722_ectx, obuf, (oblen / sizeof(obuf[0])), ibuf);
139             fwrite(ibuf, sizeof(ibuf), 1, fo);
140             fflush(fo);
141         }
142     }
143 
144     fclose(fi);
145     fclose(fo);
146 
147     exit(0);
148 }
149