Esempio n. 1
0
void MFSound_DeinitWASAPI()
{
	gpEnumerator->Release();
	gpNotification->Release();

	gDevices.Deinit();
	gCaptureDevices.Deinit();
}
Esempio n. 2
0
static void DestroyDevice(MFDevice *pDevice)
{
	AudioDevice *pDev = (AudioDevice*)pDevice->pInternal;
	if(pDev->pDevice)
		alcCloseDevice(pDev->pDevice);
	gDevices.Free(pDev);
}
Esempio n. 3
0
MFInitStatus MFHeap_InitModule()
{
	MFCALLSTACK;

	MFDebug_Assert(MFThread_GetMutexSizePlatformSpecific() <= sizeof(gMutexBuffer), "Mutex buffer too small!");
	MFThread_InitMutexPlatformSpecific((MFMutex)gMutexBuffer, "MFHeap alloc mutex");
	gAllocMutex = (MFMutex)gMutexBuffer;

	// any heap tracking allocations should be made in the debug space
	MFHeap *pOld = MFHeap_SetActiveHeap(MFHeap_GetDebugHeap());

#if defined(_USE_TRACKING_HASH_TABLE)
	// set up the memory tracking hash table
	// note: this is slightly complicated due to the chicken and egg nature
	// of making the first allocation for the pool its self ;)
	static const int numAllocHeaders = 1024;
//	uint32 bytes = (sizeof(MFHeap_AllocItem) + sizeof(void**)) * numAllocHeaders;
//	void *pPoolMemory = MFHeap_Alloc(bytes);
//	gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024, pPoolMemory, bytes);
	gAllocHeaderPool.Init(sizeof(MFHeap_AllocItem), numAllocHeaders, 1024);

	MFZeroMemory(gpAllocTable, sizeof(gpAllocTable));

	// artificially add an entry for the pool its self...
	MFHeap_AllocItem *pHeader = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc();
	pHeader->header.pHeap = &gExternalHeap;
	pHeader->header.size = bytes;
	pHeader->header.pFile = __FILE__;
	pHeader->header.line = (uint16)__LINE__;
	pHeader->header.alignment = 4;
	pHeader->pMemory = pPoolMemory;
	pHeader->pNext = NULL;
	gpAllocTable[MFUtil_HashPointer(pPoolMemory) % MFHeap_AllocTableLength] = pHeader;
#endif
#if defined(_USE_ALLOC_TRACKER)
	gAllocList.Init(sizeof(void*), 1024, 1024);
	gPoolInitialised = true;
#endif

	// restore the active heap
	MFHeap_SetActiveHeap(pOld);

	// init the heap
	MFHeap_InitModulePlatformSpecific();

	return MFAIC_Succeeded;
}
Esempio n. 4
0
MF_API void MFString_Dump()
{
	MFString temp = MFString_GetStats();

	MFDebug_Log(1, "\n-------------------------------------------------------------------------------------------------------");
	MFDebug_Log(1, temp.CStr());

	// dump all strings...
	MFDebug_Log(1, "");

	int numStrings = stringPool.GetNumAllocated();
	for(int a=0; a<numStrings; ++a)
	{
		MFStringData *pString = (MFStringData*)stringPool.GetItem(a);
		MFDebug_Log(1, MFStr("%d refs, " MFFMT_SIZE_T "b: \"%s\"", pString->refCount, pString->allocated, pString->pMemory));
	}
}
Esempio n. 5
0
MF_API MFStringData *MFStringData_Alloc()
{
	MFStringData *pData = (MFStringData*)stringPool.Alloc();
	pData->refCount = 1;
	pData->pMemory = NULL;
	pData->allocated = pData->bytes = 0;
	return pData;
}
Esempio n. 6
0
void MFString_DeinitModule()
{
	if(--gModuleInitCount == 0)
	{
		stringPool.Deinit();
		stringHeap.Deinit();
	}
}
Esempio n. 7
0
MF_API MFString MFString_GetStats()
{
	size_t overhead = stringPool.GetTotalMemory() + stringPool.GetOverheadMemory() + stringHeap.GetOverheadMemory();
	size_t waste = 0, averageSize = 0;

	// calculate waste
	int numStrings = stringPool.GetNumAllocated();
	for(int a=0; a<numStrings; ++a)
	{
		MFStringData *pString = (MFStringData*)stringPool.GetItem(a);
		size_t allocated = pString->allocated;
		if(allocated)
		{
			size_t bytes = pString->bytes+1;
			averageSize += bytes;
			waste += allocated - bytes;
		}
	}

	if(numStrings)
		averageSize /= numStrings;

	MFString desc;
    desc.Reserve(1024);
	desc = MFStr("String heap memory: " MFFMT_SIZE_T " allocated/" MFFMT_SIZE_T " reserved + " MFFMT_SIZE_T " overhead  Waste: " MFFMT_SIZE_T "  Average length: " MFFMT_SIZE_T "\n\tPool: %d/%d", stringHeap.GetAllocatedMemory(), stringHeap.GetTotalMemory(), overhead, waste, averageSize, stringPool.GetNumAllocated(), stringPool.GetNumReserved());

	int numGroups = stringHeap.GetNumPools();
	for(int a=0; a<numGroups; ++a)
	{
		MFObjectPool *pPool = stringHeap.GetPool(a);
		desc += MFStr("\n\t\t" MFFMT_SIZE_T " byte: %d/%d", pPool->GetObjectSize(), pPool->GetNumAllocated(), pPool->GetNumReserved());
	}

	return desc;
}
Esempio n. 8
0
void MFHeap_DeinitModule()
{
	MFCALLSTACK;

	MFHeap_DeinitModulePlatformSpecific();

#if defined(_USE_ALLOC_TRACKER)
	gPoolInitialised = false;
	gAllocList.Deinit();
#endif
#if defined(_USE_TRACKING_HASH_TABLE)
	// todo: list all unfreed allocations?
	//...

	gAllocHeaderPool.Deinit();
	MFZeroMemory(gpAllocTable, sizeof(gpAllocTable));
#endif

	// TODO: gAllocMutex is not allocated by MFHeap... separate the 'deinit' from the 'destroy'
//	MFThread_DestroyMutex(gAllocMutex);
}
Esempio n. 9
0
MF_API bool MFHeap_ValidateHeap()
{
#if defined(_USE_ALLOC_TRACKER)
	MFThread_LockMutex(gAllocMutex);

	if(gPoolInitialised)
	{
		int numAllocated = gAllocList.GetNumAllocated();
		for(int a=0; a<numAllocated; ++a)
		{
			void *pMem = *(void**)gAllocList.GetItem(a);
			if(!MFHeap_ValidateMemory(pMem))
			{
				MFDebug_Assert(false, "Corrupt memory allocation!");
				return false;
			}
		}
	}

	MFThread_ReleaseMutex(gAllocMutex);
#endif
	return true;
}
Esempio n. 10
0
static MFDevice *NewDevice(LPCWSTR pwstrDeviceId)
{
	MFDevice *pDev = NULL;
	IMMDevice *pDevice;
	gpEnumerator->GetDevice(pwstrDeviceId, &pDevice);
	if(pDevice)
	{
		// TODO: don't know if it's a capture device or not!
		if(1)
		{
			pDev = MFDevice_AllocDevice(MFDT_AudioRender, NULL);
			pDev->pInternal = gDevices.AllocAndZero();
			GetDeviceInfo(pDevice, pDev);
		}
		else
		{
			pDev = MFDevice_AllocDevice(MFDT_AudioCapture, NULL);
			pDev->pInternal = gCaptureDevices.AllocAndZero();
			GetDeviceInfo(pDevice, pDev);
		}
		pDevice->Release();
	}
	return pDev;
}
Esempio n. 11
0
MFInitStatus MFString_InitModule(int moduleId, bool bPerformInitialisation)
{
	if(!bPerformInitialisation)
		return MFIS_Succeeded;

	if(gModuleInitCount == 0)
	{
		++gModuleInitCount;

		stringHeap.Init(gStringGroups, sizeof(gStringGroups) / sizeof(gStringGroups[0]));
		stringPool.Init(sizeof(MFStringData), 128, 128);
	}

	return MFIS_Succeeded;
}
Esempio n. 12
0
MF_API void MFHeap_Free(void *pMem)
{
	MFCALLSTACK;

	if(!pMem)
	{
		MFDebug_Warn(3, "Attemptd to Free 'NULL' pointer.");
		return;
	}

	MFAllocHeader *pHeader = &((MFAllocHeader*)pMem)[-1];
	MFDebug_Assert(MFHeap_ValidateMemory(pMem), MFStr("Memory corruption detected!!\n%s(%d)", pHeader->pFile, pHeader->line));

	MFThread_LockMutex(gAllocMutex);

	MFHeap *pHeap = pHeader->pHeap;
	if(pHeap->heapType != MFHT_Debug)
	{
#if defined(_USE_TRACKING_HASH_TABLE)
		int hash = MFUtil_HashPointer(pMem) % MFHeap_AllocTableLength;
		MFHeap_AllocItem *pT = gpAllocTable[hash];
		if(pT)
		{
			if(pT->pMemory == pMem)
			{
				gpAllocTable[hash] = pT->pNext;
				gAllocHeaderPool.Free(pT);
			}
			else
			{
				while(pT->pNext && pT->pNext->pMemory != pMem)
					pT = pT->pNext;
				if(pT->pNext)
				{
					MFHeap_AllocItem *pTN = pT->pNext;
					pT->pNext = pTN->pNext;
					gAllocHeaderPool.Free(pTN);
				}
			}
		}
#endif
#if defined(_USE_ALLOC_TRACKER)
		if(gPoolInitialised)
		{
			int numAllocs = gAllocList.GetNumAllocated();

			for(int a=0; a<numAllocs; ++a)
			{
				void **ppAlloc = (void**)gAllocList.GetItem(a);
				if(*ppAlloc == pMem)
				{
					gAllocList.Free(ppAlloc);
					break;
				}
			}
		}
#endif
	}

#if !defined(_RETAIL)
	int pad = 0;
	while(pad < (int)sizeof(MFAllocHeader))
		pad += heapAlignment;
	size_t extra = pad + sizeof(MFAllocHeader) + MFHeap_MungwallBytes;

	pHeap->totalAllocated -= pHeader->size + extra;
	pHeap->totalWaste -= extra;
	--pHeap->allocCount;

//	MFDebug_Log(2, MFStr("Free: %08X, %d bytes - %s:(%d)", pMem, pHeader->size, pHeader->pFile, (int)pHeader->line));
#endif

	MFHeap *pAllocHeap = pHeader->pHeap;

	MFCopyMemory((char*)pMem + pHeader->size, "freefreefreefree", MFHeap_MungwallBytes);
	MFCopyMemory((char*)pMem - 8, "freefreefreefree", MFHeap_MungwallBytes);
	MFMemSet(pMem, 0xFE, pHeader->size);

	pAllocHeap->pCallbacks->pFree((char*)pMem - pHeader->alignment, pAllocHeap->pHeapData);

	MFThread_ReleaseMutex(gAllocMutex);
}
Esempio n. 13
0
MF_API void *MFHeap_AllocInternal(size_t bytes, MFHeap *pHeap)
{
	MFCALLSTACK;

	MFHeap *pAllocHeap = pOverrideHeap ? pOverrideHeap : (pHeap ? pHeap : pActiveHeap);

	int pad = 0;
	while(pad < (int)sizeof(MFAllocHeader))
		pad += heapAlignment;

	size_t allocExtra = pad + sizeof(MFAllocHeader) + MFHeap_MungwallBytes;
	size_t allocBytes = bytes + allocExtra;

	MFThread_LockMutex(gAllocMutex);

	char *pMemory = (char*)pAllocHeap->pCallbacks->pMalloc(allocBytes, pAllocHeap->pHeapData);

	MFDebug_Assert(pMemory, "Failed to allocate memory!");
	if(pMemory)
	{
		int alignment = (int)(MFALIGN(pMemory + sizeof(MFAllocHeader), heapAlignment) - (uintp)pMemory);

		pMemory += alignment;

		MFAllocHeader *pHeader = &((MFAllocHeader*)pMemory)[-1];

		pHeader->alignment = (uint16)alignment;
		pHeader->pHeap = pAllocHeap;
		pHeader->size = (uint32)bytes;
		pHeader->pFile = gpMFHeap_TrackerFile;
		pHeader->line = (uint16)gMFHeap_TrackerLine;
#if defined(USE_PRE_MUNGWALL)
		MFCopyMemory(pHeader->llawgnum, gLlawgnum, MFHeap_MungwallBytes);
#endif

		if(pAllocHeap->heapType != MFHT_Debug)
		{
#if defined(_USE_TRACKING_HASH_TABLE)
			MFHeap_AllocItem *pAlloc = (MFHeap_AllocItem*)gAllocHeaderPool.Alloc();
			pAlloc->header.alignment = (uint16)alignment;
			pAlloc->header.pHeap = pAllocHeap;
			pAlloc->header.size = (uint32)bytes;
			pAlloc->header.pFile = gpMFHeap_TrackerFile;
			pAlloc->header.line = (uint16)gMFHeap_TrackerLine;
			pAlloc->pMemory = pMemory;

			int hash = MFUtil_HashPointer(pMemory) % MFHeap_AllocTableLength;
			pAlloc->pNext = gpAllocTable[hash];
			gpAllocTable[hash] = pAlloc;
#endif
#if defined(_USE_ALLOC_TRACKER)
			if(gPoolInitialised)
				*(void**)gAllocList.Alloc() = pMemory;
#endif
		}

#if !defined(_RETAIL)
		MFCopyMemory(pMemory + bytes, gMungwall, MFHeap_MungwallBytes);

		pAllocHeap->totalAllocated += allocBytes;
		pAllocHeap->totalWaste += allocExtra;
		++pAllocHeap->allocCount;

//		MFDebug_Log(2, MFStr("Alloc: %08X(%08X), %d bytes - %s:(%d)", pMemory, pMemory - pHeader->alignment, bytes, gpMFHeap_TrackerFile, gMFHeap_TrackerLine));
#endif
	}

	MFThread_ReleaseMutex(gAllocMutex);

	return (void*)pMemory;
}
Esempio n. 14
0
void MFSound_InitModulePlatformSpecific(int *pSoundDataSize, int *pVoiceDataSize)
{
	MFCALLSTACK;

	gDevices.Init(sizeof(AudioDevice), 8, 8);

	ALCint minor, major;
	alcGetIntegerv(NULL, ALC_MAJOR_VERSION, 1, &major);
	alcGetIntegerv(NULL, ALC_MINOR_VERSION, 1, &minor);
	gAPIVersion = major*100 + minor;

	bool bCanEnumerate, bHasCapture;
	if(gAPIVersion >= 101)
	{
		bCanEnumerate = true;
		bHasCapture = true;
	}
	else
	{
		bCanEnumerate = alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE;
		bHasCapture = alcIsExtensionPresent(NULL, "ALC_EXT_CAPTURE") == AL_TRUE;
	}

	if(bCanEnumerate)
	{
		const char *pDevices = alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
		const char *pDefault = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
		while(pDevices && *pDevices)
		{
			bool bIsDefault = !MFString_Compare(pDevices, pDefault);
			MFDebug_Log(2, MFStr("OpenAL: found output device '%s'%s", pDevices, bIsDefault ? " (default)" : ""));

			MFDevice *pDevice = MFDevice_AllocDevice(MFDT_AudioRender, &DestroyDevice);
			pDevice->pInternal = gDevices.AllocAndZero();
			pDevice->state = MFDevState_Ready;

			AudioDevice &device = *(AudioDevice*)pDevice->pInternal;
			MFString_CopyN(pDevice->strings[MFDS_ID], pDevices, sizeof(pDevice->strings[MFDS_ID])-1);
			pDevice->strings[MFDS_ID][sizeof(pDevice->strings[MFDS_ID])-1] = 0;
			device.pDevice = NULL;

			if(bIsDefault)
					MFDevice_SetDefaultDevice(MFDT_AudioRender, MFDDT_All, pDevice);

			pDevices += MFString_Length(pDevices) + 1;
		}

		if(!MFDevice_GetDefaultDevice(MFDT_AudioRender, MFDDT_Default))
		{
			MFDebug_Warn(2, "OpenAL: No default output device?");

			// HACK: set it to the first one...
			MFDevice *pDevice = MFDevice_GetDeviceByIndex(MFDT_AudioRender, 0);
			MFDevice_SetDefaultDevice(MFDT_AudioRender, MFDDT_All, pDevice);
		}

		if(bHasCapture)
		{
			pDevices = alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER);
			pDefault = alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
			while(pDevices && *pDevices)
			{
				bool bIsDefault = !MFString_Compare(pDevices, pDefault);
				MFDebug_Log(2, MFStr("OpenAL: found capture device '%s'%s", pDevices, bIsDefault ? " (default)" : ""));

				MFDevice *pDevice = MFDevice_AllocDevice(MFDT_AudioCapture, &DestroyDevice);
				pDevice->pInternal = gDevices.AllocAndZero();
				pDevice->state = MFDevState_Ready;

				AudioDevice &device = *(AudioDevice*)pDevice->pInternal;
				MFString_CopyN(pDevice->strings[MFDS_ID], pDevices, sizeof(pDevice->strings[MFDS_ID])-1);
				pDevice->strings[MFDS_ID][sizeof(pDevice->strings[MFDS_ID])-1] = 0;
				device.pDevice = NULL;

				if(bIsDefault)
					MFDevice_SetDefaultDevice(MFDT_AudioCapture, MFDDT_All, pDevice);

				pDevices += MFString_Length(pDevices) + 1;
			}

			if(!MFDevice_GetDefaultDevice(MFDT_AudioCapture, MFDDT_Default))
				MFDebug_Warn(2, "OpenAL: No default capture device?");
		}
	}

	// create a context
	Context *pContext = CreateContext(MFDevice_GetDefaultDevice(MFDT_AudioRender, MFDDT_Default));
	MakeCurrent(pContext);

	// we need to return the size of the internal structures so the platform independant
	// code can make the correct allocations..
	*pSoundDataSize = sizeof(MFSoundDataInternal);
	*pVoiceDataSize = sizeof(MFVoiceDataInternal);
}
Esempio n. 15
0
void MFSound_InitWASAPI()
{
	gDevices.Init(sizeof(MFAudioDevice), 8, 8);
	gCaptureDevices.Init(sizeof(MFAudioCaptureDevice), 8, 8);

	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&gpEnumerator);
	if(FAILED(hr))
	{
		MFDebug_Assert(false, "Couldn't create multimedia device enumerator!");
		return;
	}

	// enumerate audio devices...
	gpNotification = new MFAudioDeviceNotification;
	gpEnumerator->RegisterEndpointNotificationCallback(gpNotification);

	// enumerate render devices
	IMMDeviceCollection *pDevices;
	gpEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices);
	if(pDevices)
	{
		UINT count;
		pDevices->GetCount(&count);

		for(UINT i=0; i<count; ++i)
		{
			IMMDevice *pDevice;
			pDevices->Item(i, &pDevice);

			MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioRender, NULL);
			pDev->pInternal = gDevices.AllocAndZero();
			MFAudioDevice &device = *(MFAudioDevice*)pDev->pInternal;

			GetDeviceInfo(pDevice, pDev);

			pDevice->Release();

			MFDebug_Log(0, MFStr("Found audio device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID]));
		}
		pDevices->Release();
	}

	// enumerate capture devices
	gpEnumerator->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE | DEVICE_STATE_UNPLUGGED, &pDevices);
	if(pDevices)
	{
		UINT count;
		pDevices->GetCount(&count);

		for(UINT i=0; i<count; ++i)
		{
			IMMDevice *pDevice;
			pDevices->Item(i, &pDevice);

			MFDevice *pDev = MFDevice_AllocDevice(MFDT_AudioCapture, NULL);
			pDev->pInternal = gCaptureDevices.AllocAndZero();
			MFAudioCaptureDevice &device = *(MFAudioCaptureDevice*)pDev->pInternal;

			GetDeviceInfo(pDevice, pDev);

			pDevice->Release();

			MFDebug_Log(0, MFStr("Found audio capture device: %s, %s - state: %d (%s)", pDev->strings[MFDS_DeviceName], pDev->strings[MFDS_Manufacturer], device.state, pDev->strings[MFDS_ID]));
		}
		pDevices->Release();
	}

	// set defaults (this is some awkward windows code!)
	for(int i=0; i<2; ++i)
	{
		for(int j=0; j<3; ++j)
		{
			IMMDevice *pDevice;
			gpEnumerator->GetDefaultAudioEndpoint(gDirection[i], gRole[j], &pDevice);
			if(pDevice)
			{
				wchar_t *pDefaultId;
				pDevice->GetId(&pDefaultId);
				char temp[128];
				MFString_CopyUTF16ToUTF8(temp, pDefaultId);
				MFDevice *pDev = MFDevice_GetDeviceById(temp);
				MFDevice_SetDefaultDevice(gDt[i], gDef[j], pDev);
				CoTaskMemFree(pDefaultId);
				pDevice->Release();
			}
		}
	}
}
Esempio n. 16
0
MF_API void MFStringData_Destroy(MFStringData *pStringData)
{
	if(pStringData->allocated)
		stringHeap.Free(pStringData->pMemory);
	stringPool.Free(pStringData);
}