summaryrefslogtreecommitdiffstats
path: root/src/ccitt-adpcm/decode.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccitt-adpcm/decode.c')
-rw-r--r--src/ccitt-adpcm/decode.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/ccitt-adpcm/decode.c b/src/ccitt-adpcm/decode.c
new file mode 100644
index 0000000..cf8c739
--- /dev/null
+++ b/src/ccitt-adpcm/decode.c
@@ -0,0 +1,113 @@
+/*
+ * decode.c
+ *
+ * CCITT ADPCM decoder
+ *
+ * Usage : decode [-3|4|5] [-a|u|l] < infile > outfile
+ */
+#include <stdio.h>
+#include "g72x.h"
+
+
+/*
+ * Unpack input codes and pass them back as bytes.
+ * Returns 1 if there is residual input, returns -1 if eof, else returns 0.
+ */
+int
+unpack_input(
+ unsigned char *code,
+ int bits)
+{
+ static unsigned int in_buffer = 0;
+ static int in_bits = 0;
+ unsigned char in_byte;
+
+ if (in_bits < bits) {
+ if (fread(&in_byte, sizeof (char), 1, stdin) != 1) {
+ *code = 0;
+ return (-1);
+ }
+ in_buffer |= (in_byte << in_bits);
+ in_bits += 8;
+ }
+ *code = in_buffer & ((1 << bits) - 1);
+ in_buffer >>= bits;
+ in_bits -= bits;
+ return (in_bits > 0);
+}
+
+
+main(
+ int argc,
+ char **argv)
+{
+ short sample;
+ unsigned char code;
+ int n;
+ struct g72x_state state;
+ int out_coding;
+ int out_size;
+ int (*dec_routine)();
+ int dec_bits;
+
+ g72x_init_state(&state);
+ out_coding = AUDIO_ENCODING_ULAW;
+ out_size = sizeof (char);
+ dec_routine = g721_decoder;
+ dec_bits = 4;
+
+ /* Process encoding argument, if any */
+ while ((argc > 1) && (argv[1][0] == '-')) {
+ switch (argv[1][1]) {
+ case '3':
+ dec_routine = g723_24_decoder;
+ dec_bits = 3;
+ break;
+ case '4':
+ dec_routine = g721_decoder;
+ dec_bits = 4;
+ break;
+ case '5':
+ dec_routine = g723_40_decoder;
+ dec_bits = 5;
+ break;
+ case 'u':
+ out_coding = AUDIO_ENCODING_ULAW;
+ out_size = sizeof (char);
+ break;
+ case 'a':
+ out_coding = AUDIO_ENCODING_ALAW;
+ out_size = sizeof (char);
+ break;
+ case 'l':
+ out_coding = AUDIO_ENCODING_LINEAR;
+ out_size = sizeof (short);
+ break;
+ default:
+fprintf(stderr, "CCITT ADPCM Decoder -- usage:\n");
+fprintf(stderr, "\tdecode [-3|4|5] [-a|u|l] < infile > outfile\n");
+fprintf(stderr, "where:\n");
+fprintf(stderr, "\t-3\tProcess G.723 24kbps (3-bit) input data\n");
+fprintf(stderr, "\t-4\tProcess G.721 32kbps (4-bit) input data [default]\n");
+fprintf(stderr, "\t-5\tProcess G.723 40kbps (5-bit) input data\n");
+fprintf(stderr, "\t-a\tGenerate 8-bit A-law data\n");
+fprintf(stderr, "\t-u\tGenerate 8-bit u-law data [default]\n");
+fprintf(stderr, "\t-l\tGenerate 16-bit linear PCM data\n");
+ exit(1);
+ }
+ argc--;
+ argv++;
+ }
+
+ /* Read and unpack input codes and process them */
+ while (unpack_input(&code, dec_bits) >= 0) {
+ sample = (*dec_routine)(code, out_coding, &state);
+ if (out_size == 2) {
+ fwrite(&sample, out_size, 1, stdout);
+ } else {
+ code = (unsigned char)sample;
+ fwrite(&code, out_size, 1, stdout);
+ }
+ }
+ fclose(stdout);
+}