Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

wav to hex conversion on audio testing

Hi,

     I need some clarification on conversion from wav file format to hex file format.

  Aim: let me assume i have a wav file which contains the data for producing a sound(Ex: like click or beep sound). Anyways for producing any kind of  the sound i have to send the audio data(Hex format) to DAC through Mcbsp(i2s communication).So i need to convert the wav file to hex file format. I want to prepare a lookup table(hex file) after converting from wav file. 

 Doubt:

        1. Shall i use the wav to hex converter and directly use those hex values as samples for prducing the sound?. Is the audio data will be in correct format after the Covertion?

        2. Is there any other options for converting from wav to hex format.

Can Anyone of you give me some clarity on the same?

Thanks In Advance

K.Karthikeyan

 

 

 

  

 

  • wav-format files have a 'wav header', followed by audio data, and optionally (though not often) followed by some additional data about the file.

    The wav header identifies (amongst other things) the format of the audio data (e.g., PCM, AC3, etc.)

    Subject to the format of the audio data, the wav header provides additional information.

    For PCM data, for example, the wav header indicates how many channels are present per sample-instant and how the samples are formatted (e.g., 4-byte floating-point, 3-byte integer, 2-byte integer).

    Further, for PCM integer data, the wav header identifies how many bits of the integer are significant (e.g., only 20 bits of the 24 bits in a 3-byte integer).

    There's addtional header info for PCM.

    With this background, it's unclear to me what you are asking for.  Are you looking for something that canvert _any_ wav file to a hex file?  Wouldn't all the header information about how to interpret the data be lost? 

    Are you only interested in converting 16-bit PCM stereo wav files?

    Where is the format of 'hex file' specified?

  • Hi Frank,

    Thanks for the Response. 

    My task is to play the sound which is  stored in the wav file. So i have the wav file and tested path of Mcbsp to Dac which is connected with Head Phone. If i send the Any digital data to the DAC through the Mcbsp tx it will produce some kind of sound. So i need to take the digital data from the wav file for producing the sound which will be contained in the wav file. So for this work, what are steps i have to do?

    Thanks In Advance

    K.Karthikeyan

     

     

  • The idea is: 

    • open the file in binary mode
    • read enough from the file to determine that the file has a wave header
    • make sure that the wav header indicates that the content is PCM
    • from the wav header, determine how many channels are present, the number of bytes per channel, the number of bits per sample, the sample rate
    • determine where the data starts in the file and how many bytes (a wav file can also _end_ with some non-audio content, which you ought not play)
    • start reading the audio samples in a channel-interleaved manner (you may have to convert from file bits/sample to your dac's bits/sample)

    Here's a routine I use in a Windows application to do all but the last bullet.  Documentation on the mmIO functions are available on the Microsoft site.

    #include <windows.h>
    #include <stdio.h>
    #include <io.h>
    #include <FCNTL.H>
    #include "mmreg.h"

    /*
    **  The fmt chunk in a wave file can be a WAVEFORMAT, a WAVEFORMATEX, a PCMWAVEFORMAT, or
    **  a WAVEFORMATEXTENSIBLE.
    */
    typedef union t_wf
    {
     WAVEFORMAT wf;
     WAVEFORMATEX wfex;
     PCMWAVEFORMAT pwf;
     WAVEFORMATEXTENSIBLE wfext;
    } W_FORMAT;

    /*
    **  openWaveFile returns a file handle.  The value is INVALID_HANDLE_VALUE
    **  if unable to open, or if an error was encountered.
    */

    HANDLE openWaveFile( TX_FILE_CFG *pTx )
    {
     MMIOINFO      anMMIOINFO;
     HMMIO         aHMMIO;
     MMCKINFO      riffMMCKINFO;
     MMCKINFO      dataMMCKINFO;
     W_FORMAT      aFmtChunk;
     DWORD         formatChunkBytes = 0L;
      
     pTx->nFileDataBytes = 0L;
     pTx->hFile = CreateFile( pTx->pFileName,
                                 GENERIC_READ,
                                 0,
                                 NULL,
                                 OPEN_EXISTING,
                                 FILE_ATTRIBUTE_NORMAL,
                                 NULL );
     if( pTx->hFile == INVALID_HANDLE_VALUE )
     {
      DWORD dw;
      LPVOID lpMsgBuf;
      printf( "Unable to CreateFile( %s, ... ) for reading.\n", pTx->pFileName );
      FormatMessage(
       FORMAT_MESSAGE_ALLOCATE_BUFFER |
       FORMAT_MESSAGE_FROM_SYSTEM |
       FORMAT_MESSAGE_IGNORE_INSERTS,
       NULL,
       dw = GetLastError(),
       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
       (LPTSTR) &lpMsgBuf,
       0,
       NULL
      );
      printf( "%ld: %s\n", dw, lpMsgBuf );
      LocalFree( lpMsgBuf );
      return INVALID_HANDLE_VALUE;
     }
     /*
     **  See if it looks like a RIFF file containing WAVE info.  If it meets all of our
     **  requirements, set nFileDataBytes to the data byte count.
     **  Otherwise, nFileDataBytes remains 0.
     */
     memset( &anMMIOINFO, 0, sizeof( anMMIOINFO ));
     anMMIOINFO.adwInfo[0] = (DWORD) (pTx->hFile);
     
     aHMMIO = mmioOpen( NULL, &anMMIOINFO, MMIO_READ );
     if( aHMMIO )
     {
      /*
      **  NOT conclusive!  Drop into the RIFF parent chunk.
      */
      memset( &riffMMCKINFO, 0, sizeof( riffMMCKINFO ));
      if( MMSYSERR_NOERROR == mmioDescend( aHMMIO, &riffMMCKINFO, NULL, MMIO_FINDRIFF ) )
      {
       if( riffMMCKINFO.fccType == MAKEFOURCC( 'W', 'A', 'V', 'E' ))
       {
        /*
        **  Drop into the fmt chunk to get the wave info, then pop back out.
        */
        memset( &dataMMCKINFO, 0, sizeof( dataMMCKINFO ));
        dataMMCKINFO.ckid = MAKEFOURCC( 'f', 'm', 't', ' ' );
        if( MMSYSERR_NOERROR == mmioDescend( aHMMIO, &dataMMCKINFO, &riffMMCKINFO, MMIO_FINDCHUNK ))
        {
         /*
         **  Make sure that when we read the fmt chunk, we get at least the wFormatTag,
         **  and don't overflow our union.
         */
         if( ( dataMMCKINFO.cksize >= sizeof( aFmtChunk.wf.wFormatTag ) )
                            && ( dataMMCKINFO.cksize <= sizeof( aFmtChunk ) ) )
         {
          if( dataMMCKINFO.cksize == (unsigned) mmioRead( aHMMIO, (char *)&aFmtChunk, dataMMCKINFO.cksize ) )
          {
           if( theUserCfg.vBitMask & V_INITIALIZATION )
           {
            printf( "the format chunk's format tag is 0x%x\n", aFmtChunk.wf.wFormatTag );
           }
           switch( aFmtChunk.wf.wFormatTag )
           {
            case WAVE_FORMAT_PCM:
            if( theUserCfg.vBitMask & V_INITIALIZATION )
            {
             printf( "WAVE_FORMAT_PCM\n" );
            }
            if( dataMMCKINFO.cksize < sizeof( PCMWAVEFORMAT ))
            {
             printf( "format chunk size %ld but expecting %d for WAVE_FORMAT_PCM ???\n",
                  dataMMCKINFO.cksize, sizeof( PCMWAVEFORMAT ) );
            }
            break;
            
            case WAVE_FORMAT_EXTENSIBLE:
            /*
            **  We _could_ look at the SubFormat, but why?
            */
            if( dataMMCKINFO.cksize != sizeof( WAVEFORMATEXTENSIBLE ) )
            {
             printf( "format chunk size %ld but expecting %d for WAVE_FORMAT_EXTENSIBLE ???\n",
                  dataMMCKINFO.cksize, sizeof( WAVEFORMATEXTENSIBLE ) );
            }
            else
            {
             /*
             **  BUGBUG:  if there are multiple WAVE_FORMAT_EXTENSIBLE tx files,
             **  it's too complicated.  For the moment, assume we won't be asked to do this.
             */

             /*
             **  Save the channel mask, in case the output channels are specified
             **  in terms of speaker positions.
             */
             pTx->dwChannelMask = aFmtChunk.wfext.dwChannelMask;
             if( theUserCfg.vBitMask & V_INITIALIZATION )
             {
              printf( "dwChannelMask = 0x%x\n", pTx->dwChannelMask );
             }
            }
            break;

            default:
            printf( "Don't understand input wave file format type 0x%x !\n", aFmtChunk.wf.wFormatTag );
           }
           formatChunkBytes = dataMMCKINFO.cksize;
           mmioAscend( aHMMIO, &dataMMCKINFO, 0 );
           /*
           **  Descend into the data chunk to get the data byte count.
           **  This should also position the file pointer to the start of the data.
           */
           memset( &dataMMCKINFO, 0, sizeof( dataMMCKINFO ));
           dataMMCKINFO.ckid = MAKEFOURCC( 'd', 'a', 't', 'a' );
           if( MMSYSERR_NOERROR == mmioDescend( aHMMIO, &dataMMCKINFO, &riffMMCKINFO, MMIO_FINDCHUNK ))
           {
                                        pTx->nFileDataBytes = dataMMCKINFO.cksize;
            /*
            **  file pointer points to the data
            */
           }
           else
           {
            printf( "unable to descend into data chunk\n" );
           }
          }
          else
          {
           printf( "failed reading wave header fmt info\n" );
          }
         }
         else
         {
          printf( "size of fmt chunk data unexpected: %ld bytes\n", dataMMCKINFO.cksize );
         }
        }
        else
        {
         printf( "unable to descend into 'fmt' chunk\n" );
        }
       }
       else
       {
        char buffer[5];
        *(unsigned long *)&buffer[0] = riffMMCKINFO.fccType;
        buffer[4] = '\0';
        printf( "Error:  RIFF chunk fccType = %s\n", buffer );
       }
      }
      else
      {
       /*
       **  It could be a pcm file, so this might be OK.
       */
       if( theUserCfg.vBitMask & V_INITIALIZATION )
       {
        printf( "Unable to descend into RIFF chunk\n" );
       }
      }
      mmioClose( aHMMIO, MMIO_FHOPEN );
     }
     /*
     **  Does it look like a wave header?
     */
     if( pTx->nFileDataBytes )
     {
      DWORD fileSize;
      DWORD extraByteCount;
      /*
      **  Yes it does look like a wave file.  If the user hasn't
      **  overridden via command line, use the waveheader value.
      */
      if( pTx->nChannels )
      {
       if( pTx->nChannels != aFmtChunk.wf.nChannels )
       {
        printf( "Overriding TX file's %d channels as per command line %d channels\n",
          aFmtChunk.wf.nChannels,
          pTx->nChannels );
       }
      }
      else
      {
       pTx->nChannels  = aFmtChunk.wf.nChannels;
      }
      if( pTx->nBits )
      {
       if( pTx->nBits != aFmtChunk.pwf.wBitsPerSample )
       {
        printf( "Overriding TX file's %d bits/sample as per command line %d bits/sample\n",
             aFmtChunk.pwf.wBitsPerSample,
          pTx->nBits );
       }
      }
      else
      {
       pTx->nBits = aFmtChunk.pwf.wBitsPerSample;
      }
      pTx->sampleRate = aFmtChunk.wf.nSamplesPerSec;
      /*
      **  If the file has additional RIFF stuff in it, warn the user,
      **  so he won't attempt to make RX/TX comparisons.
      **  There's 20 bytes at the front of the file with RIFF and WAVE.
      **  There's also 8 bytes in the 'data' chunk that isn't data.
      */
      fileSize = GetFileSize( pTx->hFile, NULL );
      extraByteCount = fileSize - pTx->nFileDataBytes - formatChunkBytes - 28;
      if( extraByteCount > 0 )
      {
       printf( "File <%s> has %ld extra bytes in addition to WAV header\n",
            pTx->pFileName, extraByteCount );
      }
     }
     else
     { 
      /*
      **  rewind to the beginning of the file - it was data, not wave header
      */
      if( ((DWORD)-1) == SetFilePointer( pTx->hFile, 0L, NULL, FILE_BEGIN ))
      {
       printf( "\nUnable to rewind to beginning of PCM file!\n" );
       CloseHandle( pTx->hFile );
       return( pTx->hFile = INVALID_HANDLE_VALUE );
      }
      pTx->nFileDataBytes = GetFileSize( pTx->hFile, NULL );
      /*
      **  Use defaults if user hasn't specified via command line.
      */
      if( !pTx->nChannels ) 
      {
       pTx->nChannels = DEFAULT_TX_CHANNELS;
      }
      if( !pTx->nBits )
      {
       pTx->nBits = DEFAULT_TX_BITS_PER_SAMPLE;
      }
     }
     if( ( pTx->nChannels < 1 ) || ( pTx->nChannels > MAX_TX_FILE_CHANNELS ) )
     {
      printf( "nChannels = %d, illegal\n", pTx->nChannels );
      CloseHandle( pTx->hFile );
      return( pTx->hFile = INVALID_HANDLE_VALUE );
     }
     if( pTx->nBits < 16 || pTx->nBits > 24 )
     {
      printf( "nBits = %d, not supported.\n", pTx->nBits );
      CloseHandle( pTx->hFile );
      return( pTx->hFile = INVALID_HANDLE_VALUE );
     }
     if( theUserCfg.vBitMask & V_INITIALIZATION )
     {
      printf( "using output nChannels = %d\n", pTx->nChannels );
      printf( "using output nBits = %d\n", pTx->nBits );
      printf( "using sample rate = %d\n", pTx->sampleRate );
     }
     return pTx->hFile;
    }