Home Computer Audio Asylum

Music servers and other computer based digital audio technologies.

A revolution in audio rendering

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:
  VH Audio  


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.