summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k/lib_src/eas_xmf.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-wt-22k/lib_src/eas_xmf.c')
-rw-r--r--arm-wt-22k/lib_src/eas_xmf.c1676
1 files changed, 838 insertions, 838 deletions
diff --git a/arm-wt-22k/lib_src/eas_xmf.c b/arm-wt-22k/lib_src/eas_xmf.c
index b498b42..0a92425 100644
--- a/arm-wt-22k/lib_src/eas_xmf.c
+++ b/arm-wt-22k/lib_src/eas_xmf.c
@@ -1,12 +1,12 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_xmf.c
- * 5
- * Contents and purpose:
- * XMF File Parser
- *
- * Copyright Sonic Network Inc. 2005
+/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_xmf.c
+ * 5
+ * Contents and purpose:
+ * XMF File Parser
+ *
+ * Copyright Sonic Network Inc. 2005
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,832 +19,832 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 501 $
- * $Date: 2006-12-11 17:53:36 -0800 (Mon, 11 Dec 2006) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_miditypes.h"
-#include "eas_parser.h"
-#include "eas_report.h"
-#include "eas_host.h"
-#include "eas_midi.h"
-#include "eas_xmf.h"
-#include "eas_xmfdata.h"
-#include "eas_config.h"
-#include "eas_vm_protos.h"
-#include "eas_mdls.h"
-#include "eas_smf.h"
-
-
-/* XMF header file type */
-#define XMF_IDENTIFIER 0x584d465f
-#define XMF_VERSION_2_00 0x322e3030
-#define XMF_FILE_TYPE 0x00000002
-#define XMF_SPEC_LEVEL 0x00000001
-#define XMF_RIFF_CHUNK 0x52494646
-#define XMF_RIFF_DLS 0x444c5320
-#define XMF_SMF_CHUNK 0x4d546864
-
-/* local prototypes */
-static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
-static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
-static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
-static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
-static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
-static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
-static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
-static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData);
-static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength);
-static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value);
-
-
-/*----------------------------------------------------------------------------
- *
- * XMF_Parser
- *
- * This structure contains the functional interface for the XMF parser
- *----------------------------------------------------------------------------
-*/
-const S_FILE_PARSER_INTERFACE EAS_XMF_Parser =
-{
- XMF_CheckFileType,
- XMF_Prepare,
- XMF_Time,
- XMF_Event,
- XMF_State,
- XMF_Close,
- XMF_Reset,
- XMF_Pause,
- XMF_Resume,
- NULL,
- XMF_SetData,
- XMF_GetData,
- NULL
-};
-
-/*----------------------------------------------------------------------------
- * XMF_CheckFileType()
- *----------------------------------------------------------------------------
- * Purpose:
- * Check the file type to see if we can parse it
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
-{
- S_XMF_DATA *pXMFData;
- EAS_RESULT result;
- EAS_U32 temp;
-
- /* assume we don't recognize it initially */
- *ppHandle = NULL;
-
- /* read the file identifier */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_IDENTIFIER)
- return EAS_SUCCESS;
-
- /* read the version */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_VERSION_2_00)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file version was 0x%08x, expected 0x%08x\n", temp, XMF_VERSION_2_00); */ }
- return EAS_SUCCESS;
- }
-
- /* read the file type */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_FILE_TYPE)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file type was 0x%08x, expected 0x%08x\n", temp, XMF_FILE_TYPE); */ }
- return EAS_SUCCESS;
- }
-
- /* read the spec level */
- if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (temp != XMF_SPEC_LEVEL)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file spec was 0x%08x, expected 0x%08x\n", temp, XMF_SPEC_LEVEL); */ }
- return EAS_SUCCESS;
- }
-
- /* check for static memory allocation */
- if (pEASData->staticMemoryModel)
- pXMFData = EAS_CMEnumData(EAS_CM_XMF_DATA);
- else
- pXMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_XMF_DATA));
- if (!pXMFData)
- return EAS_ERROR_MALLOC_FAILED;
-
- /* zero the memory to insure complete initialization */
- EAS_HWMemSet((void *)pXMFData,0, sizeof(S_XMF_DATA));
-
- pXMFData->fileHandle = fileHandle;
- pXMFData->fileOffset = offset;
- *ppHandle = pXMFData;
-
- /* locate the SMF and DLS contents */
- if ((result = XMF_FindFileContents(pEASData->hwInstData, pXMFData)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
- return result;
- }
-
- /* let the SMF parser take over */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pXMFData->midiOffset)) != EAS_SUCCESS)
- return result;
- return SMF_CheckFileType(pEASData, fileHandle, &pXMFData->pSMFData, pXMFData->midiOffset);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Prepare()
- *----------------------------------------------------------------------------
- * Purpose:
- * Prepare to parse the file. Allocates instance data (or uses static allocation for
- * static memory model).
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_XMF_DATA* pXMFData;
- EAS_RESULT result;
-
- /* parse DLS collection */
- pXMFData = (S_XMF_DATA*) pInstData;
- if (pXMFData->dlsOffset != 0)
- {
- if ((result = DLSParser(pEASData->hwInstData, pXMFData->fileHandle, pXMFData->dlsOffset, &pXMFData->pDLS)) != EAS_SUCCESS)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error converting XMF DLS data\n"); */ }
- return result;
- }
- }
-
- /* Prepare the SMF parser */
- if ((result = SMF_Prepare(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
- return result;
-
- /* if no DLS file, skip this step */
- if (pXMFData->pDLS == NULL)
- return EAS_SUCCESS;
-
- /* tell the synth to use the DLS collection */
- result = VMSetDLSLib(((S_SMF_DATA*) pXMFData->pSMFData)->pSynth, pXMFData->pDLS);
- if (result == EAS_SUCCESS)
- {
- DLSAddRef(pXMFData->pDLS);
- VMInitializeAllChannels(pEASData->pVoiceMgr, ((S_SMF_DATA*) pXMFData->pSMFData)->pSynth);
- }
- return result;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Time()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the time of the next event in msecs
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pTime - pointer to variable to hold time of next event (in msecs)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
-{
- return SMF_Time(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pTime);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Event()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parse the next event in the file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
-{
- return SMF_Event(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, parserMode);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_State()
- *----------------------------------------------------------------------------
- * Purpose:
- * Returns the current state of the stream
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * pState - pointer to variable to store state
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
-{
- return SMF_State(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pState);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Close()
- *----------------------------------------------------------------------------
- * Purpose:
- * Close the file and clean up
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- S_XMF_DATA* pXMFData;
- EAS_RESULT result;
-
- pXMFData = (S_XMF_DATA *)pInstData;
-
- /* close the SMF stream, it will close the file handle */
- if ((result = SMF_Close(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
- return result;
-
- if (pXMFData->pDLS)
- DLSCleanup(pEASData->hwInstData, pXMFData->pDLS);
-
- /* if using dynamic memory, free it */
- if (!pEASData->staticMemoryModel)
- {
- /* free the instance data */
- EAS_HWFree(pEASData->hwInstData, pXMFData);
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Reset()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reset the sequencer. Used for locating backwards in the file.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Reset(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Pause()
- *----------------------------------------------------------------------------
- * Purpose:
- * Pauses the sequencer. Mutes all voices and sets state to pause.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Pause(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_Resume()
- *----------------------------------------------------------------------------
- * Purpose:
- * Resume playing after a pause, sets state back to playing.
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
-{
- return SMF_Resume(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_SetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Sets the playback rate of the underlying SMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * rate - rate (28-bit fraction)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
-{
- return SMF_SetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, value);
-}
-
-/*----------------------------------------------------------------------------
- * XMF_GetData()
- *----------------------------------------------------------------------------
- * Purpose:
- * Gets the file type
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * handle - pointer to file handle
- * rate - rate (28-bit fraction)
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
-{
- EAS_RESULT result;
-
- /* call SMF parser to get value */
- if ((result = SMF_GetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, pValue)) != EAS_SUCCESS)
- return result;
-
- /* special case for file type */
- if (param == PARSER_DATA_FILE_TYPE)
- {
- if (*pValue == EAS_FILE_SMF0)
- *pValue = EAS_FILE_XMF0;
- else if (*pValue == EAS_FILE_SMF1)
- *pValue = EAS_FILE_XMF1;
- }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_FindFileContents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Finds SMF data and DLS data in XMF file, and remembers offset for each.
- * If more than one is found, uses the first one found of each.
- * Makes assumptions about the format of a mobile XMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pXMFData - pointer to XMF parser instance data
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData)
-{
- EAS_RESULT result;
- EAS_I32 value;
- EAS_I32 length;
-
- /* initialize offsets */
- pXMFData->dlsOffset = pXMFData->midiOffset = 0;
-
- /* read file length, ignore it for now */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read MetaDataTypesTable length and skip over it */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, value)) != EAS_SUCCESS)
- return result;
-
- /* get TreeStart offset and jump to it */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = XMF_ReadNode(hwInstData, pXMFData, value, &length)) != EAS_SUCCESS)
- return result;
-
- /* check for SMF data */
- if (pXMFData->midiOffset == 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* check for SFM in wrong order */
- if ((pXMFData->dlsOffset > 0) && (pXMFData->midiOffset < pXMFData->dlsOffset))
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS data must precede SMF data in Mobile XMF file\n"); */ }
-
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * XMF_ReadNode()
- *----------------------------------------------------------------------------
- * Purpose:
- *
- * Inputs:
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength)
-{
- EAS_RESULT result;
- EAS_I32 refType;
- EAS_I32 numItems;
- EAS_I32 offset;
- EAS_I32 length;
- EAS_I32 headerLength;
- EAS_U32 chunkType;
-
- /* seek to start of node */
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset)) != EAS_SUCCESS)
- return result;
-
- /* get node length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, pLength)) != EAS_SUCCESS)
- return result;
-
- /* get number of contained items */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &numItems)) != EAS_SUCCESS)
- return result;
-
- /* get node header length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &headerLength)) != EAS_SUCCESS)
- return result;
-
- /* get metadata length */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &length)) != EAS_SUCCESS)
- return result;
-
- /* get the current location */
- if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /* skip to node contents */
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset + headerLength)) != EAS_SUCCESS)
- return result;
-
- /* get reference type */
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &refType)) != EAS_SUCCESS)
- return result;
-
- /* get the current location */
- if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /* process file node */
- if (numItems == 0)
-
- {
- /* if in-file resource, find out where it is and jump to it */
- if (refType == 2)
- {
- if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
- return result;
- offset += pXMFData->fileOffset;
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
- return result;
- }
-
- /* or else it must be an inline resource */
- else if (refType != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected reference type %d\n", refType); */ }
- return EAS_ERROR_FILE_FORMAT;
- }
-
- /* get the chunk type */
- if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
-
- /* found a RIFF chunk, check for DLS type */
- if (chunkType == XMF_RIFF_CHUNK)
- {
- /* skip length */
- if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, sizeof(EAS_I32))) != EAS_SUCCESS)
- return result;
-
- /* get RIFF file type */
- if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
- return result;
- if (chunkType == XMF_RIFF_DLS)
- pXMFData->dlsOffset = offset;
- }
-
- /* found an SMF chunk */
- else if (chunkType == XMF_SMF_CHUNK)
- pXMFData->midiOffset = offset;
- }
-
- /* folder node, process the items in the list */
- else
- {
- for ( ; numItems > 0; numItems--)
- {
- /* process this item */
- if ((result = XMF_ReadNode(hwInstData, pXMFData, offset, &length)) != EAS_SUCCESS)
- return result;
-
- /* seek to start of next item */
- offset += length;
- if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
- return result;
- }
- }
-
- return EAS_SUCCESS;
-}
-
-#if 0
-/*----------------------------------------------------------------------------
- * XMF_FindFileContents()
- *----------------------------------------------------------------------------
- * Purpose:
- * Finds SMF data and DLS data in XMF file, and remembers offset for each.
- * If more than one is found, uses the first one found of each.
- * Makes assumptions about the format of a mobile XMF file
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * pXMFData - pointer to XMF parser instance data
- * handle - pointer to file handle
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_FindFileContents(S_EAS_DATA *pEASData, S_XMF_DATA *pXMFData, EAS_FILE_HANDLE fileHandle)
-{
- EAS_RESULT result;
- EAS_I32 offset;
- EAS_I32 value;
- EAS_I32 numItems;
- EAS_I32 length;
- EAS_CHAR id[4];
- EAS_I32 location;
-
- /* init dls offset, so that we know we haven't found a dls chunk yet */
- pXMFData->dlsOffset = 0;
-
- /* read file length, ignore it for now */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read MetaDataTypesTable length and skip over it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeekOfs(pEASData, fileHandle, value)) != EAS_SUCCESS)
- return result;
-
- /* get TreeStart offset and jump to it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &offset)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
- return result;
-
- /* read node length, ignore it for now */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* read number of contained items */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &numItems)) != EAS_SUCCESS)
- return result;
-
- /*read node header length */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /*go to the node offset */
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
- return result;
-
- /* read Reference Type */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure it is an in-line resource, for now */
- if (value != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file tree\n"); */ }
- return EAS_FAILURE;
- }
-
- /* parse through the list of items */
- while (numItems > 0)
- {
- /*get current offset */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &offset)) != EAS_SUCCESS)
- return result;
-
- /*read node length */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &length)) != EAS_SUCCESS)
- return result;
-
- /* read number of items */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure not a folder */
- if (value != 0)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
- return EAS_FAILURE;
- }
-
- /* read offset to resource and jump to it */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
- return result;
-
- /* read Reference Type */
- if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
- return result;
-
- /* make sure it is an in-line resource */
- if (value != 1)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
- return EAS_FAILURE;
- }
-
- /* get current offset as a possible location for SMF file or DLS file */
- if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &location)) != EAS_SUCCESS)
- return result;
-
- /* read four bytes */
- if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, id, sizeof(id), &value)) != EAS_SUCCESS)
- return result;
-
- /* check if DLS */
- if (pXMFData->dlsOffset == 0 && id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F')
- {
- //remember offset
- pXMFData->dlsOffset = location;
- }
-
- /* else check if SMF */
- else if (id[0] == 'M' && id[1] == 'T' && id[2] == 'h' && id[3] == 'd')
- {
- //remember offset
- pXMFData->midiOffset = location;
-
- //we are done
- return EAS_SUCCESS;
- }
-
- //one less item
- numItems--;
-
- //if more data, go to the next item
- if (numItems >0)
- {
- if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + length)) != EAS_SUCCESS)
- return result;
- }
- }
-
- return EAS_FAILURE;
-
-}
-#endif
-
-/*----------------------------------------------------------------------------
- * XMF_ReadVLQ()
- *----------------------------------------------------------------------------
- * Purpose:
- * Reads a VLQ encoded value from the file referenced by fileHandle
- *
- * Inputs:
- * pEASData - pointer to overall EAS data structure
- * fileHandle - pointer to file handle
- *
- * Outputs:
- * value - pointer to the value decoded from the VLQ data
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value)
-{
- EAS_RESULT result;
- EAS_U8 c;
-
- *value = 0;
-
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- return result;
-
- while (c > 0x7F)
- {
- /*lint -e{703} shift for performance */
- *value = (*value << 7) | (c & 0x7F);
-
- if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
- return result;
- }
-
- /*lint -e{703} shift for performance */
- *value = (*value << 7) | c;
-
- return EAS_SUCCESS;
-}
-
+ *
+ *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 501 $
+ * $Date: 2006-12-11 17:53:36 -0800 (Mon, 11 Dec 2006) $
+ *----------------------------------------------------------------------------
+*/
+
+#include "eas_data.h"
+#include "eas_miditypes.h"
+#include "eas_parser.h"
+#include "eas_report.h"
+#include "eas_host.h"
+#include "eas_midi.h"
+#include "eas_xmf.h"
+#include "eas_xmfdata.h"
+#include "eas_config.h"
+#include "eas_vm_protos.h"
+#include "eas_mdls.h"
+#include "eas_smf.h"
+
+
+/* XMF header file type */
+#define XMF_IDENTIFIER 0x584d465f
+#define XMF_VERSION_2_00 0x322e3030
+#define XMF_FILE_TYPE 0x00000002
+#define XMF_SPEC_LEVEL 0x00000001
+#define XMF_RIFF_CHUNK 0x52494646
+#define XMF_RIFF_DLS 0x444c5320
+#define XMF_SMF_CHUNK 0x4d546864
+
+/* local prototypes */
+static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset);
+static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime);
+static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode);
+static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_STATE *pState);
+static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData);
+static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value);
+static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue);
+static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData);
+static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength);
+static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value);
+
+
+/*----------------------------------------------------------------------------
+ *
+ * XMF_Parser
+ *
+ * This structure contains the functional interface for the XMF parser
+ *----------------------------------------------------------------------------
+*/
+const S_FILE_PARSER_INTERFACE EAS_XMF_Parser =
+{
+ XMF_CheckFileType,
+ XMF_Prepare,
+ XMF_Time,
+ XMF_Event,
+ XMF_State,
+ XMF_Close,
+ XMF_Reset,
+ XMF_Pause,
+ XMF_Resume,
+ NULL,
+ XMF_SetData,
+ XMF_GetData,
+ NULL
+};
+
+/*----------------------------------------------------------------------------
+ * XMF_CheckFileType()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Check the file type to see if we can parse it
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
+{
+ S_XMF_DATA *pXMFData;
+ EAS_RESULT result;
+ EAS_U32 temp;
+
+ /* assume we don't recognize it initially */
+ *ppHandle = NULL;
+
+ /* read the file identifier */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_IDENTIFIER)
+ return EAS_SUCCESS;
+
+ /* read the version */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_VERSION_2_00)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file version was 0x%08x, expected 0x%08x\n", temp, XMF_VERSION_2_00); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* read the file type */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_FILE_TYPE)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file type was 0x%08x, expected 0x%08x\n", temp, XMF_FILE_TYPE); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* read the spec level */
+ if ((result = EAS_HWGetDWord(pEASData->hwInstData, fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (temp != XMF_SPEC_LEVEL)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "XMF file spec was 0x%08x, expected 0x%08x\n", temp, XMF_SPEC_LEVEL); */ }
+ return EAS_SUCCESS;
+ }
+
+ /* check for static memory allocation */
+ if (pEASData->staticMemoryModel)
+ pXMFData = EAS_CMEnumData(EAS_CM_XMF_DATA);
+ else
+ pXMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_XMF_DATA));
+ if (!pXMFData)
+ return EAS_ERROR_MALLOC_FAILED;
+
+ /* zero the memory to insure complete initialization */
+ EAS_HWMemSet((void *)pXMFData,0, sizeof(S_XMF_DATA));
+
+ pXMFData->fileHandle = fileHandle;
+ pXMFData->fileOffset = offset;
+ *ppHandle = pXMFData;
+
+ /* locate the SMF and DLS contents */
+ if ((result = XMF_FindFileContents(pEASData->hwInstData, pXMFData)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
+ return result;
+ }
+
+ /* let the SMF parser take over */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, pXMFData->midiOffset)) != EAS_SUCCESS)
+ return result;
+ return SMF_CheckFileType(pEASData, fileHandle, &pXMFData->pSMFData, pXMFData->midiOffset);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Prepare()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Prepare to parse the file. Allocates instance data (or uses static allocation for
+ * static memory model).
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_XMF_DATA* pXMFData;
+ EAS_RESULT result;
+
+ /* parse DLS collection */
+ pXMFData = (S_XMF_DATA*) pInstData;
+ if (pXMFData->dlsOffset != 0)
+ {
+ if ((result = DLSParser(pEASData->hwInstData, pXMFData->fileHandle, pXMFData->dlsOffset, &pXMFData->pDLS)) != EAS_SUCCESS)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Error converting XMF DLS data\n"); */ }
+ return result;
+ }
+ }
+
+ /* Prepare the SMF parser */
+ if ((result = SMF_Prepare(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ /* if no DLS file, skip this step */
+ if (pXMFData->pDLS == NULL)
+ return EAS_SUCCESS;
+
+ /* tell the synth to use the DLS collection */
+ result = VMSetDLSLib(((S_SMF_DATA*) pXMFData->pSMFData)->pSynth, pXMFData->pDLS);
+ if (result == EAS_SUCCESS)
+ {
+ DLSAddRef(pXMFData->pDLS);
+ VMInitializeAllChannels(pEASData->pVoiceMgr, ((S_SMF_DATA*) pXMFData->pSMFData)->pSynth);
+ }
+ return result;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Time()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the time of the next event in msecs
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pTime - pointer to variable to hold time of next event (in msecs)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
+{
+ return SMF_Time(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pTime);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Event()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Parse the next event in the file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
+{
+ return SMF_Event(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, parserMode);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_State()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Returns the current state of the stream
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * pState - pointer to variable to store state
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
+{
+ return SMF_State(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, pState);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Close()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Close the file and clean up
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ S_XMF_DATA* pXMFData;
+ EAS_RESULT result;
+
+ pXMFData = (S_XMF_DATA *)pInstData;
+
+ /* close the SMF stream, it will close the file handle */
+ if ((result = SMF_Close(pEASData, pXMFData->pSMFData)) != EAS_SUCCESS)
+ return result;
+
+ if (pXMFData->pDLS)
+ DLSCleanup(pEASData->hwInstData, pXMFData->pDLS);
+
+ /* if using dynamic memory, free it */
+ if (!pEASData->staticMemoryModel)
+ {
+ /* free the instance data */
+ EAS_HWFree(pEASData->hwInstData, pXMFData);
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Reset()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reset the sequencer. Used for locating backwards in the file.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Reset(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Pause()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Pauses the sequencer. Mutes all voices and sets state to pause.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Pause(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_Resume()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Resume playing after a pause, sets state back to playing.
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
+{
+ return SMF_Resume(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_SetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Sets the playback rate of the underlying SMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * rate - rate (28-bit fraction)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
+{
+ return SMF_SetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, value);
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_GetData()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Gets the file type
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * handle - pointer to file handle
+ * rate - rate (28-bit fraction)
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
+{
+ EAS_RESULT result;
+
+ /* call SMF parser to get value */
+ if ((result = SMF_GetData(pEASData, ((S_XMF_DATA*) pInstData)->pSMFData, param, pValue)) != EAS_SUCCESS)
+ return result;
+
+ /* special case for file type */
+ if (param == PARSER_DATA_FILE_TYPE)
+ {
+ if (*pValue == EAS_FILE_SMF0)
+ *pValue = EAS_FILE_XMF0;
+ else if (*pValue == EAS_FILE_SMF1)
+ *pValue = EAS_FILE_XMF1;
+ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_FindFileContents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Finds SMF data and DLS data in XMF file, and remembers offset for each.
+ * If more than one is found, uses the first one found of each.
+ * Makes assumptions about the format of a mobile XMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pXMFData - pointer to XMF parser instance data
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_FindFileContents (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData)
+{
+ EAS_RESULT result;
+ EAS_I32 value;
+ EAS_I32 length;
+
+ /* initialize offsets */
+ pXMFData->dlsOffset = pXMFData->midiOffset = 0;
+
+ /* read file length, ignore it for now */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read MetaDataTypesTable length and skip over it */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, value)) != EAS_SUCCESS)
+ return result;
+
+ /* get TreeStart offset and jump to it */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = XMF_ReadNode(hwInstData, pXMFData, value, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* check for SMF data */
+ if (pXMFData->midiOffset == 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No SMF data found in XMF file\n"); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* check for SFM in wrong order */
+ if ((pXMFData->dlsOffset > 0) && (pXMFData->midiOffset < pXMFData->dlsOffset))
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS data must precede SMF data in Mobile XMF file\n"); */ }
+
+ return EAS_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------
+ * XMF_ReadNode()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_ReadNode (EAS_HW_DATA_HANDLE hwInstData, S_XMF_DATA *pXMFData, EAS_I32 nodeOffset, EAS_I32 *pLength)
+{
+ EAS_RESULT result;
+ EAS_I32 refType;
+ EAS_I32 numItems;
+ EAS_I32 offset;
+ EAS_I32 length;
+ EAS_I32 headerLength;
+ EAS_U32 chunkType;
+
+ /* seek to start of node */
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset)) != EAS_SUCCESS)
+ return result;
+
+ /* get node length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, pLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get number of contained items */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &numItems)) != EAS_SUCCESS)
+ return result;
+
+ /* get node header length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &headerLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get metadata length */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current location */
+ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /* skip to node contents */
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, nodeOffset + headerLength)) != EAS_SUCCESS)
+ return result;
+
+ /* get reference type */
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &refType)) != EAS_SUCCESS)
+ return result;
+
+ /* get the current location */
+ if ((result = EAS_HWFilePos(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /* process file node */
+ if (numItems == 0)
+
+ {
+ /* if in-file resource, find out where it is and jump to it */
+ if (refType == 2)
+ {
+ if ((result = XMF_ReadVLQ(hwInstData, pXMFData->fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+ offset += pXMFData->fileOffset;
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /* or else it must be an inline resource */
+ else if (refType != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unexpected reference type %d\n", refType); */ }
+ return EAS_ERROR_FILE_FORMAT;
+ }
+
+ /* get the chunk type */
+ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+
+ /* found a RIFF chunk, check for DLS type */
+ if (chunkType == XMF_RIFF_CHUNK)
+ {
+ /* skip length */
+ if ((result = EAS_HWFileSeekOfs(hwInstData, pXMFData->fileHandle, sizeof(EAS_I32))) != EAS_SUCCESS)
+ return result;
+
+ /* get RIFF file type */
+ if ((result = EAS_HWGetDWord(hwInstData, pXMFData->fileHandle, &chunkType, EAS_TRUE)) != EAS_SUCCESS)
+ return result;
+ if (chunkType == XMF_RIFF_DLS)
+ pXMFData->dlsOffset = offset;
+ }
+
+ /* found an SMF chunk */
+ else if (chunkType == XMF_SMF_CHUNK)
+ pXMFData->midiOffset = offset;
+ }
+
+ /* folder node, process the items in the list */
+ else
+ {
+ for ( ; numItems > 0; numItems--)
+ {
+ /* process this item */
+ if ((result = XMF_ReadNode(hwInstData, pXMFData, offset, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* seek to start of next item */
+ offset += length;
+ if ((result = EAS_HWFileSeek(hwInstData, pXMFData->fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ return EAS_SUCCESS;
+}
+
+#if 0
+/*----------------------------------------------------------------------------
+ * XMF_FindFileContents()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Finds SMF data and DLS data in XMF file, and remembers offset for each.
+ * If more than one is found, uses the first one found of each.
+ * Makes assumptions about the format of a mobile XMF file
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * pXMFData - pointer to XMF parser instance data
+ * handle - pointer to file handle
+ *
+ * Outputs:
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_FindFileContents(S_EAS_DATA *pEASData, S_XMF_DATA *pXMFData, EAS_FILE_HANDLE fileHandle)
+{
+ EAS_RESULT result;
+ EAS_I32 offset;
+ EAS_I32 value;
+ EAS_I32 numItems;
+ EAS_I32 length;
+ EAS_CHAR id[4];
+ EAS_I32 location;
+
+ /* init dls offset, so that we know we haven't found a dls chunk yet */
+ pXMFData->dlsOffset = 0;
+
+ /* read file length, ignore it for now */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read MetaDataTypesTable length and skip over it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeekOfs(pEASData, fileHandle, value)) != EAS_SUCCESS)
+ return result;
+
+ /* get TreeStart offset and jump to it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
+ return result;
+
+ /* read node length, ignore it for now */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* read number of contained items */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &numItems)) != EAS_SUCCESS)
+ return result;
+
+ /*read node header length */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /*go to the node offset */
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
+ return result;
+
+ /* read Reference Type */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is an in-line resource, for now */
+ if (value != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file tree\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* parse through the list of items */
+ while (numItems > 0)
+ {
+ /*get current offset */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &offset)) != EAS_SUCCESS)
+ return result;
+
+ /*read node length */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &length)) != EAS_SUCCESS)
+ return result;
+
+ /* read number of items */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure not a folder */
+ if (value != 0)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* read offset to resource and jump to it */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + value)) != EAS_SUCCESS)
+ return result;
+
+ /* read Reference Type */
+ if ((result = XMF_ReadVLQ(pEASData, fileHandle, &value)) != EAS_SUCCESS)
+ return result;
+
+ /* make sure it is an in-line resource */
+ if (value != 1)
+ {
+ { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Problem parsing XMF file node\n"); */ }
+ return EAS_FAILURE;
+ }
+
+ /* get current offset as a possible location for SMF file or DLS file */
+ if ((result = EAS_HWFilePos(pEASData->hwInstData, fileHandle, &location)) != EAS_SUCCESS)
+ return result;
+
+ /* read four bytes */
+ if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, id, sizeof(id), &value)) != EAS_SUCCESS)
+ return result;
+
+ /* check if DLS */
+ if (pXMFData->dlsOffset == 0 && id[0] == 'R' && id[1] == 'I' && id[2] == 'F' && id[3] == 'F')
+ {
+ //remember offset
+ pXMFData->dlsOffset = location;
+ }
+
+ /* else check if SMF */
+ else if (id[0] == 'M' && id[1] == 'T' && id[2] == 'h' && id[3] == 'd')
+ {
+ //remember offset
+ pXMFData->midiOffset = location;
+
+ //we are done
+ return EAS_SUCCESS;
+ }
+
+ //one less item
+ numItems--;
+
+ //if more data, go to the next item
+ if (numItems >0)
+ {
+ if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset + length)) != EAS_SUCCESS)
+ return result;
+ }
+ }
+
+ return EAS_FAILURE;
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * XMF_ReadVLQ()
+ *----------------------------------------------------------------------------
+ * Purpose:
+ * Reads a VLQ encoded value from the file referenced by fileHandle
+ *
+ * Inputs:
+ * pEASData - pointer to overall EAS data structure
+ * fileHandle - pointer to file handle
+ *
+ * Outputs:
+ * value - pointer to the value decoded from the VLQ data
+ *
+ *
+ * Side Effects:
+ *
+ *----------------------------------------------------------------------------
+*/
+static EAS_RESULT XMF_ReadVLQ (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 *value)
+{
+ EAS_RESULT result;
+ EAS_U8 c;
+
+ *value = 0;
+
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+
+ while (c > 0x7F)
+ {
+ /*lint -e{703} shift for performance */
+ *value = (*value << 7) | (c & 0x7F);
+
+ if ((result = EAS_HWGetByte(hwInstData, fileHandle, &c)) != EAS_SUCCESS)
+ return result;
+ }
+
+ /*lint -e{703} shift for performance */
+ *value = (*value << 7) | c;
+
+ return EAS_SUCCESS;
+}
+