}\r
\r
// ------------------------------------------------------------------------------------------\r
-// Aligns v backwards\r
+// Aligns 'v' backwards\r
static UINT32 ALIGN_BWD(UINT32 v, UINT32 align)\r
{\r
return ((v - (align ? v % align : 0)));\r
}\r
\r
+// ------------------------------------------------------------------------------------------\r
+// Aligns 'v' forward\r
+static UINT32 ALIGN_FWD(UINT32 v, UINT32 align)\r
+{\r
+ UINT32 remainder = (align ? (v % align) : 0);\r
+ if (remainder == 0)\r
+ return v;\r
+ return v + (align - remainder);\r
+}\r
+\r
// ------------------------------------------------------------------------------------------\r
// Aligns WASAPI buffer to 128 byte packet boundary. HD Audio will fail to play if buffer\r
// is misaligned. This problem was solved in Windows 7 were AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED\r
// is thrown although we must align for Vista anyway.\r
static UINT32 AlignFramesPerBuffer(UINT32 nFrames, UINT32 nSamplesPerSec, UINT32 nBlockAlign)\r
{\r
-#define HDA_PACKET_SIZE 128\r
+#define HDA_PACKET_SIZE (128)\r
\r
- //long packets_total = 10000 * (nSamplesPerSec * nBlockAlign / HDA_PACKET_SIZE);\r
- long frame_bytes = nFrames * nBlockAlign;\r
+ long frame_bytes = nFrames * nBlockAlign;\r
long packets;\r
\r
// align to packet size\r
- frame_bytes = ALIGN_BWD(frame_bytes, HDA_PACKET_SIZE);\r
+ frame_bytes = ALIGN_FWD(frame_bytes, HDA_PACKET_SIZE); // use ALIGN_FWD if bigger but safer period is more desired\r
nFrames = frame_bytes / nBlockAlign;\r
packets = frame_bytes / HDA_PACKET_SIZE;\r
\r
- // align to packets count\r
- /*while (packets && ((packets_total % packets) != 0))\r
- {\r
- --packets;\r
- }*/\r
-\r
frame_bytes = packets * HDA_PACKET_SIZE;\r
nFrames = frame_bytes / nBlockAlign;\r
-\r
+ \r
return nFrames;\r
+\r
+#undef HDA_PACKET_SIZE\r
}\r
\r
// ------------------------------------------------------------------------------------------\r
}\r
\r
// Correct latency to default device period (in Exclusive mode this is 10ms) if user selected 0\r
- suggestedLatency = (params->suggestedLatency < 0.001 ? nano100ToSeconds(info->DefaultDevicePeriod) : params->suggestedLatency);\r
+ //suggestedLatency = (params->suggestedLatency < 0.001 ? nano100ToSeconds(info->DefaultDevicePeriod) : params->suggestedLatency);\r
+ suggestedLatency = params->suggestedLatency;\r
\r
// Add latency frames\r
framesPerLatency += MakeFramesFromHns(SecondsTonano100(suggestedLatency), pSubStream->wavex.Format.nSamplesPerSec);\r
\r
+ // Avoid 0 frames\r
+ if (framesPerLatency == 0)\r
+ framesPerLatency = MakeFramesFromHns(info->DefaultDevicePeriod, pSubStream->wavex.Format.nSamplesPerSec);\r
+\r
// Align frames to HD Audio packet size of 128 bytes for Exclusive mode only.\r
// Not aligning on Windows Vista will cause Event timeout, although Windows 7 will\r
// return AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED error to realign buffer. Aligning is necessary\r
stream->in.streamFlags = 0; // polling interface is implemented for full-duplex mode also\r
\r
// Create Audio client\r
- hr = CreateAudioClient(&stream->in, info, inputParameters, 0/*framesPerLatency*/,\r
+ hr = CreateAudioClient(&stream->in, info, inputParameters, framesPerBuffer/*framesPerLatency*/,\r
sampleRate, stream->in.streamFlags, (streamCallback == NULL), FALSE, &result);\r
if (hr != S_OK)\r
{\r
stream->out.streamFlags = 0; // polling interface is implemented for full-duplex mode also\r
\r
// Create Audio client\r
- hr = CreateAudioClient(&stream->out, info, outputParameters, 0/*framesPerLatency*/,\r
+ hr = CreateAudioClient(&stream->out, info, outputParameters, framesPerBuffer/*framesPerLatency*/,\r
sampleRate, stream->out.streamFlags, (streamCallback == NULL), TRUE, &result);\r
if (hr != S_OK)\r
{\r
// Exclusive/Shared non paWinWasapiPolling mode: paUtilFixedHostBufferSize - always fixed\r
// Exclusive/Shared paWinWasapiPolling mode: paUtilBoundedHostBufferSize - may vary\r
bufferMode = paUtilFixedHostBufferSize;\r
- if (inputParameters &&\r
- (!stream->in.streamFlags || ((stream->in.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) == 0)))\r
+ if (inputParameters /*&& // !!! WASAPI IAudioCaptureClient::GetBuffer extracts not number of frames but 1 packet, thus we always must adapt\r
+ (!stream->in.streamFlags || ((stream->in.streamFlags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) == 0))*/)\r
bufferMode = paUtilBoundedHostBufferSize;\r
else\r
if (outputParameters &&\r