예제 #1
0
int PreCacheFrameOffsets(MFMADDecoder *pDecoder)
{
	MP3Header header;
	unsigned char headerBuffer[10];
	int sampleRate = 0;

	uint32 filePos = MFFile_Tell(pDecoder->pFile);
	while(MFFile_Read(pDecoder->pFile, headerBuffer, 4))
	{
		int validHeader = ReadMP3Header(&header, headerBuffer);
		sampleRate = header.samplerate;

		if(validHeader != 1)
		{
			if(pDecoder->frameCount >= pDecoder->numFrameOffsetsAllocated)
			{
				pDecoder->numFrameOffsetsAllocated *= 2;
				pDecoder->pFrameOffsets = (uint32*)MFHeap_Realloc(pDecoder->pFrameOffsets, sizeof(uint32) * pDecoder->numFrameOffsetsAllocated);
			}
			pDecoder->pFrameOffsets[pDecoder->frameOffsetCount++] = filePos;
			++pDecoder->frameCount;

			MFFile_Seek(pDecoder->pFile, header.frameSize-4, MFSeek_Current);
		}
		else
		{
			// check if we have some other header.. ID3?
			if(!MFString_CaseCmpN((char*)headerBuffer, "TAG", 3))
			{
				// read ID3 v1? ...

				// skip past it for now...
				MFFile_Seek(pDecoder->pFile, 128-4, MFSeek_Current);
			}
			else if(!MFString_CaseCmpN((char*)headerBuffer, "ID3", 3))
			{
				// ID3 v2...
				MFFile_Read(pDecoder->pFile, headerBuffer + 4, 6);
				uint32 size = GetSynchSafeInt(headerBuffer + 6);

				// skip ID3 v2 data
				MFFile_Seek(pDecoder->pFile, size, MFSeek_Current);
			}
			else
			{
				// lost sync? :/
				return 0;
			}
		}

		filePos = MFFile_Tell(pDecoder->pFile);
	}

	return sampleRate;
}
예제 #2
0
long ztell_file_func(voidpf opaque, voidpf stream)
{
	return MFFile_Tell((MFFile*)stream);
}
예제 #3
0
MF_API long MFFile_StdTell(void* fileHandle)
{
	return (long)MFFile_Tell((MFFile*)fileHandle);
}
예제 #4
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;
}