LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

How to read 32 bits wave file with LabWindows/CVI?

Thanks!
0 Kudos
Message 1 of 4
(3,542 Views)
Hi,
 
You can use the Windows SDK to play 32-bits wave files. Take a look at the attached file.
 
Kind regards,
0 Kudos
Message 2 of 4
(3,517 Views)

Thank you Maxime.

I would like to get the data of the wave file such that I can perform the filtering, other calculations...

Any suggestions? Thanks.

0 Kudos
Message 3 of 4
(3,494 Views)

As seen in the Windows SDK help :

The first step in reading a wave file is to call the WaveOpenFile function. This gets a handle to the file, verifies that it is in RIFF format, and gets information about the wave format. The parameters are the filename and the addresses of three of the variables you have declared:

if (WaveOpenFile(lpzFileName, &hmmio, &pwfx, &mmckinfoParent) != 0)
{
    // Failure
}

Note that the wrapper functions all return zero if successful.

The next step is to call the WaveStartDataRead function, causing the file pointer to descend to the data chunk. This function also fills in the MMCKINFO structure for the data chunk, so that you know how much data is available:

if (WaveStartDataRead(&hmmio, &mmckinfoData, &mmckinfoParent) != 0)
    {
    // Failure
    }

The application can now begin copying data from the file to a secondary sound buffer. Normally you don't create the sound buffer until you have obtained the size of the data chunk and the format of the wave. The following code creates a static buffer just large enough to hold all the data in the file.

/* It is assumed that lpds in a valid pointer
   to the DirectSound object. */
 
LPDIRECTSOUNDBUFFER  lpdsbStatic;
DSBUFFERDESC         dsbdesc;
 
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); 
dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
dsbdesc.dwFlags = DSBCAPS_STATIC; 
dsbdesc.dwBufferBytes = mmckinfoData.cksize;  
dsbdesc.lpwfxFormat = pwfx; 
 
if FAILED(lpds->CreateSoundBuffer(&dsbdesc, &lpdsbStatic, NULL))
{
    WaveCloseReadFile(&hmmio, &pwfx);
    return FALSE; 
}

Because in this case the application is not streaming the data but simply filling a static buffer, the entire buffer is locked from the beginning. There is no wrap around, so only a single pointer and byte count are required.

LPVOID lpvAudio1;
DWORD  dwBytes1;
 
if FAILED(lpdsbStatic->Lock(
        0,              // Offset of lock start
        0,              // Size of lock; ignored in this case
        &lpvAudio1,     // Address of lock start
        &dwBytes1,      // Number of bytes locked
        NULL,           // Wrap around start; not used
        NULL,           // Wrap around size; not used
        DSBLOCK_ENTIREBUFFER))  // Flag
{
    // Error handling
    Close();
    .
    .
    .
}

The WaveReadFile function copies the data from the file to the buffer pointer and returns zero if successful.

UINT cbBytesRead;
 
if (WaveReadFile(
        hmmio,              // file handle
        dwBytes1,           // no. of bytes to read
        (BYTE *) lpvAudio1, // destination
        &mmckinfoData,      // file chunk info 
        &cbBytesRead))      // actual no. of bytes read
{
    // Handle failure on non-zero return
    WaveCloseReadFile(&hmmio, &pwfx);
    .
    .
    .
}

Finally, the application unlocks the buffer and closes the wave file:

lpdsbStatic->Unlock(lpvAudio1, dwBytes1, NULL, 0);
Close();

For a streaming buffer, you would typically call WaveReadFile at regular intervals determined by the current play position. If the locked portion of the buffer wrapped around, of course, you would call WaveReadFile once for each segment of the lock.

Kind regards,



Message Edité par Maxime MULLER le 11-08-2007 10:26 AM

Message Edité par Maxime MULLER le 11-08-2007 10:28 AM
0 Kudos
Message 4 of 4
(3,483 Views)