diff gsm_hr.c @ 0:9008dbc8ca74

import original C code from GSM 06.06
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 14 Jun 2024 23:27:16 +0000
parents
children a6db7d8d6df4
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gsm_hr.c	Fri Jun 14 23:27:16 2024 +0000
@@ -0,0 +1,480 @@
+/**************************************************************************
+ *
+ *   File Name:  gsm_hr.c
+ *
+ *   Purpose:
+ *
+ *     This file contains the main routine for the GSM Half Rate speech
+ *     codec.  The code for the speech coder, including the VAD, DTX,
+ *     Comfort Noise, bad frame handling (error concealment), and codec
+ *     homing functions is in the files listed below:
+ *
+ *     gsm_hr.c      globdefs.c      homing.c      host.c
+ *     mathdp31.c    mathhalf.c      sp_dec.c      sp_enc.c
+ *     sp_frm.c      sp_rom.c        sp_sfrm.c     vad.c
+ *     dtx.c         err_conc.c
+ *
+ *     This particular file only has the level 0, main(), and all level
+ *     1, main()'s daughter functions, in it.
+ *
+ *     Details on how to run gsm_hr are in the readme.txt file.
+ *
+ *     Below is a listing of all the functions appearing in the file.
+ *     The ordering is hierarchical.
+ *
+ *     main() "gsm_hr", main program.
+ *       encode() - encodes a speech file, outputs an encoded parameter file
+ *       decode() - decodes a parameter file, outputs a decoded speech file
+ *
+ **************************************************************************/
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Include Files                              |
+ |_________________________________________________________________________|
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "gsm_hr.h"
+#include "homing.h"
+#include "host.h"
+#include "sp_dec.h"
+#include "sp_enc.h"
+#include "typedefs.h"
+
+/****************************************************************************
+ *
+ *   PROGRAM NAME:  gsm_hr
+ *
+ *   PURPOSE:
+ *      gsm_hr - main program for the GSM Half-Rate speech coder.
+ *      Allows running one of the following operational modes:
+ *         0. Encoder only with speech input / encoded parameter data output.
+ *         1. Decoder only with speech parameter data input / speech output.
+ *
+ *   INPUT:
+ *      inputFileName     0. speech file in 8 kHz, pcm format.
+ *                        1. speech parameter file in decoder input format.
+ *      <number of frames> - number of frames to be processed (optional).
+ *      <dtx|nodtx>        - switch to enable/disable the DTX functions.
+ *
+ *   OUTPUT:
+ *      outputFileName    0. encoded paramter output file.
+ *                        1. synthesized speech file in 8 kHz, pcm format.
+ *
+ *   RETURN:
+ *      none
+ *
+ *   REFERENCES: Sub-clause 4.0 of GSM Recomendation 06.20
+ *
+ *   KEYWORDS: main, gsm_hr, speech codec, top level
+ *
+ ***************************************************************************/
+
+int    main(int argc, char *argv[])
+{
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Local Constants                              |
+ |_________________________________________________________________________|
+*/
+
+#define  DEFAULT_NUMFRAMES  32766
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Automatic Variables                          |
+ |_________________________________________________________________________|
+*/
+
+  int    iDoneFrm,
+         iMaxNumFrms,
+         option,
+         i;
+
+  FILE  *pfileInFile,
+        *pfileOutFile;
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Executable Code                            |
+ |_________________________________________________________________________|
+*/
+
+  /* check command line arguments */
+  /* ---------------------------- */
+
+  iMaxNumFrms = DEFAULT_NUMFRAMES;
+  giDTXon = 1;
+
+  /* check command line arguments */
+  /* ---------------------------- */
+
+  switch (argc)
+  {
+    case 4:
+
+      break;
+
+    case 5:
+    case 6:
+
+      for (i = 4; i < argc; i++)
+      {
+        if (!strcmp(argv[i], "dtx"))
+          giDTXon = 1;
+        else if (!strcmp(argv[i], "nodtx"))
+          giDTXon = 0;
+        else if ((iMaxNumFrms = atoi(argv[i])) <= 0)
+        {
+          printf("invalid number of frames or wrong DTX switch, %s", argv[i]);
+          exit(1);
+        }
+      }
+      break;
+
+    default:
+
+      printf("\n\nUsage:\n\n");
+      printf("gsm_hr option inputFileName outputFileName ");
+      printf("<number of frames> <dtx|nodtx>\n");
+      printf(" or\n");
+      printf("gsm_hr option inputFileName outputFileName ");
+      printf("<dtx|nodtx> <number of frames>\n");
+      printf("\nOptions: ");
+      printf("enc    ");
+      puts("inputFileName: speech --> outputFileName: encoder output");
+      printf("         ");
+      printf("dec    ");
+      puts("inputFileName: decoder input --> outputFileName: speech");
+      printf("\n");
+      exit(1);
+  }
+
+  /* check encoding and decoding options */
+  /* ----------------------------------- */
+
+  if (!strcmp(argv[1], "enc"))
+    option = 0;
+  else if (!strcmp(argv[1], "dec"))
+    option = 1;
+  else
+  {
+    printf("error in option selection\n");
+    printf(" Your entry : %s \n", argv[1]);
+    printf("\n\nUsage:\n\n");
+    printf("gsm_hr option inputFileName outputFileName ");
+    printf("<number of frames> <dtx|nodtx>\n");
+    printf(" or\n");
+    printf("gsm_hr option inputFileName outputFileName ");
+    printf("<dtx|nodtx> <number of frames>\n");
+    printf("\nOptions: ");
+    printf("enc    ");
+    puts("inputFileName: speech --> outputFileName: encoder output");
+    printf("         ");
+    printf("dec    ");
+    puts("inputFileName: decoder input --> outputFileName: speech");
+    printf("\n");
+    exit(1);
+  }
+
+
+  /* open the input and output files */
+  /* ------------------------------- */
+
+#ifdef VAX
+  pfileInFile = fopen(argv[2], "rb", "mrs=2", "rfm=fix", "ctx=stm");
+  pfileOutFile = fopen(argv[3], "wb", "mrs=2", "rfm=fix", "ctx=stm");
+#else
+  pfileInFile = fopen(argv[2], "rb");
+  pfileOutFile = fopen(argv[3], "wb");
+#endif
+
+  if (pfileInFile == NULL)
+  {
+    printf("error: can not open file %s\n", argv[2]);
+    exit(1);
+  }
+  if (pfileOutFile == NULL)
+  {
+    printf("error: can not open file %s\n", argv[3]);
+    exit(1);
+  }
+
+  puts("\n\n");
+  puts("   ****************************************");
+  puts("   *                                      *");
+  puts("   *      GSM Half-Rate Speech Coder      *");
+  puts("   *                                      *");
+  puts("   *                                      *");
+  printf("   *        %s            *\n", VERSION);
+  printf("   *        %s            *\n", DATE);
+  puts("   *                                      *");
+  puts("   ****************************************");
+  puts("\n");
+
+
+  printf("option:       ");
+
+  switch (option)
+  {
+    case 0:
+      puts("enc (speech encoder)");
+      break;
+    case 1:
+      puts("dec (speech decoder)");
+      break;
+    default:
+      puts("invalid option");
+      exit(1);
+  }
+
+  if (giDTXon)
+    printf("DTX mode:     enabled\n");
+  else
+    printf("DTX mode:     disabled\n");
+
+  printf("input file:   %s\n", argv[2]);
+  printf("output file:  %s\n\n", argv[3]);
+
+
+  switch (option)
+  {
+    case 0:                            /* encode */
+
+      /* start the encoder, VAD, and transmit DTX in the home state */
+      /* ---------------------------------------------------------- */
+
+      resetEnc();
+
+      /* encode:  analyze 8 kHz speech and output encoded parameter file */
+      /* --------------------------------------------------------------- */
+
+      for (giFrmCnt = 1, iDoneFrm = 0;
+           !iDoneFrm && giFrmCnt <= iMaxNumFrms;
+           giFrmCnt++)
+      {
+
+#ifndef SILENT
+        printf("encoding frame %d \r", giFrmCnt);
+#endif
+
+        if (encode(pfileInFile, pfileOutFile))
+          iDoneFrm = 1;
+      }
+
+      if (iDoneFrm)
+        giFrmCnt--;
+
+      printf(" %d speech frames encoded\n", giFrmCnt - 1);
+      break;
+
+    case 1:                            /* decode */
+
+      /* start the decoder and receive DTX in the home state */
+      /* --------------------------------------------------- */
+
+      resetDec();
+
+      /* decode:  synthesize speech */
+      /* -------------------------- */
+
+      for (giFrmCnt = 1, iDoneFrm = 0;
+           !iDoneFrm && giFrmCnt <= iMaxNumFrms;
+           giFrmCnt++)
+      {
+
+#ifndef SILENT
+        printf("decoding frame %d \r", giFrmCnt);
+#endif
+
+        if (decode(pfileInFile, pfileOutFile))
+          iDoneFrm = 1;
+      }
+
+      if (iDoneFrm)
+        giFrmCnt--;
+
+      printf(" %d speech frames decoded\n", giFrmCnt - 1);
+      break;
+  }
+
+  fclose(pfileInFile);
+  fclose(pfileOutFile);
+
+  return (0);
+}
+
+/**************************************************************************
+ *
+ *   FUNCTION NAME:  decode
+ *
+ *   PURPOSE:
+ *      Reads in one frame of speech parameters and outputs one frame of
+ *      synthesized speech.  Resets the decoder to the home state if the
+ *      Decoder Homing Frame pattern is detected.
+ *
+ *   INPUT:
+ *      pfileDec        speech parameter input file.
+ *
+ *   OUTPUT:
+ *      pfileSpeechOut  synthesized speech file
+ *
+ *   RETURN:
+ *      0               successfully synthesized a complete frame of speech
+ *      1               failed to synthesize a complete frame of speech
+ *
+ *   REFERENCES: Sub-clause 4.2 of GSM Recomendation 06.20
+ *
+ *   KEYWORDS:
+ *      pfileDec, pfileSpeechOut
+ **************************************************************************/
+
+int    decode(FILE *pfileDec, FILE *pfileSpeechOut)
+{
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Local Constants                              |
+ |_________________________________________________________________________|
+*/
+
+/* These constants define the number of consecutive */
+/* parameters that decoderHomingFrameTest checks.   */
+/* -------------------------------------------------*/
+
+#define  WHOLE_FRAME  18
+#define  TO_FIRST_SUBFRAME  9
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Static Variables                             |
+ |_________________________________________________________________________|
+*/
+  static Shortword pswSpeechPara[22],
+         pswDecodedSpeechFrame[F_LEN];
+
+  static int reset_flag_decoder_old = 1;
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Automatic Variables                          |
+ |_________________________________________________________________________|
+*/
+  int    i,
+         reset_flag_decoder;
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Executable Code                            |
+ |_________________________________________________________________________|
+*/
+
+  if (readDecfile(pfileDec, pswSpeechPara))
+    return (1);
+
+  if(reset_flag_decoder_old)
+    reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara,
+					      TO_FIRST_SUBFRAME);
+  else
+    reset_flag_decoder=0;
+
+  if (reset_flag_decoder && reset_flag_decoder_old)
+  {
+    /* force the output to be the encoder homing frame pattern */
+
+    for (i = 0; i < F_LEN; i++)
+      pswDecodedSpeechFrame[i] = EHF_MASK;
+  }
+  else
+  {
+    speechDecoder(pswSpeechPara, pswDecodedSpeechFrame);
+  }
+
+  speechDecoderHostInterface(pswDecodedSpeechFrame, pfileSpeechOut);
+
+  if(!reset_flag_decoder_old)
+    reset_flag_decoder=decoderHomingFrameTest(pswSpeechPara, WHOLE_FRAME);
+
+  if (reset_flag_decoder)
+    resetDec();                        /* bring the decoder and receive DTX
+                                        * to the home state */
+
+  reset_flag_decoder_old = reset_flag_decoder;
+
+  return (0);
+}
+
+/**************************************************************************
+ *
+ *   FUNCTION NAME:  encode
+ *
+ *   PURPOSE:
+ *      Reads in one frame of speech samples and outputs one frame of
+ *      speech parameters.  Resets the encoder to the home state if the
+ *      Encoder Homing Frame pattern is detected.
+ *
+ *   INPUT:
+ *      pfileSpeechIn   speech file
+ *
+ *   OUTPUT:
+ *      pfileEnc        speech, encoded paramater data
+ *
+ *   RETURN:
+ *      0                successfully wrote a complete frame of data
+ *      1                failed to write a complete frame of data
+ *
+ *   REFERENCES: Sub-clause 4.1 of GSM Recomendation 06.20
+ *
+ *   KEYWORDS:
+ *      pfileSpeechIn, pfileEnc
+ **************************************************************************/
+
+int    encode(FILE *pfileSpeechIn, FILE *pfileEnc)
+{
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Static Variables                             |
+ |_________________________________________________________________________|
+*/
+  static Shortword pswSpeechPara[20];
+  static Shortword pswSpeechBuff[F_LEN];
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                            Automatic Variables                          |
+ |_________________________________________________________________________|
+*/
+  int    iNumRead,
+         reset_flag;
+
+/*_________________________________________________________________________
+ |                                                                         |
+ |                              Executable Code                            |
+ |_________________________________________________________________________|
+*/
+
+  iNumRead = hostEncoderInterface(pfileSpeechIn, F_LEN, &pswSpeechBuff[0]);
+
+  if (iNumRead < F_LEN)
+    return (1);
+
+  reset_flag = encoderHomingFrameTest(&pswSpeechBuff[0]);
+
+  speechEncoder(&pswSpeechBuff[0], pswSpeechPara);
+
+  if (writeEncfile(pswSpeechPara, pfileEnc) != 20)
+    return (1);
+
+  if (reset_flag)
+    resetEnc();                        /* Bring the encoder, VAD, and DTX to
+                                        * the home state */
+
+  return (0);
+}