In Reply to: RE: optimised WASAPI exclusive event c++ code posted by SBGK on January 28, 2013 at 16:03:54:
right we have perfection, fantastic bass, midrange, detail, neutral sound, no digital noise etc, this is as good as it gets. Turns out the clean sound wasn't a keeper and I had a brainwave about how to further optimise the render loop which solved that issue.
I have updated the playerextreme.exe in the link in the above posts for anyone brave enough to try.
I find it outrageous that I have made such great improvements in removing digital noise from the sound and also ending up with the best sound I have heard in such little time, I guess you remove noise you get good sound.
It's just lazyness on the part of the player developers that they rely on the old methods, I guess they think bits are bits. It would be interesting to see if anyone could try it with ALSA etc, they all use the same methods, that's why they all sound the same. They actually introduce noise at the most critical part of loading the buffer and then we moan about digital noise. Well it doesn't need to be that way, listen to this basic player and then ask your player developer why their player sounds worse in comparison. It's not rocket science.
Anyway, the new idea I had was to move the getbuffer and load data step to after the buffer release. Traditionally there is a buffer event that says fill me, the code then does a getbuffer and a load and then a release. It is only the buffer release that makes the buffer available to play and we don't want a delay in making the buffer available, that delay causes the digital noise we all love. so by preloading the buffer before the loop I can get the release to happen immediately after the event, resulting in fantastic SQ, never heard such great bass and natural sound from my system. Also making the loop a while x > 0 and decrementing the counter at the end using --x helps (1 cpu tick). Does a while loop sound better than a for loop ? there's something to ponder. Also changing the time to INFINITE in the WaitForSingleObject(hNeedDataEvent, INFINITE); statement means we don't require an additional counter, although it's bad practice.
Will anyone adopt this method of rendering a stream ? I wonder, it would change the need for reclockers etc if they did.
does anyone know how to use waveformatextensible ? I need it to play 24 bit wavs.
BYTE *pData;
UINT32 nFramesThisPass = nFramesInBuffer;
UINT32 nBytesThisPass = nFramesThisPass * pWfx->nBlockAlign;
hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
hr = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);
// register with MMCSS
DWORD nTaskIndex = 0;
HANDLE hTask = AvSetMmThreadCharacteristics(L"Pro Audio", &nTaskIndex);
if (NULL == hTask) {
DWORD dwErr = GetLastError();
printf("AvSetMmThreadCharacteristics failed: last error = %u\n", dwErr);
pAudioRenderClient->Release();
CloseHandle(hNeedDataEvent);
pAudioClient->Release();
return HRESULT_FROM_WIN32(dwErr);
}
// call IAudioClient::Start
hr = pAudioClient->Start();
if (FAILED(hr)) {
printf("IAudioClient::Start failed: hr = 0x%08x", hr);
AvRevertMmThreadCharacteristics(hTask);
pAudioRenderClient->Release();
CloseHandle(hNeedDataEvent);
pAudioClient->Release();
}
// render loop
UINT32 nBuffersinFile = (nFramesInFile/nFramesInBuffer);
UINT32 nBuffersPlayed = nBuffersinFile;
printf("bufinfile %I64u nframfile %I64u nframbuff %I64u", nBuffersinFile,nFramesInFile,nFramesInBuffer );
while (nBuffersPlayed > 0)
{
WaitForSingleObject(hNeedDataEvent, INFINITE);
hr = pAudioRenderClient->ReleaseBuffer(nFramesInBuffer, 0); // no flags
hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
hr = mmioRead(hFile, (HPSTR)pData, nBytesThisPass);
--nBuffersPlayed;
} // render loop
hr = pAudioRenderClient->GetBuffer(nFramesInBuffer, &pData);
nFramesThisPass = nFramesInFile - nBuffersPlayed*nFramesInBuffer;
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);
http://mqnplayer.blogspot.co.uk/
This post is made possible by the generous support of people like you and our sponsors:
Follow Ups
- 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)