www.pudn.com > ETSI_ES_202_212_software.rar > fileio.c


/*===============================================================================
 *      ETSI ES 202 212   Distributed Speech Recognition
 *      Extended Advanced Front-End Feature Extraction Algorithm & Compression Algorithm
 *      Speech Reconstruction Algorithm.
 *      C-language software implementation                                      
 *      Version 1.1.1   October, 2003                                            
 *===============================================================================*/
/*--------------------------------------------------------------------------------
 *
 * FILE NAME: fileio.c
 * PURPOSE:   General purpose function package for DSR file I/O operations.
 *            Various input file formats (RAW, NIST, HTK) are supported.
 *            Output file format is always HTK. Package consists of functions
 *            for reading different file headers and input data and writing
 *            output HTK header and output data.
 *
 *-------------------------------------------------------------------------------*/

/*-----------------
 * File Inclusions
 *-----------------*/
#include 
#include 
#include 
#include "fileio.h"

/*---------------------------
 * Local Function Prototypes
 *---------------------------*/
int ParseHTKParmKind (int parmKind, char *outstr);

/*----------------------------------------------------------------------------
 * FUNCTION NAME: ReadNISTHeader
 *
 * PURPOSE:       Reads NIST header of an input file and stores header
 *                information in output data structure. Called by main
 *                function.
 *
 * INPUT:
 *   fp_in        Input waveform file handle
 *   header       Pointer to memory segment allocated for output data structure
 *
 * OUTPUT
 *                Header information stored in output data structure pointed
 *                to by *header*
 *
 * RETURN VALUE
 *   0            In case of any errors
 *   1            Otherwise
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
int 
ReadNISTHeader (FILE * fp_in, NIST_Header * header)
{
    char str[199], s1[30], s2[30], s3[30];

    fseek (fp_in, 0L, SEEK_SET);
    if (!fgets (str, sizeof (str), fp_in))
        return 0;               /* Empty file */

    str[sizeof (header->Type) - 1] = '\0';
    strcpy (header->Type, str);
    str[4] = '\0';
    if (strcmp (str, "NIST"))
        return 0;               /* No NIST stamp */

    if (!fgets (str, sizeof (str), fp_in))
        return 0;               /* Unexpected end of file */

    header->HeaderSize = atoi (str);

    while (fgets (str, sizeof (str), fp_in))
    {
        sscanf (str, "%s %s %s", s1, s2, s3);
        if (!strcmp (s1, "end_head"))
        {
            fseek (fp_in, (long) (header->HeaderSize), SEEK_SET);
            return 1;
        }
        else if (!strcmp (s1, "database_id"))
            strcpy (header->DatabaseID, s3);
        else if (!strcmp (s1, "database_version"))
            strcpy (header->DatabaseVersion, s3);
        else if (!strcmp (s1, "utterance_id"))
            strcpy (header->UtteranceID, s3);
        else if (!strcmp (s1, "channel_count"))
            header->ChannelCount = atoi (s3);
        else if (!strcmp (s1, "sample_count"))
            header->SampleCount = atol (s3);
        else if (!strcmp (s1, "sample_rate"))
            header->SampleRate = atol (s3);
        else if (!strcmp (s1, "sample_min"))
            header->SampleMin = atoi (s3);
        else if (!strcmp (s1, "sample_max"))
            header->SampleMax = atoi (s3);
        else if (!strcmp (s1, "sample_n_bytes"))
            header->SamplenBytes = atoi (s3);
        else if (!strcmp (s1, "sample_byte_format"))
            strcpy (header->SampleByteFormat, s3);
        else if (!strcmp (s1, "sample_sig_bits"))
            header->SampleSigBits = atoi (s3);
        else if (!strcmp (s1, "sample_coding"))
            strcpy (header->SampleCoding, s3);
        else if (!strcmp (s1, "sample_checksum"))
            header->SampleChecksum = atol (s3);
    }
    return 0;                   /* Incorrect header format */
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: ReadHTKHeader
 *
 * PURPOSE:       Reads HTK header of an input file and stores header
 *                information in output data structure. Called by main
 *                function.
 *
 * INPUT:
 *   fp_in        Input waveform file handle
 *   header       Pointer to memory segment allocated for output data structure
 *   swap         Nonzero if byte swapping is needed
 *
 * OUTPUT
 *                Header information stored in output data structure pointed
 *                to by *header*
 *
 * RETURN VALUE
 *   0            In case of any errors
 *   1            Otherwise
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
int 
ReadHTKHeader (FILE * fp_in, HTK_Header * header, int Swap )
{

    char str[20];

    fseek (fp_in, 0L, SEEK_SET);
    if (!fread (&(header->nSamples), sizeof (long), 1, fp_in))
          return 0;
    if (!fread (&(header->sampPeriod), sizeof (long), 1, fp_in))
          return 0;
    if (!fread (&(header->sampSize), sizeof (short), 1, fp_in))
          return 0;
    if (!fread (&(header->sampKind), sizeof (short), 1, fp_in))
          return 0;

    if ( Swap )
    {
        Swap32 (&(header->nSamples));
        Swap32 (&(header->sampPeriod));
        Swap16 (&(header->sampSize));
        Swap16 (&(header->sampKind));
    }
    
    if (header->nSamples < 0 || header->sampPeriod < 0 ||
        header->sampPeriod > 100000 || header->sampSize < 0 ||
        !ParseHTKParmKind (header->sampKind, str))
        return 0;
    else
        return 1;
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: WriteHTKHeader
 *
 * PURPOSE:       Writes HTK header stored in input data structure into an
 *                output file. Called by main function.
 *
 * INPUT:
 *   fp_out       Output feature file handle
 *   header       Pointer to HTK data structure
 *
 * OUTPUT
 *   none
 *
 * RETURN VALUE
 *   none
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
void 
WriteHTKHeader (FILE * fp_out, HTK_Header * header)
{
    fseek (fp_out, 0L, SEEK_SET);
    fwrite (&(header->nSamples), sizeof (long), 1, fp_out);
    fwrite (&(header->sampPeriod), sizeof (long), 1, fp_out);
    fwrite (&(header->sampSize), sizeof (short), 1, fp_out);
    fwrite (&(header->sampKind), sizeof (short), 1, fp_out);
    fseek (fp_out, 0L, SEEK_END);
}

/*---------------------------------------------------------------------------
 * FUNCTION NAME: WriteHTKFeature
 *
 * PURPOSE:       Writes one feature vector into output file.
 *                Called by main function.
 *
 * INPUT:
 *   fp_out       Output feature file handle
 *   out          Pointer to feature vector
 *   fea_len      Feature vector length
 *
 * OUTPUT
 *   none
 *
 * RETURN VALUE
 *   none
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
void 
WriteHTKFeature (FILE * fp_out, float *out, short fea_len)
{
    fwrite (out, sizeof (float), fea_len, fp_out);
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: ReadWave
 *
 * PURPOSE:       Reads waveform into memory
 *
 * INPUT:
 *   fp_in        Input waveform file handle
 *   CircBuff     Circular float buffer
 *   BSize        Buffer size
 *   BPointer     Buffer pointer
 *   nSamples     Number of samples to be read
 *   Swap         Nonzero if byte swapping is necessary
 *
 * OUTPUT
 *                Waveform stored in circular float buffer. Buffer pointer
 *                remains untouched (points to the first sample read)
 *
 * RETURN VALUE
 *   0            In case of any errors
 *   1            Otherwise
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
int
ReadWave (FILE *fp_in, float *CircBuff, int BSize, int BPointer, int nSamples, int Swap )
{
  short s;
  int i;

  for ( i=0; i> 8);
    CircBuff[BPointer]=(float)s;
    BPointer=(BPointer+1)%BSize;
    }
  return 1;
}



/*-----------------
 * Local Functions
 *-----------------*/

/*----------------------------------------------------------------------------
 * FUNCTION NAME: ParseHTKParmKind
 *
 * PURPOSE:       Parses HTK parameter kind integer and converts in to ASCII
 *                format.
 *
 * INPUT:
 *   parmKind     Input parameter kind integer from HTK header
 *   outstr       Pointer to ASCII buffer
 *
 * OUTPUT
 *                ASCII parameter kind stored in *outstr*
 *
 * RETURN VALUE
 *   0            If input parameter kind in incorrect
 *   1            Otherwise
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
int 
ParseHTKParmKind (int parmKind, char *outstr)
{
    int tmp;

    tmp = parmKind & 0x003f;    /* Basic Parameter Kind Codes */
    switch (tmp)
    {
    case 0:
        strcpy (outstr, "WAVEFORM");
        break;
    case 1:
        strcpy (outstr, "LPC");
        break;
    case 2:
        strcpy (outstr, "LPREFC");
        break;
    case 3:
        strcpy (outstr, "LPCEPSTRA");
        break;
    case 4:
        strcpy (outstr, "LPDELCEP");
        break;
    case 5:
        strcpy (outstr, "IREFC");
        break;
    case 6:
        strcpy (outstr, "MFCC");
        break;
    case 7:
        strcpy (outstr, "FBANK");
        break;
    case 8:
        strcpy (outstr, "MELSPEC");
        break;
    case 9:
        strcpy (outstr, "USER");
        break;
    case 10:
        strcpy (outstr, "DISCRETE");
        break;
    default:
        return 0;
    }
    tmp = parmKind & 0xffc0;    /* Bit-encoded Qualifiers */
    if (tmp & 000100)
        strcat (outstr, "_E");
    if (tmp & 000200)
        strcat (outstr, "_N");
    if (tmp & 000400)
        strcat (outstr, "_D");
    if (tmp & 001000)
        strcat (outstr, "_A");
    if (tmp & 002000)
        strcat (outstr, "_C");
    if (tmp & 004000)
        strcat (outstr, "_Z");
    if (tmp & 010000)
        strcat (outstr, "_K");
    if (tmp & 020000)
        strcat (outstr, "_0");
    return 1;
}

