Jump to content
  • Advertisement


This topic is now archived and is closed to further replies.


Sound doesn't play smoothly

This topic is 6025 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

Hello, I'm streaming an OGG vorbis file via DirectSound using the code provided in the tutorial. I'm decoding 4096 or less bytes of PCM data at a time, and writing to the DirectSound buffer. However the sound doesn't play smoothly and there is a crackling or subtle static sound the whole time while playing. Code is as follows:
void main()
	HANDLE hThread = NULL;

		cout << "Couldn't init DSound.\n";

		cout << "Couldn't set stream.\n";

	hThread = (HANDLE)_beginthread(Messages, 0, NULL );



BOOL InitDSound(HWND hwnd)
   // Create DirectSound

    if FAILED(DirectSoundCreate(NULL, &lpds, NULL)) 
        return FALSE;
    // Set co-op level

    if FAILED(IDirectSound_SetCooperativeLevel(lpds, hwnd,
        return FALSE;

	// Obtain primary buffer

    ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC));
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
    if FAILED(lpds->CreateSoundBuffer(&dsbdesc, &lpdsbPrimary, NULL))
        return FALSE;

	// Set primary buffer format

    memset(&wfx, 0, sizeof(WAVEFORMATEX)); 
    wfx.wFormatTag = WAVE_FORMAT_PCM; 
    wfx.nChannels = 2; 
    wfx.nSamplesPerSec = 44100; 
    wfx.wBitsPerSample = 16; 
    wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
    return TRUE;
}  // InitDSound()

BOOL SetupStreamBuffer()
    // Close any open file and release interfaces

	f = fopen("C:/a5/work/media/8_256.ogg", "rb");
	int eof=0;
	if(ov_open(f, &vf, NULL, 0))	
			return FALSE;

	if(!(vi = ov_info(&vf, -1)))
		return FALSE;

	pwfx = new WAVEFORMATEX;

	pwfx->wFormatTag      = WAVE_FORMAT_PCM; 
    pwfx->nChannels       = vi->channels; 
    pwfx->nSamplesPerSec  = vi->rate; 
    pwfx->wBitsPerSample  = vi->channels*8; 
    pwfx->nBlockAlign     = pwfx->wBitsPerSample / 8 * pwfx->nChannels;
    pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign;

	memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); 
    dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
    dsbdesc.dwFlags = 
            DSBCAPS_GETCURRENTPOSITION2   // Always a good idea

            | DSBCAPS_GLOBALFOCUS         // Allows background playing

            | DSBCAPS_CTRLPOSITIONNOTIFY; // Needed for notification

 // Set buffer size

	dsbdesc.dwBufferBytes = 4096;
	dsbdesc.lpwfxFormat = pwfx;
    if FAILED(IDirectSound_CreateSoundBuffer(lpds, &dsbdesc, &lpdsb,
        return FALSE; 

	for (int i = 0; i < NUMEVENTS; i++)
        rghEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
        if (NULL == rghEvent[i]) return FALSE;

	rgdsbpn[0].dwOffset = 0;
    rgdsbpn[0].hEventNotify = rghEvent[0];
    rgdsbpn[1].dwOffset = (dsbdesc.dwBufferBytes/2);
    rgdsbpn[1].hEventNotify = rghEvent[1];

	if FAILED(IDirectSoundBuffer_QueryInterface(lpdsb,
IID_IDirectSoundNotify, (VOID **)&lpdsNotify))
        return FALSE; 
    if FAILED(IDirectSoundNotify_SetNotificationPositions(lpdsNotify,
NUMEVENTS, rgdsbpn))
        return FALSE;

	IDirectSoundBuffer_Play(lpdsb, 0, 0, TRUE);

    return TRUE;
} // end of SetupStreamBuffer()

BOOL StreamToBuffer(DWORD dwPos)
    LONG            lNumToWrite;
    DWORD           dwStartOfs;
    VOID            *lpvPtr1, *lpvPtr2;
    DWORD           dwBytes1, dwBytes2;
    static DWORD    dwStopNextTime = 0xFFFF;
    if (dwStopNextTime == dwPos)   // All data has been played

        dwStopNextTime = 0xFFFF;
        return TRUE;
    if (dwStopNextTime != 0xFFFF)  // No more to stream, but keep

                                 // playing to end of data

        return TRUE;

	if (dwPos == 0)
        dwStartOfs = rgdsbpn[NUMEVENTS - 1].dwOffset;
        dwStartOfs = rgdsbpn[dwPos-1].dwOffset;

	lNumToWrite = (LONG) rgdsbpn[dwPos].dwOffset - dwStartOfs;
    if (lNumToWrite < 0) lNumToWrite += dsbdesc.dwBufferBytes;

                     dwStartOfs,       // Offset of lock start

                     lNumToWrite,      // Number of bytes to lock

                     &lpvPtr1,         // Address of lock start

                     &dwBytes1,        // Count of bytes locked

                     &lpvPtr2,         // Address of wrap around

                     &dwBytes2,        // Count of wrap around bytes


	cbBytesRead = ov_read(&vf,pcmout,4096,0,2,1,¤t_section);

	memcpy( lpvPtr1, pcmout, cbBytesRead);

	if (cbBytesRead ==0)        // Reached end of file

        FillMemory((PBYTE)lpvPtr1 + cbBytesRead,
                dwBytes1 - cbBytesRead, 
                (dsbdesc.lpwfxFormat->wBitsPerSample==8) ? 128 : 0);
        dwStopNextTime = dwPos;

	IDirectSoundBuffer_Unlock(lpdsb, lpvPtr1, cbBytesRead, lpvPtr2, dwBytes2);
    return TRUE;
} // end StreamToBuffer()

void Messages( void *dummy)
while (!Done)
    DWORD dwEvt = MsgWaitForMultipleObjects(
            NUMEVENTS,      // How many possible events

            rghEvent,       // Location of handles

            FALSE,          // Wait for all?

            INFINITE,       // How long to wait

            QS_ALLINPUT);   // Any message is an event

    // WAIT_OBJECT_0 == 0 but is properly treated as an arbitrary

    // index value assigned to the first event, therefore we subtract

    // it from dwEvt to get the zero-based index of the event.

    dwEvt -= WAIT_OBJECT_0;
    // If the event was set by the buffer, there's input

    // to process. 

    if (dwEvt < NUMEVENTS) 
        StreamToBuffer(dwEvt); // copy data to output stream

    // If it's the last event, it's a message 

    else if (dwEvt == NUMEVENTS) 
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
            if (msg.message == WM_QUIT) 
                Done = TRUE;
    }  // end message processing

} // while (!Done)


This is likely a problem in StreamToBuffer, but is it possible that the initial value of dsbdesc.dwBufferBytes is incorrect? Any help would be greatly appreciated! Thanks, -Anthony Edited by - frozentax on December 19, 2001 4:19:12 PM

Share this post

Link to post
Share on other sites
If the sound is crackeling does it mean that a buffer is being overwritten? I would increase the size of dsbdesc.dwBufferBytes to the suggested "pwfx->nAvgBytesPerSec * 2" but I can only decode so many bytes from the OGG file at a time - not nearly as much as "pwfx->nAvgBytesPerSec * 2", so this creates long pauses between small audio samples.

Share this post

Link to post
Share on other sites

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!