Example #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;
}
void MFAnimation_FixUp(MFAnimationTemplate *pTemplate, bool load)
{
	if(load)
	{
		MFFixUp(pTemplate->pBones, pTemplate, 1);
		MFFixUp(pTemplate->pAnimName, pTemplate, 1);
	}

	for(uint32 a=0; a<pTemplate->numBones; a++)
	{
		MFFixUp(pTemplate->pBones[a].pBoneName, pTemplate, load);
		MFFixUp(pTemplate->pBones[a].pTime, pTemplate, load);
		MFFixUp(pTemplate->pBones[a].pFrames, pTemplate, load);
	}

	if(!load)
	{
		MFFixUp(pTemplate->pBones, pTemplate, 0);
		MFFixUp(pTemplate->pAnimName, pTemplate, 0);
	}
}
Example #3
0
void MFMesh_FixUpMeshChunkGeneric(MFMeshChunk *pMeshChunk, void *pBase, bool load)
{
	MFCALLSTACK;

	MFDebug_Assert(pMeshChunk->type == MFMCT_Generic, "Not a Generic type meshchunk!!");

	MFMeshChunk_Generic *pMC = (MFMeshChunk_Generic*)pMeshChunk;

	MFFixUp(pMC->pMaterial, pBase, load);
	MFFixUp(pMC->pIndexData, pBase, load);
	MFFixUp(pMC->pBatchIndices, pBase, load);

	if(load)
	{
		MFFixUp(pMC->pVertexFormat, pBase, 1);
		MFFixUp(pMC->pVertexFormat->pStreams, pBase, 1);
		MFFixUp(pMC->ppVertexStreams, pBase, 1);
	}

	for(int b=0; b<pMC->pVertexFormat->numVertexStreams; ++b)
	{
		if(pMC->pVertexFormat->pStreams[b].pStreamName)
			MFFixUp(pMC->pVertexFormat->pStreams[b].pStreamName, pBase, load);
		MFFixUp(pMC->pVertexFormat->pStreams[b].pElements, pBase, load);
		MFFixUp(pMC->ppVertexStreams[b], pBase, load);
	}

	if(!load)
	{
		MFFixUp(pMC->pVertexFormat->pStreams, pBase, 0);
		MFFixUp(pMC->pVertexFormat, pBase, 0);
		MFFixUp(pMC->ppVertexStreams, pBase, 0);
	}
}
Example #4
0
int main(int argc, char *argv[])
{
    MFPlatform platform = FP_Unknown;
    MFWaveFormat targetFormat = MFWF_PCM_s16;

    char fileName[256] = "";
    char outFile[256] = "";

    int a;

    // process command line
    for(a=1; a<argc; a++)
    {
        if(argv[a][0] == '-' || argv[a][0] == '/')
        {
            for(int b=0; b<FP_Max; b++)
            {
                if(!MFString_CaseCmp(&argv[a][1], MFSystem_GetPlatformString(b)))
                {
                    platform = (MFPlatform)b;
                    break;
                }
            }

            if(!MFString_CaseCmp(&argv[a][1], "v") || !MFString_CaseCmp(&argv[a][1], "version"))
            {
                // print version
                return 0;
            }
        }
        else
        {
            if(!fileName[0])
                MFString_Copy(fileName, argv[a]);
            else if(!outFile[0])
                MFString_Copy(outFile, argv[a]);
        }
    }

    if(platform == FP_Unknown)
    {
        LOGERROR("No platform specified...\n");
        return 1;
    }

    if(!fileName[0])
    {
        LOGERROR("No file specified...\n");
        return 1;
    }

    if(!outFile[0])
    {
        // generate output filename
        MFString_Copy(outFile, fileName);
        for(int i=MFString_Length(outFile); --i; )
        {
            if(outFile[i] == '.')
            {
                outFile[i] = 0;
                break;
            }
        }

        MFString_Cat(outFile, ".snd");
    }

    // load image
    char *pBuffer;

    FILE *pFile = fopen(fileName, "rb");
    if(!pFile)
    {
        LOGERROR("Couldnt open source file '%s' for reading.", fileName);
        return 1;
    }

    fseek(pFile, 0, SEEK_END);
    int bytes = ftell(pFile) + 1;
    fseek(pFile, 0, SEEK_SET);

    pBuffer = (char*)malloc(bytes);
    fread(pBuffer, bytes, 1, pFile);
    fclose(pFile);

    FILE *pOutFile = fopen(outFile, "wb");

    if(!pOutFile)
    {
        LOGERROR("Couldnt open output file '%s' for writing.", outFile);
        return 2;
    }

    // parse the sound file...
    WAVHeader *pHeader = (WAVHeader*)pBuffer;

    if(pHeader->RIFF != MFMAKEFOURCC('R', 'I', 'F', 'F') || pHeader->WAVE != MFMAKEFOURCC('W', 'A', 'V', 'E'))
    {
        LOGERROR("Source file '%s' is not a wave file.", fileName);
        return 1;
    }

    WAVChunk *pChunk = (WAVChunk*)&pHeader[1];

    WAVFormatChunk *pFormat = NULL;
    WAVDataChunk *pData = NULL;

    while((char*)pChunk - pBuffer < bytes && bytes - ((char*)pChunk - pBuffer) >= sizeof(WAVChunk))
    {
        if(pChunk->id == MFMAKEFOURCC('f', 'm', 't', ' '))
        {
            pFormat = (WAVFormatChunk*)pChunk;
        }
        else if(pChunk->id == MFMAKEFOURCC('d', 'a', 't', 'a'))
        {
            pData = (WAVDataChunk*)pChunk;
        }

        pChunk = (WAVChunk*)((char*)pChunk + sizeof(WAVChunk) + ((pChunk->size+1) & ~1));
    }

    if(!pFormat || !pData)
    {
        LOGERROR("WAVE file '%s' has no format or data chunks.", fileName);
        return 2;
    }

    // we only output 1 stream for now..
    int numStreams = 1;
    int numSamples = ((pData->size*8) / ((pFormat->wBitsPerSample + 7) & ~7)) / pFormat->nChannels;

    int fileSize = sizeof(MFSoundTemplate) + sizeof(char*)*numStreams + bytesPerSample[targetFormat]*pFormat->nChannels*numSamples*numStreams;
    char *pSndFile = (char*)MFHeap_Alloc(fileSize);

    MFSoundTemplate *pTemplate = (MFSoundTemplate*)pSndFile;
    pTemplate->ppStreams = (char **)&pTemplate[1];
    char *pWaveData = (char*)&pTemplate->ppStreams[numStreams];
    for(int a=0; a<numStreams; a++)
    {
        pTemplate->ppStreams[a] = pWaveData;
        pWaveData += bytesPerSample[targetFormat]*pFormat->nChannels*numSamples;
    }

    pTemplate->magic = MFMAKEFOURCC('S', 'N', 'D', '1');
    pTemplate->flags = 0;
    pTemplate->format = targetFormat;
    pTemplate->numSamples = numSamples;
    pTemplate->numStreams = numStreams;
    pTemplate->numChannels = pFormat->nChannels;
    pTemplate->bitsPerSample = bytesPerSample[targetFormat]*8;
    pTemplate->sampleRate = pFormat->nSamplesPerSec;

    // write wave data into file
    if(pTemplate->bitsPerSample == pFormat->wBitsPerSample)
    {
        for(int a=0; a<pTemplate->numStreams; a++)
            MFCopyMemory(pTemplate->ppStreams[a], pData->data, bytesPerSample[targetFormat]*pTemplate->numChannels*pTemplate->numSamples);
    }
    else
    {
        // do a format conversion
        LOGERROR("Format conversion not written.");
        return 3;
    }

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

    // write to disk
    fwrite(pSndFile, fileSize, 1, pOutFile);
    fclose(pOutFile);

    printf("> %s\n", outFile);

    return 0;
}
Example #5
0
void MFModel_FixUp(MFModelTemplate *pTemplate, bool load)
{
	int a, b, c;

	if(load)
	{
		MFFixUp(pTemplate->pDataChunks, pTemplate, 1);
		MFFixUp(pTemplate->pName, pTemplate, 1);
	}

	for(a=0; a<pTemplate->numDataChunks; a++)
	{
		if(load)
			MFFixUp(pTemplate->pDataChunks[a].pData, pTemplate, 1);

		switch(pTemplate->pDataChunks[a].chunkType)
		{
			case MFChunkType_SubObjects:
			{
				MFModelSubObject *pSubobjects = (MFModelSubObject*)pTemplate->pDataChunks[a].pData;

				for(b=0; b<pTemplate->pDataChunks[a].count; b++)
				{
					if(load)
					{
						MFFixUp(pSubobjects[b].pMeshChunks, pTemplate, 1);

						MFFixUp(pSubobjects[b].pSubObjectName, pTemplate, 1);
//						MFFixUp(pSubobjects[b].pMaterial, pTemplate, 1);
					}

					for(c=0; c<pSubobjects[b].numMeshChunks; c++)
					{
						MFModel_FixUpMeshChunk(MFModel_GetMeshChunkInternal(pTemplate, b, c), pTemplate, load);
					}

					if(!load)
					{
						MFFixUp(pSubobjects[b].pSubObjectName, pTemplate, 0);
//						MFFixUp(pSubobjects[b].pMaterial, pTemplate, 0);

						MFFixUp(pSubobjects[b].pMeshChunks, pTemplate, 0);
					}
				}
				break;
			}

			case MFChunkType_Bones:
			{
				MFModelBone *pBones = (MFModelBone*)pTemplate->pDataChunks[a].pData;

				for(b=0; b<pTemplate->pDataChunks[a].count; b++)
				{
					MFFixUp(pBones[b].pBoneName, pTemplate, load);
					MFFixUp(pBones[b].pParentName, pTemplate, load);
					MFFixUp(pBones[b].pChildren, pTemplate, load);
				}
				break;
			}

			case MFChunkType_Collision:
			{
				MFCollisionTemplate *pCollisionChunk = (MFCollisionTemplate*)pTemplate->pDataChunks[a].pData;

				for(b=0; b<pTemplate->pDataChunks[a].count; b++)
				{
					MFFixUp(pCollisionChunk[b].pName, pTemplate, load);

					if(load)
						MFFixUp(pCollisionChunk[b].pCollisionTemplateData, pTemplate, 1);

					if(pCollisionChunk[b].type == MFCT_Mesh)
					{
						MFCollisionMesh *pMesh = (MFCollisionMesh*)pCollisionChunk[b].pCollisionTemplateData;
						MFFixUp(pMesh->pTriangles, pTemplate, load);
					}

					if(!load)
						MFFixUp(pCollisionChunk[b].pCollisionTemplateData, pTemplate, 0);
				}
				break;
			}

			case MFChunkType_Tags:
			{
				MFModelTag *pTags = (MFModelTag*)pTemplate->pDataChunks[a].pData;

				for(b=0; b<pTemplate->pDataChunks[a].count; b++)
				{
					MFFixUp(pTags[b].pTagName, pTemplate, load);
				}
				break;
			}

			default:
				break;
		}

		if(!load)
			MFFixUp(pTemplate->pDataChunks[a].pData, pTemplate, 0);
	}

	if(!load)
	{
		MFFixUp(pTemplate->pDataChunks, pTemplate, 0);
		MFFixUp(pTemplate->pName, pTemplate, 0);
	}
}