Beispiel #1
0
MF_API MFFile* MFFile_CreateMemoryFile(const void *pMemory, size_t size, bool writable, bool ownMemory)
{
	MFOpenDataMemory memory;
	memory.cbSize = sizeof(MFOpenDataMemory);
	memory.openFlags = MFOF_Read|MFOF_Binary|(writable ? MFOF_Write : 0);
	memory.pMemoryPointer = (void*)pMemory;
	memory.fileSize = size;
	memory.allocated = size;
	memory.ownsMemory = false;

	return MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_MemoryFileSystem), &memory);
}
MFFile* MFFileSystemZipFile_Open(MFMount *pMount, const char *pFilename, uint32 openFlags)
{
	MFCALLSTACK;

	MFFile *hFile = NULL;

	// recurse toc
	MFTOCEntry *pTOCEntry = MFFileSystem_GetTocEntry(pFilename, pMount->pEntries, pMount->numFiles);

	if(pTOCEntry)
	{
		MFOpenDataZipFile openData;

		openData.cbSize = sizeof(MFOpenDataZipFile);
		openData.openFlags = openFlags | MFOF_Zip_AlreadyMounted;
		openData.pZipArchive = (MFFile*)pMount->pFilesysData;
		openData.pFilename = MFStr("%s%s", pTOCEntry->pFilesysData ? (char*)pTOCEntry->pFilesysData : "", pTOCEntry->pName);

		hFile = MFFile_Open(hZipFileSystem, &openData);
	}

	return hFile;
}
Beispiel #3
0
void MFFileSystem_RegisterDefaultArchives(void *)
{
	GET_MODULE_DATA(MFFileSystemState);

	MFFile *&hDataArchive = pModuleData->hDataArchive;
	MFFile *&hPatchArchive = pModuleData->hPatchArchive;

	// try and mount the 'standard' archives...
	// TODO: ponder removing this code and forcing the use of a filesystem init callback? :/
	MFOpenDataNative dataArchive;
	dataArchive.cbSize = sizeof(MFOpenDataNative);
	dataArchive.openFlags = MFOF_Read|MFOF_Binary;
	hDataArchive = 0;
	const char **pArc = gArchiveNames;
	while(!hDataArchive && *pArc)
	{
		dataArchive.pFilename =  MFFile_SystemPath(MFStr(*pArc, MFSystem_GetPlatformString(MFSystem_GetCurrentPlatform())));
		hDataArchive = MFFile_Open(pModuleData->hNativeFileSystem, &dataArchive);
		++pArc;
	}

	MFMountDataNative mountData;
	mountData.cbSize = sizeof(MFMountDataNative);
	mountData.priority = MFMP_Normal;

	if(hDataArchive)
	{
		// attempt to cache the zip archive
		MFOpenDataCachedFile cachedOpen;
		cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
		cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
		cachedOpen.maxCacheSize = 1*1024*1024; // 1mb cache for zip archives should be heaps!!
		cachedOpen.pBaseFile = hDataArchive;

		MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
		if(pCachedFile)
			hDataArchive = pCachedFile;

		// mount the zip archive.
		MFMountDataZipFile zipMountData;
		zipMountData.cbSize = sizeof(MFMountDataZipFile);
		zipMountData.flags = MFMF_Recursive|MFMF_FlattenDirectoryStructure;
		zipMountData.priority = MFMP_Normal;
		zipMountData.pMountpoint = "data";
		zipMountData.pZipArchive = hDataArchive;
		MFFileSystem_Mount(pModuleData->hZipFileSystem, &zipMountData);
	}

	mountData.flags = MFMF_DontCacheTOC;
	mountData.pMountpoint = "home";
	mountData.pPath = MFFile_HomePath();
	MFFileSystem_Mount(pModuleData->hNativeFileSystem, &mountData);

	// see if we can mount the patch archive..
	hPatchArchive = 0;
	pArc = gPatchArchiveNames;
	while(!hPatchArchive && *pArc)
	{
		dataArchive.pFilename =  MFFile_SystemPath(MFStr(*pArc, MFSystem_GetPlatformString(MFSystem_GetCurrentPlatform())));
		hDataArchive = MFFile_Open(pModuleData->hNativeFileSystem, &dataArchive);
		++pArc;
	}

	if(hPatchArchive)
	{
		// attempt to cache the zip archive
		MFOpenDataCachedFile cachedOpen;
		cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
		cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
		cachedOpen.maxCacheSize = 1*1024*1024; // 1mb cache for zip archives should be heaps!!
		cachedOpen.pBaseFile = hPatchArchive;

		MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
		if(pCachedFile)
			hPatchArchive = pCachedFile;

		// mount the zip archive.
		MFMountDataZipFile zipMountData;
		zipMountData.cbSize = sizeof(MFMountDataZipFile);
		zipMountData.flags = MFMF_Recursive|MFMF_FlattenDirectoryStructure;
		zipMountData.priority = MFMP_VeryHigh;
		zipMountData.pMountpoint = "patch";
		zipMountData.pZipArchive = hPatchArchive;
		MFFileSystem_Mount(pModuleData->hZipFileSystem, &zipMountData);
	}

	if(pModuleData->hHTTPFileSystem != -1)
	{
		// register the network filesystems
		MFMountDataHTTP mountDataHTTP;
		mountDataHTTP.cbSize = sizeof(MFMountDataHTTP);
		mountDataHTTP.pMountpoint = "http";
		mountDataHTTP.priority = MFMP_Normal + 1;
		mountDataHTTP.flags = MFMF_OnlyAllowExclusiveAccess;
		MFFileSystem_Mount(pModuleData->hHTTPFileSystem, &mountDataHTTP);
	}
}
Beispiel #4
0
void CreateVorbisStream(MFAudioStream *pStream, const char *pFilename)
{
	MFCALLSTACK;

	MFVorbisStream *pVS = (MFVorbisStream*)MFHeap_Alloc(sizeof(MFVorbisStream));
	pStream->pStreamData = pVS;

	// open vorbis file
	MFFile* hFile = MFFileSystem_Open(pFilename);
	if(!hFile)
		return;

	// attempt to cache the vorbis stream
	MFOpenDataCachedFile cachedOpen;
	cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
	cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
	cachedOpen.maxCacheSize = 256*1024; // 256k cache for vorbis stream should be heaps!!
	cachedOpen.pBaseFile = hFile;

	MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
	if(pCachedFile)
		hFile = pCachedFile;

	// setup vorbis read callbacks
	ov_callbacks callbacks;
	callbacks.read_func = MFFile_StdRead;
	callbacks.seek_func = MFSound_VorbisSeek;
	callbacks.close_func = MFFile_StdClose;
	callbacks.tell_func = MFFile_StdTell;

	// open vorbis file
	if(ov_test_callbacks(hFile, &pVS->vorbisFile, NULL, 0, callbacks))
	{
		MFDebug_Assert(false, "Not a vorbis file.");
		MFHeap_Free(pVS);
		return;
	}

	ov_test_open(&pVS->vorbisFile);

	// get vorbis file info
	pVS->pInfo = ov_info(&pVS->vorbisFile, -1);

#if defined(VORBIS_TREMOR)
//	pStream->trackLength = (float)ov_pcm_total(&pVS->vorbisFile, -1) / (float)pVS->pInfo->rate;
	pStream->trackLength = 1000.0f;
#else
	pStream->trackLength = (float)ov_time_total(&pVS->vorbisFile, -1);
#endif

	// fill out the stream info
	pStream->streamInfo.sampleRate = pVS->pInfo->rate;
	pStream->streamInfo.channels = pVS->pInfo->channels;
	pStream->streamInfo.bitsPerSample = 16;
	pStream->streamInfo.bufferLength = pVS->pInfo->rate;

	// read the vorbis comment data
	pVS->pComment = ov_comment(&pVS->vorbisFile, -1);
	if(pVS->pComment)
	{
		const char *pTitle = vorbis_comment_query(pVS->pComment, "TITLE", 0);
		const char *pArtist = vorbis_comment_query(pVS->pComment, "ALBUM", 0);
		const char *pAlbum = vorbis_comment_query(pVS->pComment, "ARTIST", 0);
		const char *pGenre = vorbis_comment_query(pVS->pComment, "GENRE", 0);

		if(pTitle)
			MFString_CopyN(pStream->streamInfo.songName, pTitle, sizeof(pStream->streamInfo.songName)-1);
		if(pArtist)
			MFString_CopyN(pStream->streamInfo.artistName, pArtist, sizeof(pStream->streamInfo.artistName)-1);
		if(pAlbum)
			MFString_CopyN(pStream->streamInfo.albumName, pAlbum, sizeof(pStream->streamInfo.albumName)-1);
		if(pGenre)
			MFString_CopyN(pStream->streamInfo.genre, pGenre, sizeof(pStream->streamInfo.genre)-1);
	}
}
Beispiel #5
0
void CreateWAVStream(MFAudioStream *pStream, const char *pFilename)
{
	MFCALLSTACK;

	// open wav file
	MFFile* hFile = MFFileSystem_Open(pFilename);
	if(!hFile)
		return;

	// attempt to cache the vorbis stream
	MFOpenDataCachedFile cachedOpen;
	cachedOpen.cbSize = sizeof(MFOpenDataCachedFile);
	cachedOpen.openFlags = MFOF_Read | MFOF_Binary | MFOF_Cached_CleanupBaseFile;
	cachedOpen.maxCacheSize = 256*1024; // 256k cache for wav stream should be heaps!!
	cachedOpen.pBaseFile = hFile;

	MFFile *pCachedFile = MFFile_Open(MFFileSystem_GetInternalFileSystemHandle(MFFSH_CachedFileSystem), &cachedOpen);
	if(pCachedFile)
		hFile = pCachedFile;

	RIFFHeader header;
	MFFile_Read(hFile, &header, sizeof(header));

	if(header.RIFF != MFMAKEFOURCC('R', 'I', 'F', 'F') || header.WAVE != MFMAKEFOURCC('W', 'A', 'V', 'E'))
		return;	// not a .wav file...

	// if everything's good, and it appears to be a valid wav file
	MFWAVStream *pWS = (MFWAVStream*)MFHeap_AllocAndZero(sizeof(MFWAVStream));
	pStream->pStreamData = pWS;
	pWS->pStream = hFile;

	size_t read;
	size_t fptr = sizeof(header);
	do
	{
		MFFile_Seek(hFile, fptr, MFSeek_Begin);

		WAVChunk dataChunk;
		MFZeroMemory(&dataChunk, sizeof(dataChunk));
		read = MFFile_Read(hFile, &dataChunk, sizeof(dataChunk));
		fptr += sizeof(dataChunk) + dataChunk.size;

		if(dataChunk.id == MFMAKEFOURCC('f', 'm', 't', ' '))
		{
			read = MFFile_Read(hFile, &pWS->format, dataChunk.size);
			if(pWS->format.cbSize)
				read = (size_t)MFFile_Seek(hFile, pWS->format.cbSize, MFSeek_Current);
		}
		else if(dataChunk.id == MFMAKEFOURCC('d', 'a', 't', 'a'))
		{
			pWS->dataOffset = (size_t)MFFile_Tell(hFile);
			pWS->dataSize = dataChunk.size;
		}
	}
	while(read);

	// return to the start of the audio data
	MFFile_Seek(pWS->pStream, (int)pWS->dataOffset, MFSeek_Begin);

	// calculate the track length
	pWS->sampleSize = (pWS->format.nChannels * pWS->format.wBitsPerSample) >> 3;
	pStream->trackLength = (float)(pWS->dataSize / pWS->sampleSize) / (float)pWS->format.nSamplesPerSec;

	// fill out the stream info
	pStream->streamInfo.sampleRate = pWS->format.nSamplesPerSec;
	pStream->streamInfo.channels = pWS->format.nChannels;
	pStream->streamInfo.bitsPerSample = pWS->format.wBitsPerSample;
	pStream->streamInfo.bufferLength = pWS->format.nSamplesPerSec;
}