/*----------------------------------------------------------------------------
 * FUNCTION NAME: TextToParmKind
 *
 * PURPOSE:       Converts ASCII HTK parameter description to parameter kind
 *                integer to be written into HTK header
 *
 * INPUT:
 *   instr        Pointer to input parameter string
 *   parmKind     Pointer to output parameter kind integer
 *
 * OUTPUT
 *                Output parameter kind integer
 *
 * RETURN VALUE
 *   0            If input parameter string is incorrect
 *   1            Otherwise
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
int
TextToParmKind( char *instr, int *parmKind )
{
 char   workstr[40];
 int    idx;

 *parmKind=0;
 strcpy( workstr, instr );
 idx=strlen(workstr);

 while ( workstr[idx-2]=='_' )
   {
   workstr[idx]='\0';
   switch ( workstr[idx-1] )
     {
     case 'E' : *parmKind+=000100;
                break;
     case 'N' : *parmKind+=000200;
                break;
     case 'D' : *parmKind+=000400;
                break;
     case 'A' : *parmKind+=001000;
                break;
     case 'C' : *parmKind+=002000;
                break;
     case 'Z' : *parmKind+=004000;
                break;
     case 'K' : *parmKind+=010000;
                break;
     case '0' : *parmKind+=020000;
                break;
     default  : return 0;
     } 
   idx-=2;
   if ( idx<2 ) return 0;
   }
   workstr[idx]='\0';

   if ( !strcmp( workstr, "WAVEFORM" ) ) ;
   else if ( !strcmp( workstr, "LPC" ) ) *parmKind+=1;
   else if ( !strcmp( workstr, "LPREFC" ) ) *parmKind+=2;
   else if ( !strcmp( workstr, "LPCEPSTRA" ) ) *parmKind+=3;
   else if ( !strcmp( workstr, "LPDELCEP" ) ) *parmKind+=4;
   else if ( !strcmp( workstr, "IREFC" ) ) *parmKind+=5;
   else if ( !strcmp( workstr, "MFCC" ) ) *parmKind+=6;
   else if ( !strcmp( workstr, "FBANK" ) ) *parmKind+=7;
   else if ( !strcmp( workstr, "MELSPEC" ) ) *parmKind+=8;
   else if ( !strcmp( workstr, "USER" ) ) *parmKind+=9;
   else if ( !strcmp( workstr, "DISCRETE" ) ) *parmKind+=10;
   else return 0;

   return 1;
}


/*----------------------------------------------------------------------------
 * FUNCTION NAME: Swap16
 *
 * PURPOSE:       Swaps two bytes
 *
 * INPUT:
 *   Short        Pointer to input and output short variable
 *
 * OUTPUT
 *                Byte swapped short variable pointed by *Short*
 *
 * RETURN VALUE
 *   none
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
void Swap16 ( short *Short )
{
  *Short = ((*Short&0x0000ffL)<<8 )| \
           ((*Short&0x00ff00L)>>8 );
}


/*----------------------------------------------------------------------------
 * FUNCTION NAME: Swap32
 *
 * PURPOSE:       Reorders four bytes
 *
 * INPUT:
 *   Long         Pointer to input and output long variable
 *
 * OUTPUT
 *                Byte swapped long variable pointed by *Long*
 *
 * RETURN VALUE
 *   none
 *
 * Copyright (c) 1998 Nokia Research Center, Tampere, Finland
 *---------------------------------------------------------------------------*/
void Swap32 ( long* Long )
{
  *Long = ((*Long&0x000000ffL)<<24 )| \
          ((*Long&0x0000ff00L)<<8 )| \
          ((*Long&0x00ff0000L)>>8 )| \
          ((*Long&0xff000000L)>>24 );
}