MF_API void MFInput_EnableBufferedInput(bool bEnable, int frequency) { gInputFrequency = frequency; if(!gInputThread) { for(int i=0; i<MFInput_MaxInputID; ++i) { gInputEvents[IDD_Gamepad][i] = (MFInputEvent*)MFHeap_Alloc(sizeof(MFInputEvent)*MaxEvents); gNumEvents[IDD_Gamepad][i] = 0; } gInputMutex = MFThread_CreateMutex("MFInput Mutex"); gInputThread = MFThread_CreateThread("MFInput Thread", &MFInput_Thread, NULL); } else { bInputTerminate = true; MFThread_Join(gInputThread); gInputThread = NULL; MFThread_DestroyMutex(gInputMutex); for(int i=0; i<MFInput_MaxInputID; ++i) { MFHeap_Free(gInputEvents[IDD_Gamepad][i]); } } }
MFFileSystemHandle MFFileSystem_RegisterFileSystem(const char *pFilesystemName, MFFileSystemCallbacks *pCallbacks) { MFDebug_Log(5, MFStr("Call: MFFileSystem_RegisterFileSystem(\"%s\")", pFilesystemName)); GET_MODULE_DATA(MFFileSystemState); for(uint32 a=0; a<gDefaults.filesys.maxFileSystems; a++) { if(pModuleData->ppFileSystemList[a] == NULL) { MFDebug_Assert(pCallbacks->Open, "No Open function supplied."); MFDebug_Assert(pCallbacks->Close, "No Close function supplied."); MFDebug_Assert(pCallbacks->Read, "No Read function supplied."); MFDebug_Assert(pCallbacks->Write, "No Write function supplied."); MFDebug_Assert(pCallbacks->Seek, "No Seek function supplied."); MFFileSystem *pFS = pModuleData->gFileSystems.Create(); MFZeroMemory(pFS, sizeof(MFFileSystem)); MFString_Copy(pFS->name, pFilesystemName); MFCopyMemory(&pFS->callbacks, pCallbacks, sizeof(MFFileSystemCallbacks)); pModuleData->ppFileSystemList[a] = pFS; #if defined(USE_JOB_THREAD) pFS->ppJobQueue = (MFJob**)MFHeap_Alloc(sizeof(MFJob*)*MAX_JOBS); pFS->jobs.Init(MFStr("%s Job List", pFilesystemName), MAX_JOBS+2); pFS->readJob = 0; pFS->writeJob = 0; pFS->numJobs = MAX_JOBS; pFS->semaphore = MFThread_CreateSemaphore("Filesystem Semaphore", MAX_JOBS, 0); pFS->thread = MFThread_CreateThread(MFStr("%s Thread", pFilesystemName), MKFileJobThread, pFS, MFPriority_AboveNormal); #endif if(pFS->callbacks.RegisterFS) pFS->callbacks.RegisterFS(); return a; } } MFDebug_Assert(false, MFStr("Exceeded maximum of %d Filesystems. Modify 'gDefaults.filesys.maxFileSystems'.", gDefaults.filesys.maxFileSystems)); return -1; }
MF_API bool MFSound_OpenCaptureDevice(MFDevice *pDevice) { MFDebug_Assert(pDevice->type == MFDT_AudioCapture, "Incorrect device type!"); MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)pDevice->pInternal; if(device.state == 1) { // get a handle to the device wchar_t id[256]; MFWString_CopyUTF8ToUTF16(id, pDevice->strings[MFDS_ID]); HRESULT hr = gpEnumerator->GetDevice(id, &device.pDevice); // activate the capture device hr = device.pDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&device.pAudioClient); // get format from input device WAVEFORMATEX *pwfx = NULL; hr = device.pAudioClient->GetMixFormat(&pwfx); device.format = MFWaveFmt_Unknown; device.info.sampleRate = pwfx->nSamplesPerSec; device.info.bitsPerSample = pwfx->wBitsPerSample; device.info.numChannels = pwfx->nChannels; device.info.channelMask = pwfx->nChannels == 1 ? MFSCM_FrontCenter : (MFSCM_FrontLeft | MFSCM_FrontRight); WORD wFormatTag = pwfx->wFormatTag; if(wFormatTag == WAVE_FORMAT_EXTENSIBLE) { WAVEFORMATEXTENSIBLE *pwfex = (WAVEFORMATEXTENSIBLE*)pwfx; device.info.channelMask = pwfex->dwChannelMask; if(pwfex->SubFormat == KSDATAFORMAT_SUBTYPE_PCM) wFormatTag = WAVE_FORMAT_PCM; else if(pwfex->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT) wFormatTag = WAVE_FORMAT_IEEE_FLOAT; } switch(wFormatTag) { case WAVE_FORMAT_PCM: { switch(pwfx->wBitsPerSample) { case 8: device.format = MFWaveFmt_PCM_u8; break; case 16: device.format = MFWaveFmt_PCM_s16; break; case 24: device.format = MFWaveFmt_PCM_s24; break; default: MFDebug_Assert(false, "Invalid wave format!"); } break; } case WAVE_FORMAT_IEEE_FLOAT: { MFDebug_Assert(pwfx->wBitsPerSample == 32, "Unknown float format!"); device.format = MFWaveFmt_PCM_f32; break; } default: MFDebug_Warn(2, "Unsupported wave format!"); break; } // initialise capture device REFERENCE_TIME hnsRequestedDuration = 10000000; hr = device.pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, hnsRequestedDuration, 0, pwfx, NULL); // get the size of the allocated buffer. UINT32 bufferFrameCount; hr = device.pAudioClient->GetBufferSize(&bufferFrameCount); device.info.bufferLength = bufferFrameCount; hr = device.pAudioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&device.pCaptureClient); // calculate the actual duration of the allocated buffer. device.info.bufferTime = (float)((double)bufferFrameCount / pwfx->nSamplesPerSec); // REFERENCE_TIME hnsActualDuration = (REFERENCE_TIME)((double)10000000 * bufferFrameCount / pwfx->nSamplesPerSec); device.bActive = false; device.thread = MFThread_CreateThread(pDevice->strings[MFDS_ID], CaptureThread, &device, MFPriority_AboveNormal, MFTF_Joinable); return true; } return false; }