int MFInput_Thread(void *) { // poll input at high frequency... uint64 freq = MFSystem_GetRTCFrequency(); uint64 interval = freq / gInputFrequency; uint64 now = MFSystem_ReadRTC(); uint64 nextSample = now + interval; while(!bInputTerminate) { MFThread_LockMutex(gInputMutex); bThreadUpdate = true; MFInput_Update(); bThreadUpdate = false; // build events for(uint32 i=0; i<MFInput_MaxInputID; ++i) { if(!gDeviceStatus[IDD_Gamepad][i] == IDS_Ready) continue; for(uint32 j=0; j<GamepadType_Max; ++j) { if(gNumEvents[IDD_Gamepad][i] >= MaxEvents) break; MFGamepadState &state = gGamepadStates[i]; MFGamepadState &prev = gPrevGamepadStates[i]; if(state.values[j] == prev.values[j]) continue; MFInputEvent &e = gInputEvents[IDD_Gamepad][i][gNumEvents[IDD_Gamepad][i]++]; e.timestamp = now; e.event = MFIE_Change; e.input = j; e.state = state.values[j]; e.prevState = prev.values[j]; } } MFThread_ReleaseMutex(gInputMutex); // uint64 updateTime = MFSystem_ReadRTC(); // MFDebug_Log(0, MFStr("Input update: %dus", (uint32)((updateTime - now) * 1000000LL / MFSystem_GetRTCFrequency()))); uint32 ms = (uint32)((nextSample - now) * 1000LL / freq); MFThread_Sleep(ms); now = MFSystem_ReadRTC(); do nextSample += interval; while(now >= nextSample); } bInputTerminate = false; return 0; }
static int CaptureThread(void *_pData) { MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)_pData; const int NumSamples = 4096; float buffer[NumSamples]; while(1) { if(device.bActive) { while(device.bActive) { // get samples, and feed to callback UINT32 packetLength = 0; HRESULT hr = device.pCaptureClient->GetNextPacketSize(&packetLength); while(packetLength != 0) { // get the available data in the shared buffer. UINT32 numFramesAvailable; BYTE *pData; DWORD flags; UINT64 position, performanceCounter; hr = device.pCaptureClient->GetBuffer(&pData, &numFramesAvailable, &flags, &position, &performanceCounter); if(flags & AUDCLNT_BUFFERFLAGS_SILENT) pData = NULL; UINT32 numRemaining = numFramesAvailable; while(numRemaining) { UINT32 samplesToDeliver; float *pSamples; switch(device.format) { case MFWaveFmt_PCM_f32: pSamples = (float*)pData; samplesToDeliver = numRemaining; break; default: pSamples = buffer; samplesToDeliver = numRemaining; MFDebug_Assert(false, "TODO: Samples require conversion"); } // feed samples to the callback device.pSampleCallback(pSamples, samplesToDeliver, device.info.numChannels, device.pUserData); numRemaining -= samplesToDeliver; } hr = device.pCaptureClient->ReleaseBuffer(numFramesAvailable); hr = device.pCaptureClient->GetNextPacketSize(&packetLength); } MFThread_Sleep(5); } device.pAudioClient->Stop(); // Stop recording. } if(device.bTerminate) break; MFThread_Sleep(64); } return 0; }