Esempio n. 1
0
MF_API void MFIntSound_CreateRuntimeData(MFIntSound *pSound, void **ppOutput, size_t *pSize, MFPlatform platform)
{
	*ppOutput = NULL;

	MFAudioStream *pStream = (MFAudioStream*)pSound->pInternal;

	// decode audio into buffer
	size_t sampleSize = (pSound->soundTemplate.bitsPerSample * pSound->soundTemplate.numChannels) >> 3;
	size_t bytesAllocated = 44100 * sampleSize;
	size_t bytes = 0;

	char *pAudioData = (char*)MFHeap_Alloc(bytesAllocated);

	size_t read;
	do
	{
		// read samples from stream
		read = MFSound_ReadStreamSamples(pStream, pAudioData + bytes, bytesAllocated - bytes);
		bytes += read;

		// if we fill the buffer, increase it's size
		if(bytes == bytesAllocated)
		{
			bytesAllocated *= 4;
			pAudioData = (char*)MFHeap_Realloc(pAudioData, bytesAllocated);
		}
	}
	while(read);

	// calculate the number of samples from the bytes read
	int numSamples = (int)(bytes / sampleSize);

	// construct MFSoundTemplate
	size_t templateBytes = sizeof(MFSoundTemplate) + sizeof(char*)*pSound->soundTemplate.numStreams + sampleSize*numSamples;
	MFSoundTemplate *pTemplate = (MFSoundTemplate*)MFHeap_Alloc(templateBytes);
	MFCopyMemory(pTemplate, &pSound->soundTemplate, sizeof(MFSoundTemplate));
	pTemplate->numSamples = numSamples;
	pTemplate->ppStreams = (char**)&pTemplate[1];
	pTemplate->ppStreams[0] = (char*)&pTemplate->ppStreams[1];

	// copy sample data
	MFCopyMemory(pTemplate->ppStreams[0], pAudioData, sampleSize * numSamples);

	// free decode buffer
	MFHeap_Free(pAudioData);

	// fix down pointers
	for(int a=0; a<pTemplate->numStreams; a++)
		MFFixUp(pTemplate->ppStreams[a], pTemplate, false);
	MFFixUp(pTemplate->ppStreams, pTemplate, false);

	// return template data
	*ppOutput = pTemplate;
	if(pSize)
		*pSize = templateBytes;
}
Esempio n. 2
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;
}
Esempio n. 3
0
void *MFPoolHeapCollection::Realloc(void *pItem, size_t size)
{
	if(!pItem)
		return Alloc(size);

	for(int i = 0; i < numHeaps; ++i)
	{
		MFPoolHeap *pHeap = pHeaps[i];

		if(pHeap->IsFromThisHeap(pItem))
		{
			size_t heapSize = pHeap->Size();
			if(size <= heapSize)
				return pItem;

			void *pNewItem = Alloc(size);
			MFCopyMemory(pNewItem, pItem, heapSize);
			Delete(pItem);
			return pNewItem;
		}
	}

	return MFHeap_Realloc(pItem, size);
}
Esempio n. 4
0
static void CALLBACK MidiInProc(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
	MFDevice *pDevice = (MFDevice*)dwInstance;
	MFMidiPC_MidiInputDevice *pMidi = (MFMidiPC_MidiInputDevice*)pDevice->pInternal;

	switch(wMsg)
	{
		case MIM_OPEN:
			MFDebug_Log(0, MFStr("Opened MIDI input device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MIM_CLOSE:
			MFDebug_Log(0, MFStr("Closed MIDI input device: %s", pDevice->strings[MFDS_ID]));
			break;
		case MIM_MOREDATA:
			MFDebug_Log(0, "MIDI message: MIM_MOREDATA");
			break;
		case MIM_DATA:
		{
			MFMidiEvent ev;
			MFMidi_DecodeShortMessage((uint32)dwParam1, &ev, (uint32)dwParam2);

			switch(ev.ev)
			{
				case MFMET_NoteOff:
					pMidi->channels[ev.channel].notes[ev.noteOff.note] = 0;
					break;
				case MFMET_NoteOn:
				case MFMET_NoteAftertouch:
					pMidi->channels[ev.channel].notes[ev.noteOn.note] = ev.noteOn.velocity;
					break;
				case MFMET_ControlChange:
					pMidi->channels[ev.channel].control[ev.controlChange.control] = ev.controlChange.value;
					break;
				case MFMET_ProgramChange:
					pMidi->channels[ev.channel].program = ev.programChange.program;
					break;
				case MFMET_ChannelAftertouch:
					// TODO: ... what is this?
					break;
				case MFMET_PitchBend:
					pMidi->channels[ev.channel].pitch = ev.pitchBend.value;
					break;
				default:
					MFDebug_Assert(false, "Why are we getting sys events?");
					break;
			}

			if (pMidi->bBuffered || pMidi->pEventCallback)
			{
				if (pMidi->bBuffered)
				{
					if (pMidi->numEvents >= pMidi->numAllocated)
					{
						pMidi->numAllocated *= 2;
						pMidi->pEvents = (MFMidiEvent*)MFHeap_Realloc(pMidi->pEvents, sizeof(MFMidiEvent)*pMidi->numAllocated);
					}

					pMidi->pEvents[pMidi->numEvents++] = ev;
				}
				if (pMidi->pEventCallback)
				{
					pMidi->pEventCallback(pDevice, &ev);
				}
			}
			break;
		}
		case MIM_LONGDATA:
		{
			MIDIHDR *pHdr = (MIDIHDR*)dwParam1;

			MFMidiEvent ev;
			MFMidi_DecodePacket((const uint8*)pHdr->lpData, pHdr->dwBytesRecorded, &ev, (uint32)dwParam2);

			if (pMidi->bBuffered || pMidi->pEventCallback)
			{
				if (pMidi->bBuffered)
				{
					if (pMidi->numEvents >= pMidi->numAllocated)
					{
						pMidi->numAllocated *= 2;
						pMidi->pEvents = (MFMidiEvent*)MFHeap_Realloc(pMidi->pEvents, sizeof(MFMidiEvent)*pMidi->numAllocated);
					}

					pMidi->pEvents[pMidi->numEvents++] = ev;
				}
				if (pMidi->pEventCallback)
				{
					pMidi->pEventCallback(pDevice, &ev);
				}
			}

			MMRESULT r = midiInAddBuffer(pMidi->hMidiIn, pHdr, sizeof(*pHdr));
			if (r != MMSYSERR_NOERROR)
			{
				wchar_t errorBuffer[256];
				midiInGetErrorText(r, errorBuffer, sizeof(errorBuffer));
				MFDebug_Warn(1, MFStr("Failed to open MIDI input device: %s", MFString_WCharAsUTF8(errorBuffer)));
			}
			break;
		}
		case MIM_ERROR:
		case MIM_LONGERROR:
		{
			MFDebug_Log(0, MFStr("MIDI input error: %d, 0x%08X : 0x%08X", wMsg, dwParam1, dwParam2));
			break;
		}
	}
}