In Reply to: optimised WASAPI exclusive event c++ code posted by SBGK on January 26, 2013 at 09:33:11:
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:
Follow Ups
- RE: optimised WASAPI exclusive event c++ code - SBGK 17:47:41 01/26/13 (76)
- RE: optimised WASAPI exclusive event c++ code - EmailTim 18:50:59 01/26/13 (75)
- RE: optimised WASAPI exclusive event c++ code - SBGK 21:50:39 01/26/13 (74)
- RE: optimised WASAPI exclusive event c++ code - SBGK 04:26:36 01/27/13 (73)
- RE: optimised WASAPI exclusive event c++ code - SBGK 16:03:54 01/28/13 (72)
- RE: optimised WASAPI exclusive event c++ code - phofman 04:08:37 02/08/13 (1)
- RE: optimised WASAPI exclusive event c++ code - SBGK 12:14:52 02/14/13 (0)
- A revolution in audio rendering - SBGK 15:42:42 01/29/13 (69)
- RE: A revolution in audio rendering - SBGK 00:31:47 02/08/13 (68)
- RE: A revolution in audio rendering - Tony Lauck 05:34:57 02/08/13 (67)
- RE: A revolution in audio rendering - SBGK 12:04:50 02/14/13 (3)
- RE: A revolution in audio rendering - Tony Lauck 12:23:37 02/14/13 (2)
- RE: A revolution in audio rendering - SBGK 10:08:19 02/15/13 (1)
- RE: A revolution in audio rendering - phofman 11:24:12 02/17/13 (0)
- RE: A revolution in audio rendering - jrling 03:47:36 02/09/13 (0)
- RE: A revolution in audio rendering - jrling 03:40:25 02/09/13 (58)
- RE: A revolution in audio rendering - SBGK 13:42:35 02/11/13 (57)
- RE: A revolution in audio rendering - jrling 14:11:55 02/11/13 (56)
- RE: A revolution in audio rendering - SBGK 16:12:40 02/11/13 (55)
- RE: A revolution in audio rendering - SBGK 16:15:16 02/11/13 (54)
- RE: A revolution in audio rendering - SBGK 09:42:35 02/12/13 (53)
- RE: A revolution in audio rendering - jrling 11:40:45 02/12/13 (52)
- RE: A revolution in audio rendering - SBGK 14:45:16 02/12/13 (51)
- RE: A revolution in audio rendering - jrling 14:26:37 02/14/13 (50)
- RE: A revolution in audio rendering - SBGK 09:56:41 02/15/13 (49)
- .NET v.4 - jrling 12:40:10 02/17/13 (48)
- RE: .NET v.4 - SBGK 13:02:41 02/17/13 (47)
- Linux Build? - jrling 14:08:43 02/17/13 (45)
- RE: Linux Build? - SBGK 15:19:46 02/17/13 (44)
- RE: Linux Build? - jrling 12:46:58 02/18/13 (43)
- RE: Linux Build? - SBGK 13:41:01 02/18/13 (42)
- RE: Linux Build? - SBGK 13:05:20 02/21/13 (41)
- RE: Linux Build? - SBGK 12:25:23 03/03/13 (40)
- RE: Linux Build? - SBGK 10:47:53 03/07/13 (30)
- RE: Linux Build? - SBGK 05:54:30 03/10/13 (29)
- RE: Linux Build? - SBGK 17:28:29 03/10/13 (28)
- RE: Linux Build? - SBGK 16:33:49 03/11/13 (27)
- RE: Linux Build? - SBGK 16:37:56 03/11/13 (26)
- RE: Linux Build? - SBGK 14:52:44 03/13/13 (25)
- RE: Linux Build? - SBGK 16:13:00 03/14/13 (24)
- RE: Linux Build? - SBGK 05:25:06 03/24/13 (23)
- RE: Linux Build? - SBGK 05:37:15 03/24/13 (22)
- Repost - jrling 10:56:32 03/24/13 (21)
- RE: Repost - SBGK 09:41:26 03/26/13 (19)
- RE: Repost - SBGK 11:03:40 03/26/13 (18)
- RE: Repost - SBGK 13:20:37 03/26/13 (17)
- RE: Repost - SBGK 00:15:21 03/28/13 (16)
- RE: Repost - jupabe 06:04:25 03/28/13 (15)
- RE: Repost - SBGK 06:29:24 03/30/13 (14)
- RE: Repost - jupabe 12:07:28 03/30/13 (13)
- RE: Repost - SBGK 23:01:20 04/01/13 (11)
- MQn v 14 / Flac play - SBGK 13:25:18 04/07/13 (10)
- RE: MQn v 14 / Flac play - SBGK 15:01:49 04/10/13 (9)
- RE: MQn v 14 / Flac play - SBGK 17:02:32 04/17/13 (8)
- RE: MQn v 14 / Flac play - SBGK 13:58:13 04/22/13 (7)
- RE: MQn v 14 / Flac play - SBGK 12:19:27 04/23/13 (6)
- MQn v 47 - SBGK 13:05:41 05/07/13 (5)
- RE: MQn v 47 - SBGK 13:35:05 05/21/13 (4)
- RE: MQn v 47 - SBGK 22:22:05 05/26/13 (3)
- RE: MQn v 79 - SBGK 12:13:39 05/28/13 (2)
- RE: MQn v 79 - jupabe 23:55:00 05/29/13 (1)
- RE: MQn v 80 - SBGK 15:14:03 05/30/13 (0)
- RE: Repost - SBGK 12:43:30 03/30/13 (0)
- RE: Repost - SBGK 16:10:11 03/25/13 (0)
- RE: Linux Build? - jupabe 02:59:45 03/04/13 (8)
- RE: Linux Build? - SBGK 13:16:39 03/04/13 (7)
- RE: Linux Build? - jupabe 13:59:00 03/04/13 (6)
- RE: Linux Build? - SBGK 14:46:51 03/04/13 (4)
- RE: Linux Build? - SBGK 15:04:44 03/04/13 (3)
- RE: Linux Build? - jupabe 23:19:08 03/04/13 (2)
- RE: Linux Build? - SBGK 00:24:41 03/05/13 (1)
- RE: Linux Build? - jupabe 06:40:43 03/05/13 (0)
- RE: Linux Build? - SBGK 14:22:01 03/04/13 (0)
- RE: .NET v.4 - jrling 13:59:29 02/17/13 (0)
- RE: A revolution in audio rendering - jrling 14:39:21 02/08/13 (2)
- RE: A revolution in audio rendering - bushpilot 17:31:07 02/17/13 (1)
- RE: A revolution in audio rendering - jrling 12:43:34 02/18/13 (0)