Home Computer Audio Asylum

Music servers and other computer based digital audio technologies.

RE: optimised WASAPI exclusive event c++ code

here is the rendering loop with all the commented code in, the changes to the code path are to precalculate the no of buffers in the file and then loop until the last one which is processed out of loop, this saves numerous calculations running everytime the buffer fill event is triggered that were required to find out if we were at the end of the file. Needless to say the advantages to SQ are tremendous, if you're not getting the data right at this stage what chance is there of correcting things down the line. Now just need to get it working for other sample rates. I am pretty sure other players don't optimise the render loop to this extent and is one of the reasons they sound digital. pretty fundamental to get the code as efficient as possible, but not many c++ developers are interested in SQ.

// render loop

UINT32 nBuffersinFile = (nFramesInFile/nFramesInBuffer);
UINT32 nBuffersPlayed = 0;
UINT32 nFramesThisPass = nFramesInBuffer;
printf("bufinfile %I64u nframfile %I64u nframbuff %I64u", nBuffersinFile,nFramesInFile,nFramesInBuffer );
while (nBuffersPlayed < nBuffersinFile)
{
nFramesThisPass = nFramesInBuffer;

/* for (
UINT32 nFramesPlayed = 0,
nFramesThisPass = nFramesInBuffer;
nFramesPlayed < nFramesInFile;
nFramesPlayed += nFramesThisPass
) {*/


// in a production app there would be a timeout here
WaitForSingleObject(hNeedDataEvent, INFINITE);

// need data
hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
//if (FAILED(hr)) {
// //printf("IAudioRenderClient::GetBuffer failed: hr = 0x%08x\n", hr);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return hr;
//}

// is there a full buffer's worth of data left in the file?
//if (nFramesPlayed + nFramesInBuffer > nFramesInFile) {
// // nope - this is the last buffer
// nFramesThisPass = nFramesInFile - nFramesPlayed;
// UINT32 nBytesThisPass = nFramesThisPass * pWfx->nBlockAlign;

//LONG nBytesGotten = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);
//if (0 == nBytesGotten) {
// // printf("Unexpectedly reached the end of the file.\n");
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//} else if (-1 == nBytesGotten) {
// // printf("Error reading from the file.\n");
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//} else if (nBytesGotten != (LONG)nBytesThisPass) {
// // printf("mmioRead got %d bytes instead of %u\n", nBytesGotten, nBytesThisPass);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//}

// if there's leftover buffer space, zero it out
// it would be much better if we could intelligently fill this with silence
// ah well, c'est la vie
/* if (nFramesThisPass < nFramesInBuffer) {*/
/* UINT32 nBytesToZero = (nFramesInBuffer * pWfx->nBlockAlign) - nBytesThisPass;
ZeroMemory(pData + nBytesGotten, nBytesToZero);
*/ /*}*/

/*} else
{*/
UINT32 nBytesThisPass = nFramesThisPass * pWfx->nBlockAlign;
LONG nBytesGotten = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);



/*}*/
/* UINT32 nBytesThisPass = nFramesThisPass * pWfx->nBlockAlign;

LONG nBytesGotten = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);*/
//if (0 == nBytesGotten) {
// // printf("Unexpectedly reached the end of the file.\n");
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//} else if (-1 == nBytesGotten) {
// // printf("Error reading from the file.\n");
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//} else if (nBytesGotten != (LONG)nBytesThisPass) {
// // printf("mmioRead got %d bytes instead of %u\n", nBytesGotten, nBytesThisPass);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return E_UNEXPECTED;
//}

// if there's leftover buffer space, zero it out
// it would be much better if we could intelligently fill this with silence
// ah well, c'est la vie
/*if (nFramesThisPass < nFramesInBuffer) {
UINT32 nBytesToZero = (nFramesInBuffer * pWfx->nBlockAlign) - nBytesThisPass;
ZeroMemory(pData + nBytesGotten, nBytesToZero);
}*/

hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, 0); // no flags
//if (FAILED(hr)) {
// // printf("IAudioRenderClient::ReleaseBuffer failed: hr = 0x%08x\n", hr);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return hr;
//}
nBuffersPlayed += 1;
/*printf("bufplayed %I64u", nBuffersPlayed );*/

} // render loop

hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
nFramesThisPass = nFramesInFile - nBuffersPlayed*nFramesInBuffer;
UINT32 nBytesThisPass = nFramesThisPass * pWfx->nBlockAlign;

LONG nBytesGotten = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);

if (nFramesThisPass < nFramesInBuffer) {
UINT32 nBytesToZero = (nFramesInBuffer * pWfx->nBlockAlign) - nBytesThisPass;
ZeroMemory(pData + nBytesGotten, nBytesToZero);
}

hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, 0);



// add a buffer of silence for good measure
//WaitForSingleObject(hNeedDataEvent, INFINITE);
//hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
//if (FAILED(hr)) {
// // printf("IAudioRenderClient::GetBuffer failed trying to post-roll silence: hr = 0x%08x\n", hr);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return hr;
//}

//hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, AUDCLNT_BUFFERFLAGS_SILENT);
//if (FAILED(hr)) {
// // printf("IAudioRenderClient::ReleaseBuffer failed trying to post-roll silence: hr = 0x%08x\n", hr);
// pAudioClient->Stop();
// AvRevertMmThreadCharacteristics(hTask);
// pAudioRenderClient->Release();
// CloseHandle(hNeedDataEvent);
// pAudioClient->Release();
// return hr;
//}
http://mqnplayer.blogspot.co.uk/


This post is made possible by the generous support of people like you and our sponsors:
  McShane Design  


Follow Ups Full Thread
Follow Ups

FAQ

Post a Message!

Forgot Password?
Moniker (Username):
Password (Optional):
  Remember my Moniker & Password  (What's this?)    Eat Me
E-Mail (Optional):
Subject:
Message:   (Posts are subject to Content Rules)
Optional Link URL:
Optional Link Title:
Optional Image URL:
Upload Image:
E-mail Replies:  Automagically notify you when someone responds.