Sign in to follow this  

WAV loop glitch

This topic is 4730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have this snippet of code which I followed a tutorial on to get working...however I am unable to understand why the writer of the tutorial failed to realise there is a slight pause when looping a WAV file using the code...and I am wondering if anyone else could possibly see if there is a way to stop this in the current code I have provided or post a possible better tutorial on loading and playing wav files...
WAVEFORMATEX wfex;
HWAVEOUT hwo;
char *lpfile;
int file_size;

#define OFFSET_FORMATTAG        20
#define OFFSET_CHANNELS         22
#define OFFSET_SAMPLESPERSEC    24
#define OFFSET_AVGBYTESPERSEC   28
#define OFFSET_BLOCKALIGN       32
#define OFFSET_BITSPERSAMPLE    34
#define OFFSET_WAVEDATA         44
#define HEADER_SIZE             OFFSET_WAVEDATA


bool LoadWave(LPSTR szFileName)
{
    FILE *f; // Handler to load the file into memory

    // Open and read the wave file
    f = fopen(szFileName, "rb");
    if(!f)
        // Error, file not found.
        return true;

    // Determine the file size
    fseek(f, 0, SEEK_END);
    file_size = ftell(f);
    // Rewind the pointer to the begginning so we can read it
    fseek(f, 0, SEEK_SET);

    // Allocate enough memory to store the entire file
    lpfile = new char [file_size];
    // 'Copy' the file to memory
    fread(lpfile, 1, file_size, f);
    // Close the file, we won't need it anymore
    fclose(f);

    wfex.wFormatTag      = *((WORD* )(lpfile + OFFSET_FORMATTAG     ));
    wfex.nChannels       = *((WORD* )(lpfile + OFFSET_CHANNELS      ));
    wfex.nSamplesPerSec  = *((DWORD*)(lpfile + OFFSET_SAMPLESPERSEC ));
    wfex.nAvgBytesPerSec = *((DWORD*)(lpfile + OFFSET_AVGBYTESPERSEC));
    wfex.nBlockAlign     = *((WORD* )(lpfile + OFFSET_BLOCKALIGN    ));
    wfex.wBitsPerSample  = *((WORD* )(lpfile + OFFSET_BITSPERSAMPLE ));

    return false;
}

void CALLBACK WaveOutProc(
	HWAVEOUT hwo, 
	UINT uMsg, 
	DWORD dwInstance, 
	DWORD dwParam1, 
	DWORD dwParam2)
{
    switch(uMsg)
    {
    case WOM_OPEN:
        break;
	case WOM_DONE:
	{
		WAVEHDR *whdr = (WAVEHDR*)dwParam1;  // Only to keep the clarity of the code
		if(whdr->dwUser)
			waveOutWrite(hwo, whdr, sizeof(WAVEHDR));
		else
		{
			waveOutUnprepareHeader(hwo, whdr, sizeof(WAVEHDR));
			delete whdr;
		}
	}
	break;
    case WOM_CLOSE:
        break;
    }
}

WAVEHDR* PlayWave(bool loop)
{
    WAVEHDR *whdr = new WAVEHDR;
    ZeroMemory((void*)whdr, sizeof(WAVEHDR));

    whdr->lpData = lpfile+HEADER_SIZE;
    whdr->dwBufferLength = file_size-HEADER_SIZE;
    whdr->dwUser = (DWORD)loop;

    // Find a waveOut device and open it
    for(UINT devid = 0; devid < waveOutGetNumDevs(); devid++)
    {
        if(devid == waveOutGetNumDevs())
            // Error, no free devices found
            return NULL;
        if(waveOutOpen(&hwo, WAVE_MAPPER, &wfex, (DWORD)WaveOutProc, 0, CALLBACK_FUNCTION)
	   == MMSYSERR_NOERROR)
            // Usable device found, stop searching
            break;
    }

    if(waveOutPrepareHeader(hwo, whdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
        return NULL;
    if(waveOutWrite(hwo, whdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
        return NULL;

    // Return the pointer to the WAVEHDR we used here
    return whdr;
}

void StopWave(WAVEHDR *whdr)
{
    if(whdr)
        whdr->dwUser = (DWORD)false;
} 

void CloseWave()
{
    waveOutClose(hwo);
    delete [] lpfile;
} 

Thanks!

Share this post


Link to post
Share on other sites
Well, the thing that will determine how long your gap is is the time that it takes to receive and service WOM_DONE. Are you loading your system really hard, are you doing sound on a low priority thread, and have you checked to make sure that your wav file itself isn't the source of the pause?

-fel

Share this post


Link to post
Share on other sites

This topic is 4730 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this