1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * testG711.cpp : Defines the entry point for the console application.
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdio.h>
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h>
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* include API */
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "g711_interface.h"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Runtime statistics */
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <time.h>
244a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org#define CLOCKS_PER_SEC_G711 1000
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* function for reading audio data from PCM file */
274a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.orgint readframe(int16_t* data, FILE* inp, int length) {
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
294a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  short k, rlen, status = 0;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
314a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  rlen = (short) fread(data, sizeof(int16_t), length, inp);
324a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if (rlen < length) {
334a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    for (k = rlen; k < length; k++)
344a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      data[k] = 0;
354a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    status = 1;
364a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
384a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  return status;
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
414a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.orgint main(int argc, char* argv[]) {
424a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  char inname[80], outname[40], bitname[40];
434a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  FILE* inp;
444a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  FILE* outp;
454a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  FILE* bitp = NULL;
464a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int framecnt, endfile;
474a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
484a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t framelength = 80;
494a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
504a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int err;
514a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
524a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Runtime statistics */
534a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  double starttime;
544a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  double runtime;
554a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  double length_file;
564a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
574a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t stream_len = 0;
584a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t shortdata[480];
594a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t decoded[480];
604a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t streamdata[500];
614a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  int16_t speechType[1];
624a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  char law[2];
634a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  char versionNumber[40];
644a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
654a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* handling wrong input arguments in the command line */
664a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if ((argc != 5) && (argc != 6)) {
674a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("\n\nWrong number of arguments or flag values.\n\n");
684a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
694a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("\n");
704a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("\nG.711 test application\n\n");
714a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("Usage:\n\n");
724a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("./testG711.exe framelength law infile outfile \n\n");
734a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("framelength: Framelength in samples.\n");
744a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("law        : Coding law, A och u.\n");
754a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("infile     : Normal speech input file\n");
764a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("outfile    : Speech output file\n\n");
774a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("outbits    : Output bitstream file [optional]\n\n");
784a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    exit(0);
794a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
804a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
814a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
824a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Get version and print */
834a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  WebRtcG711_Version(versionNumber, 40);
844a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
854a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("-----------------------------------\n");
864a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("G.711 version: %s\n\n", versionNumber);
874a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Get frame length */
884a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  framelength = atoi(argv[1]);
894a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
904a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Get compression law */
914a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  strcpy(law, argv[2]);
924a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
934a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Get Input and Output files */
944a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  sscanf(argv[3], "%s", inname);
954a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  sscanf(argv[4], "%s", outname);
964a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if (argc == 6) {
974a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    sscanf(argv[5], "%s", bitname);
984a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    if ((bitp = fopen(bitname, "wb")) == NULL) {
994a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      printf("  G.711: Cannot read file %s.\n", bitname);
1004a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      exit(1);
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1024a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
1034a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
1044a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if ((inp = fopen(inname, "rb")) == NULL) {
1054a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("  G.711: Cannot read file %s.\n", inname);
1064a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    exit(1);
1074a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
1084a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if ((outp = fopen(outname, "wb")) == NULL) {
1094a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("  G.711: Cannot write file %s.\n", outname);
1104a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    exit(1);
1114a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
1124a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("\nInput:  %s\nOutput: %s\n", inname, outname);
1134a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  if (argc == 6) {
1144a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    printf("\nBitfile:  %s\n", bitname);
1154a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
1164a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
1174a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  starttime = clock() / (double) CLOCKS_PER_SEC_G711; /* Runtime statistics */
1184a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
1194a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  /* Initialize encoder and decoder */
1204a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  framecnt = 0;
1214a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  endfile = 0;
1224a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  while (endfile == 0) {
1234a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    framecnt++;
1244a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    /* Read speech block */
1254a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    endfile = readframe(shortdata, inp, framelength);
1264a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org
1274a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    /* G.711 encoding */
1284a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    if (!strcmp(law, "A")) {
1294a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      /* A-law encoding */
1304a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      stream_len = WebRtcG711_EncodeA(NULL, shortdata, framelength, streamdata);
1314a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      if (argc == 6) {
1324a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org        /* Write bits to file */
1334a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org        if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
1344a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org            static_cast<size_t>(stream_len)) {
1354a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org          return -1;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1374a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      }
1384a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      err = WebRtcG711_DecodeA(NULL, streamdata, stream_len, decoded,
1394a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org                               speechType);
1404a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    } else if (!strcmp(law, "u")) {
1414a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      /* u-law encoding */
1424a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      stream_len = WebRtcG711_EncodeU(NULL, shortdata, framelength, streamdata);
1434a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      if (argc == 6) {
1444a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org        /* Write bits to file */
1454a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org        if (fwrite(streamdata, sizeof(unsigned char), stream_len, bitp) !=
1464a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org            static_cast<size_t>(stream_len)) {
1474a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org          return -1;
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1494a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      }
1504a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      err = WebRtcG711_DecodeU(NULL, streamdata, stream_len, decoded,
1514a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org                               speechType);
1524a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    } else {
1534a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      printf("Wrong law mode\n");
1544a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      exit(1);
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1564a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    if (stream_len < 0 || err < 0) {
1574a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      /* exit if returned with error */
1584a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      printf("Error in encoder/decoder\n");
1594a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    } else {
1604a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      /* Write coded speech to file */
1614a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      if (fwrite(decoded, sizeof(short), framelength, outp) !=
1624a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org          static_cast<size_t>(framelength)) {
1634a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org        return -1;
1644a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org      }
1654a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org    }
1664a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  }
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1684a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  runtime = (double)(clock() / (double) CLOCKS_PER_SEC_G711 - starttime);
1694a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  length_file = ((double) framecnt * (double) framelength / 8000);
1704a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("\n\nLength of speech file: %.1f s\n", length_file);
1714a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("Time to run G.711:      %.2f s (%.2f %% of realtime)\n\n",
1724a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org         runtime,
1734a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org         (100 * runtime / length_file));
1744a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  printf("---------------------END----------------------\n");
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1764a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  fclose(inp);
1774a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  fclose(outp);
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1794a48fd68ea57d801b0035101103846b8765af7e3pbos@webrtc.org  return 0;
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
181