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; }
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; }
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); }
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; } } }