eas_smf.c revision a8c89077d78769bf4840fa91609edc51fe2fa02d
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * File:
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eas_smf.c
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Contents and purpose:
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF Type 0 and 1 File Parser
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * For SMF timebase analysis, see "MIDI Sequencer Analysis.xls".
10df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt *
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright Sonic Network Inc. 2005
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License");
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * you may not use this file except in compliance with the License.
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * You may obtain a copy of the License at
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *      http://www.apache.org/licenses/LICENSE-2.0
1850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
1950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software
2050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS,
2150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * See the License for the specific language governing permissions and
2350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * limitations under the License.
2450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
25c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
26c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Revision Control:
27c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *   $Revision: 803 $
28c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *   $Date: 2007-08-01 09:57:00 -0700 (Wed, 01 Aug 2007) $
2950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
3050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt*/
3150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_data.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_miditypes.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_parser.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_report.h"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_host.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_midi.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_config.h"
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_vm_protos.h"
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_smfdata.h"
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eas_smf.h"
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef JET_INTERFACE
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "jet_data.h"
45fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt#endif
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//3 dls: The timebase for this module is adequate to keep MIDI and
488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//3 digital audio synchronized for only a few minutes. It should be
498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//3 sufficient for most mobile applications. If better accuracy is
508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt//3 required, more fractional bits should be added to the timebase.
518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const EAS_U8 smfHeader[] = { 'M', 'T', 'h', 'd' };
538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* local prototypes */
558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData);
568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream);
578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode);
588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode);
598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream);
608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks);
618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
6450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
6550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * SMF_Parser
6650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This structure contains the functional interface for the SMF parser
6850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst S_FILE_PARSER_INTERFACE EAS_SMF_Parser =
718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    SMF_CheckFileType,
738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    SMF_Prepare,
74c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Time,
75c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Event,
76c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_State,
77c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Close,
78c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Reset,
79c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Pause,
80c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    SMF_Resume,
8150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    NULL,
8250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    SMF_SetData,
8350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    SMF_GetData,
8450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    NULL
8550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt};
8650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
8750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*----------------------------------------------------------------------------
888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_CheckFileType()
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Check the file type to see if we can parse it
928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle           - pointer to file handle
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_CheckFileType (S_EAS_DATA *pEASData, EAS_FILE_HANDLE fileHandle, EAS_VOID_PTR *ppHandle, EAS_I32 offset)
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    S_SMF_DATA* pSMFData;
1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_RESULT result;
1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* seek to starting offset - usually 0 */
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    *ppHandle = NULL;
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWFileSeek(pEASData->hwInstData, fileHandle, offset)) != EAS_SUCCESS)
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* search through file for header - slow method */
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pEASData->searchHeaderFlag)
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        result = EAS_SearchFile(pEASData, fileHandle, smfHeader, sizeof(smfHeader), &offset);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (result != EAS_SUCCESS)
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return (result == EAS_EOF) ? EAS_SUCCESS : result;
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* read the first 4 bytes of the file - quick method */
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else {
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        EAS_U8 header[4];
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        EAS_I32 count;
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = EAS_HWReadFile(pEASData->hwInstData, fileHandle, header, sizeof(header), &count)) != EAS_SUCCESS)
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* check for 'MTrk' - return if no match */
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((header[0] != 'M') || (header[1] != 'T') || (header[2] != 'h') || (header[3] != 'd'))
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return EAS_SUCCESS;
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* check for static memory allocation */
1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pEASData->staticMemoryModel)
1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData = EAS_CMEnumData(EAS_CM_SMF_DATA);
1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else
1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData = EAS_HWMalloc(pEASData->hwInstData, sizeof(S_SMF_DATA));
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        EAS_HWMemSet((void *)pSMFData,0, sizeof(S_SMF_DATA));
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (!pSMFData)
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return EAS_ERROR_MALLOC_FAILED;
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* initialize some critical data */
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->fileHandle = fileHandle;
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->fileOffset = offset;
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->pSynth = NULL;
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->time = 0;
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->state = EAS_STATE_OPEN;
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    *ppHandle = pSMFData;
15250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
15350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    return EAS_SUCCESS;
15450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt}
15550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
15650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*----------------------------------------------------------------------------
15750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * SMF_Prepare()
15850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
15950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Purpose:
16050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Prepare to parse the file. Allocates instance data (or uses static allocation for
16150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * static memory model).
16250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle           - pointer to file handle
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
17450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry ShmidtEAS_RESULT SMF_Prepare (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
17550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{
17650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    S_SMF_DATA* pSMFData;
17750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_RESULT result;
17850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* check for valid state */
180c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData = (S_SMF_DATA *) pInstData;
181c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->state != EAS_STATE_OPEN)
182c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
183c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
184c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* instantiate a synthesizer */
185c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if ((result = VMInitMIDI(pEASData, &pSMFData->pSynth)) != EAS_SUCCESS)
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "VMInitMIDI returned %d\n", result); */ }
1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
190c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
191c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* parse the file header and setup the individual stream parsers */
192c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if ((result = SMF_ParseHeader(pEASData->hwInstData, pSMFData)) != EAS_SUCCESS)
19361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt        return result;
19461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
195c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* ready to play */
196c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData->state = EAS_STATE_READY;
197c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    return EAS_SUCCESS;
198c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
199c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
200c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/*----------------------------------------------------------------------------
201c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * SMF_Time()
202c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
203c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Purpose:
204c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Returns the time of the next event in msecs
20561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *
20661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Inputs:
207c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
208c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * handle           - pointer to file handle
209c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pTime            - pointer to variable to hold time of next event (in msecs)
210c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
211c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Outputs:
212c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
213c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
21450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Side Effects:
21550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
21650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
21750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt*/
21850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*lint -esym(715, pEASData) reserved for future use */
21950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry ShmidtEAS_RESULT SMF_Time (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_U32 *pTime)
22050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{
22150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    S_SMF_DATA *pSMFData;
22250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
22350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
22450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
22550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* sanity check */
22650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#ifdef _CHECKED_BUILD
22750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if (pSMFData->state == EAS_STATE_STOPPED)
22850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    {
22950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Can't ask for time on a stopped stream\n"); */ }
23050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
23150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
23250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if (pSMFData->nextStream == NULL)
23350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    {
23450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        { /* dpp: EAS_ReportEx( _EAS_SEVERITY_ERROR, "no is NULL\n"); */ }
23550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
23650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#endif
23750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
23850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt#if 0
23950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* return time in milliseconds */
24050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* if chase mode, lie about time */
241c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        *pTime = 0;
24361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
24461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    else
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /*lint -e{704} use shift instead of division */
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        *pTime = pSMFData->time >> 8;
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    *pTime = pSMFData->time >> 8;
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
255c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * SMF_Event()
256c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
25750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Purpose:
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Parse the next event in the file
25950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
26250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * handle           - pointer to file handle
26350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
26450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Outputs:
26550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
26650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
26750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Side Effects:
26850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
26950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
27050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt*/
27150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry ShmidtEAS_RESULT SMF_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode)
27250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{
27350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    S_SMF_DATA* pSMFData;
27450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_RESULT result;
27550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_I32 i;
27650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_U32 ticks;
27750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_U32 temp;
27850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
27950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* establish pointer to instance data */
28050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
28150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if (pSMFData->state >= EAS_STATE_OPEN)
28250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        return EAS_SUCCESS;
28350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
28450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* get current ticks */
28550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    ticks = pSMFData->nextStream->ticks;
28650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
28750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* assume that an error occurred */
28850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    pSMFData->state = EAS_STATE_ERROR;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef JET_INTERFACE
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* if JET has track muted, set parser mode to mute */
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pSMFData->nextStream->midiStream.jetData & MIDI_FLAGS_JET_MUTE)
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        parserMode = eParserModeMute;
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* parse the next event from all the streams */
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = SMF_ParseEvent(pEASData, pSMFData, pSMFData->nextStream, parserMode)) != EAS_SUCCESS)
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* check for unexpected end-of-file */
3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (result != EAS_EOF)
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* indicate end of track for this stream */
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get next delta time, unless already at end of track */
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else if (pSMFData->nextStream->ticks != SMF_END_OF_TRACK)
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = SMF_GetDeltaTime(pEASData->hwInstData, pSMFData->nextStream)) != EAS_SUCCESS)
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        {
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* check for unexpected end-of-file */
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (result != EAS_EOF)
314c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                return result;
31550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            /* indicate end of track for this stream */
31750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            pSMFData->nextStream->ticks = SMF_END_OF_TRACK;
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        }
31950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
32050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        /* if zero delta to next event, stay with this stream */
32150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        else if (pSMFData->nextStream->ticks == ticks)
32250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        {
32350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            pSMFData->state = EAS_STATE_PLAY;
32450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            return EAS_SUCCESS;
32550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        }
32650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* find next event in all streams */
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    temp = 0x7ffffff;
330c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData->nextStream = NULL;
331c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    for (i = 0; i < pSMFData->numStreams; i++)
332c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
333c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (pSMFData->streams[i].ticks < temp)
334c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        {
335c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            temp = pSMFData->streams[i].ticks;
336c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            pSMFData->nextStream = &pSMFData->streams[i];
337c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        }
338c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
339c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
340c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* are there any more events to parse? */
341c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->nextStream)
342c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
343c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        pSMFData->state = EAS_STATE_PLAY;
344c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
345c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        /* update the time of the next event */
346c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks - ticks);
347c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
348c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    else
349c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
350c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        pSMFData->state = EAS_STATE_STOPPING;
351c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        VMReleaseAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
352c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
353c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
354c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    return EAS_SUCCESS;
355c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
356c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
357c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/*----------------------------------------------------------------------------
358c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * SMF_State()
359c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
360c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Purpose:
361c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Returns the current state of the stream
362c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
363c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Inputs:
364c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
365c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * handle           - pointer to file handle
366c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pState           - pointer to variable to store state
367c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
368c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Outputs:
369c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
370c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
371c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Side Effects:
372c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
373c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
374c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt*/
375c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/*lint -esym(715, pEASData) reserved for future use */
376c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry ShmidtEAS_RESULT SMF_State (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 *pState)
377c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
378c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    S_SMF_DATA* pSMFData;
379c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
380c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* establish pointer to instance data */
381c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
382c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
383c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* if stopping, check to see if synth voices are active */
38404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt    if (pSMFData->state == EAS_STATE_STOPPING)
385c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
386c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (VMActiveVoices(pSMFData->pSynth) == 0)
387c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            pSMFData->state = EAS_STATE_STOPPED;
388c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
389c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
390c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->state == EAS_STATE_PAUSING)
391c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
392c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (VMActiveVoices(pSMFData->pSynth) == 0)
393c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            pSMFData->state = EAS_STATE_PAUSED;
394c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
395c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
396c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* return current state */
397c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    *pState = pSMFData->state;
398c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    return EAS_SUCCESS;
399c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
400c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
401c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/*----------------------------------------------------------------------------
402c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * SMF_Close()
403c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
404c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Purpose:
405c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Close the file and clean up
406c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
407c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Inputs:
408c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
409c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * handle           - pointer to file handle
410c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
411c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Outputs:
412c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
413c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
414c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Side Effects:
415c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
416c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
417c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt*/
418c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry ShmidtEAS_RESULT SMF_Close (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
419c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt{
420c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    S_SMF_DATA* pSMFData;
421c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    EAS_I32 i;
422c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    EAS_RESULT result;
423c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
424c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
425c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
426c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* close all the streams */
427c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    for (i = 0; i < pSMFData->numStreams; i++)
428c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
429c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (pSMFData->streams[i].fileHandle != NULL)
430c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        {
431c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->streams[i].fileHandle)) != EAS_SUCCESS)
432c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                return result;
433c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        }
434c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
435c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->fileHandle != NULL)
436c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if ((result = EAS_HWCloseFile(pEASData->hwInstData, pSMFData->fileHandle)) != EAS_SUCCESS)
437c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            return result;
438c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
439c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* free the synth */
440c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->pSynth != NULL)
441c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        VMMIDIShutdown(pEASData, pSMFData->pSynth);
442c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
443c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* if using dynamic memory, free it */
444c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (!pEASData->staticMemoryModel)
445c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
446c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (pSMFData->streams)
447c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            EAS_HWFree(pEASData->hwInstData, pSMFData->streams);
448c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
449c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        /* free the instance data */
450c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        EAS_HWFree(pEASData->hwInstData, pSMFData);
451c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
452c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
453c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    return EAS_SUCCESS;
454c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
455c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
45604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt/*----------------------------------------------------------------------------
45704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt * SMF_Reset()
458c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
459c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Purpose:
460c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Reset the sequencer. Used for locating backwards in the file.
461c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
462c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Inputs:
463c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
464c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * handle           - pointer to file handle
465c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
466c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Outputs:
467c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *
46850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
46950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Side Effects:
47050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
471c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt *----------------------------------------------------------------------------
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_Reset (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    S_SMF_DATA* pSMFData;
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_I32 i;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_RESULT result;
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 ticks;
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
482df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt    /* reset time to zero */
483df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt    pSMFData->time = 0;
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
485df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt    /* reset the synth */
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    VMReset(pEASData->pVoiceMgr, pSMFData->pSynth, EAS_TRUE);
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* find the start of each track */
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ticks = 0x7fffffffL;
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->nextStream = NULL;
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (i = 0; i < pSMFData->numStreams; i++)
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* reset file position to first byte of data in track */
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFData->streams[i].fileHandle, pSMFData->streams[i].startFilePos)) != EAS_SUCCESS)
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* initalize some data */
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData->streams[i].ticks = 0;
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* initalize the MIDI parser data */
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* parse the first delta time in each stream */
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = SMF_GetDeltaTime(pEASData->hwInstData,&pSMFData->streams[i])) != EAS_SUCCESS)
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (pSMFData->streams[i].ticks < ticks)
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        {
50950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            ticks = pSMFData->streams[i].ticks;
51050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            pSMFData->nextStream = &pSMFData->streams[i];
51150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        }
51250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
51350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
51450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
51550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    pSMFData->state = EAS_STATE_READY;
51650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    return EAS_SUCCESS;
51750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt}
51850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
51950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*----------------------------------------------------------------------------
52050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * SMF_Pause()
52150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
52250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Purpose:
52350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Pauses the sequencer. Mutes all voices and sets state to pause.
52450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
52550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Inputs:
52650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
527c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * handle           - pointer to file handle
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_Pause (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    S_SMF_DATA *pSMFData;
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* can't pause a stopped stream */
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pSMFData->state == EAS_STATE_STOPPED)
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return EAS_ERROR_ALREADY_STOPPED;
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* mute the synthesizer */
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    VMMuteAllVoices(pEASData->pVoiceMgr, pSMFData->pSynth);
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->state = EAS_STATE_PAUSING;
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_Resume()
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Resume playing after a pause, sets state back to playing.
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle           - pointer to file handle
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*lint -esym(715, pEASData) reserved for future use */
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_Resume (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData)
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    S_SMF_DATA *pSMFData;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* can't resume a stopped stream */
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pSMFData->state == EAS_STATE_STOPPED)
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return EAS_ERROR_ALREADY_STOPPED;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* nothing to do but resume playback */
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->state = EAS_STATE_PLAY;
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_SetData()
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
586df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt * Purpose:
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Sets parser parameters
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle           - pointer to file handle
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*lint -esym(715, pEASData) reserved for future use */
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_SetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 value)
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    S_SMF_DATA *pSMFData;
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    switch (param)
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* set metadata callback */
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_METADATA_CB:
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            EAS_HWMemCpy(&pSMFData->metadata, (void*) value, sizeof(S_METADATA_CB));
612fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt            break;
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef JET_INTERFACE
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* set jet segment and track ID of all tracks for callback function */
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_JET_CB:
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                EAS_U32 i;
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                EAS_U32 bit = (EAS_U32) value;
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                bit = (bit << JET_EVENT_SEG_SHIFT) & JET_EVENT_SEG_MASK;
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                for (i = 0; i < pSMFData->numStreams; i++)
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                    pSMFData->streams[i].midiStream.jetData =
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                        (pSMFData->streams[i].midiStream.jetData &
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                        ~(JET_EVENT_TRACK_MASK | JET_EVENT_SEG_MASK)) |
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                        i << JET_EVENT_TRACK_SHIFT | bit | MIDI_FLAGS_JET_CB;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                pSMFData->flags |= SMF_FLAGS_JET_STREAM;
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* set state of all mute flags at once */
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_MUTE_FLAGS:
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            {
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                EAS_INT i;
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                EAS_U32 bit = (EAS_U32) value;
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                for (i = 0; i < pSMFData->numStreams; i++)
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                {
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                    if (bit & 1)
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                        pSMFData->streams[i].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                    else
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                        pSMFData->streams[i].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                    bit >>= 1;
642fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt                }
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            }
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* set track mute */
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_SET_MUTE:
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (value < pSMFData->numStreams)
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                pSMFData->streams[value].midiStream.jetData |= MIDI_FLAGS_JET_MUTE;
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                return EAS_ERROR_PARAMETER_RANGE;
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* clear track mute */
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_CLEAR_MUTE:
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (value < pSMFData->numStreams)
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                pSMFData->streams[value].midiStream.jetData &= ~MIDI_FLAGS_JET_MUTE;
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            else
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                return EAS_ERROR_PARAMETER_RANGE;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        default:
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return EAS_ERROR_INVALID_PARAMETER;
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_GetData()
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Retrieves parser parameters
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handle           - pointer to file handle
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
6844b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt *
6854b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt *----------------------------------------------------------------------------
686fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt*/
6874b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt/*lint -esym(715, pEASData) reserved for future use */
6884b9d52f502481b258fec743c03a5e957e5605afcDmitry ShmidtEAS_RESULT SMF_GetData (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I32 param, EAS_I32 *pValue)
6894b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt{
690fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    S_SMF_DATA *pSMFData;
6914b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt
692fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    pSMFData = (S_SMF_DATA*) pInstData;
6934b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt    switch (param)
6944b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt    {
6954b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt        /* return file type */
6964b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt        case PARSER_DATA_FILE_TYPE:
6974b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt            if (pSMFData->numStreams == 1)
6984b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt                *pValue = EAS_FILE_SMF0;
6994b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt            else
7004b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt                *pValue = EAS_FILE_SMF1;
701fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt            break;
702fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt
7034b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt/* now handled in eas_public.c */
7044b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt#if 0
7054b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt        case PARSER_DATA_POLYPHONY:
7064b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt            if (pSMFData->pSynth)
7074b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt                VMGetPolyphony(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
7084b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt            else
7094b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt                return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
7104b9d52f502481b258fec743c03a5e957e5605afcDmitry Shmidt            break;
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_PRIORITY:
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if (pSMFData->pSynth)
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                VMGetPriority(pEASData->pVoiceMgr, pSMFData->pSynth, pValue);
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* set transposition */
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_TRANSPOSITION:
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            *pValue = pSMFData->transposition;
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        case PARSER_DATA_SYNTH_HANDLE:
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            *pValue = (EAS_I32) pSMFData->pSynth;
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            break;
7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
727e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt        default:
728e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt            return EAS_ERROR_INVALID_PARAMETER;
729e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    }
730e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
731fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    return EAS_SUCCESS;
732e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt}
733e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
734e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt/*----------------------------------------------------------------------------
735e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * SMF_GetVarLenData()
736e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *----------------------------------------------------------------------------
737e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * Purpose:
738e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * Reads a varible length quantity from an SMF file
739e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *
740fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt * Inputs:
741fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt *
742fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt *
743e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * Outputs:
744e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *
745e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *
746e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt * Side Effects:
747e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *
748e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt *----------------------------------------------------------------------------
749e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt*/
750e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtstatic EAS_RESULT SMF_GetVarLenData (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_U32 *pData)
751fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt{
752e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    EAS_RESULT result;
753e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    EAS_U32 data;
754e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    EAS_U8 c;
755fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt
756e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    /* read until bit 7 is zero */
757e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    data = 0;
758e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt    do
7595460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt    {
7605460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt        if ((result = EAS_HWGetByte(hwInstData, fileHandle,&c)) != EAS_SUCCESS)
7615460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt            return result;
7625460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt        data = (data << 7) | (c & 0x7f);
763fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    } while (c & 0x80);
7645460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt    *pData = data;
7655460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt    return EAS_SUCCESS;
7665460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt}
7675460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
7685460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt/*----------------------------------------------------------------------------
7695460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * SMF_GetDeltaTime()
7705460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *----------------------------------------------------------------------------
7715460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Purpose:
772fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt * Reads a varible length quantity from an SMF file
773fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt *
774fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt * Inputs:
7755460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *
7765460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *
7775460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Outputs:
7785460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *
7795460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *
7805460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt * Side Effects:
7815460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *
7825460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt *----------------------------------------------------------------------------
783fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt*/
7845460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidtstatic EAS_RESULT SMF_GetDeltaTime (EAS_HW_DATA_HANDLE hwInstData, S_SMF_STREAM *pSMFStream)
7855460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt{
7865460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt    EAS_RESULT result;
787fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt    EAS_U32 ticks;
7885460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt
7895460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt    if ((result = SMF_GetVarLenData(hwInstData, pSMFStream->fileHandle, &ticks)) != EAS_SUCCESS)
7905460547a121207cf7a99eac45e05fcdd83be3161Dmitry Shmidt        return result;
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFStream->ticks += ticks;
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*----------------------------------------------------------------------------
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_ParseMetaEvent()
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reads a varible length quantity from an SMF file
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outputs:
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_ParseMetaEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream)
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_RESULT result;
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 len;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_I32 pos;
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 temp;
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U8 c;
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get the meta-event type */
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get the length */
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get the current file position so we can skip the event */
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWFilePos(pEASData->hwInstData, pSMFStream->fileHandle, &pos)) != EAS_SUCCESS)
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pos += (EAS_I32) len;
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* end of track? */
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (c == SMF_META_END_OF_TRACK)
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: end of track\n", c, len); */ }
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFStream->ticks = SMF_END_OF_TRACK;
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* tempo event? */
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else if (c == SMF_META_TEMPO)
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* read the 3-byte timebase value */
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        temp = 0;
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        while (len--)
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        {
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                return result;
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            temp = (temp << 8) | c;
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        }
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData->tickConv = (EAS_U16) (((temp * 1024) / pSMFData->ppqn + 500) / 1000);
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        pSMFData->flags |= SMF_FLAGS_HAS_TEMPO;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* check for time signature - see iMelody spec V1.4 section 4.1.2.2.3.6 */
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else if (c == SMF_META_TIME_SIGNATURE)
85861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt    {
85961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt        pSMFData->flags |= SMF_FLAGS_HAS_TIME_SIG;
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* if the host has registered a metadata callback return the metadata */
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else if (pSMFData->metadata.callback)
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        EAS_I32 readLen;
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        E_EAS_METADATA_TYPE metaType;
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        metaType = EAS_METADATA_UNKNOWN;
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* only process title on the first track */
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (c == SMF_META_SEQTRK_NAME)
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            metaType = EAS_METADATA_TITLE;
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        else if (c == SMF_META_TEXT)
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            metaType = EAS_METADATA_TEXT;
8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        else if (c == SMF_META_COPYRIGHT)
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            metaType = EAS_METADATA_COPYRIGHT;
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        else if (c == SMF_META_LYRIC)
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            metaType = EAS_METADATA_LYRIC;
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if (metaType != EAS_METADATA_UNKNOWN)
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        {
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            readLen = pSMFData->metadata.bufferSize - 1;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if ((EAS_I32) len < readLen)
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                readLen = (EAS_I32) len;
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if ((result = EAS_HWReadFile(pEASData->hwInstData, pSMFStream->fileHandle, pSMFData->metadata.buffer, readLen, &readLen)) != EAS_SUCCESS)
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                return result;
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            pSMFData->metadata.buffer[readLen] = 0;
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            pSMFData->metadata.callback(metaType, pSMFData->metadata.buffer, pSMFData->metadata.pUserData);
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        }
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* position file to next event - in case we ignored all or part of the meta-event */
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWFileSeek(pEASData->hwInstData, pSMFStream->fileHandle, pos)) != EAS_SUCCESS)
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Meta-event: type=%02x, len=%d\n", c, len); */ }
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
898c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
899c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
900c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt/*----------------------------------------------------------------------------
90150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * SMF_ParseSysEx()
90250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reads a varible length quantity from an SMF file
90550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
90650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Inputs:
90750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
90850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
909c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * Outputs:
910fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt *
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
91250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Side Effects:
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic EAS_RESULT SMF_ParseSysEx (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_U8 f0, EAS_INT parserMode)
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
91850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_RESULT result;
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 len;
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U8 c;
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get the length */
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = SMF_GetVarLenData(pEASData->hwInstData, pSMFStream->fileHandle, &len)) != EAS_SUCCESS)
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return result;
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* start of SysEx message? */
927fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    if (f0 == 0xf0)
928fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt    {
929fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt        if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, f0, parserMode)) != EAS_SUCCESS)
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
93250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
933c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* feed the SysEx to the stream parser */
93450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    while (len--)
93550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    {
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
93850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
941c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        /* check for GM system ON */
942c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        if (pSMFStream->midiStream.flags & MIDI_FLAG_GM_ON)
943c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            pSMFData->flags |= SMF_FLAGS_HAS_GM_ON;
944c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    }
945c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
946c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    return EAS_SUCCESS;
947c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt}
94850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
94950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*----------------------------------------------------------------------------
9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SMF_ParseEvent()
9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
9528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Reads a varible length quantity from an SMF file
9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
95550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Inputs:
95650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
95750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
95850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Outputs:
95950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
96050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
96150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt * Side Effects:
96250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *
96350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt *----------------------------------------------------------------------------
9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
96550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidtstatic EAS_RESULT SMF_ParseEvent (S_EAS_DATA *pEASData, S_SMF_DATA *pSMFData, S_SMF_STREAM *pSMFStream, EAS_INT parserMode)
96650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt{
96750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_RESULT result;
96850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    EAS_U8 c;
96950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
97050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* get the event type */
97150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
97250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        return result;
97350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
97450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* parse meta-event */
97550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if (c == 0xff)
9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = SMF_ParseMetaEvent(pEASData, pSMFData, pSMFStream)) != EAS_SUCCESS)
9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
9808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* parse SysEx */
9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else if ((c == 0xf0) || (c == 0xf7))
9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
984fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt        if ((result = SMF_ParseSysEx(pEASData, pSMFData, pSMFStream, c, parserMode)) != EAS_SUCCESS)
985fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt            return result;
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* parse MIDI message */
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    else
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            return result;
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* keep streaming data to the MIDI parser until the message is complete */
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        while (pSMFStream->midiStream.pending)
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        {
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt            if ((result = EAS_HWGetByte(pEASData->hwInstData, pSMFStream->fileHandle, &c)) != EAS_SUCCESS)
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt                return result;
999c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt            if ((result = EAS_ParseMIDIStream(pEASData, pSMFData->pSynth, &pSMFStream->midiStream, c, parserMode)) != EAS_SUCCESS)
1000c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt                return result;
1001c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        }
1002c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
100350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
100450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* chase mode logic */
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if (pSMFData->time == 0)
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
100850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
100950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        {
101050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            if (pSMFStream->midiStream.flags & MIDI_FLAG_FIRST_NOTE)
101150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt                pSMFData->flags &= ~SMF_FLAGS_CHASE_MODE;
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        }
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        else if ((pSMFData->flags & SMF_FLAGS_SETUP_BAR) == SMF_FLAGS_SETUP_BAR)
1014ea69e84a6f4455c59348485895d3d5e3af77a65bDmitry Shmidt            pSMFData->flags = (pSMFData->flags & ~SMF_FLAGS_SETUP_BAR) | SMF_FLAGS_CHASE_MODE;
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
101650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    return EAS_SUCCESS;
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
102050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt/*----------------------------------------------------------------------------
1021c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * SMF_ParseHeader()
10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Purpose:
10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Parses the header of an SMF file, allocates memory the stream parsers and initializes the
10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * stream parsers.
10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Inputs:
10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pEASData         - pointer to overall EAS data structure
10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * pSMFData         - pointer to parser instance data
10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fileHandle       - file handle
10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * fileOffset       - offset in the file where the header data starts, usually 0
10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1034fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt * Outputs:
10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
1036fa3fc4a1ac08ad14272301c7f6f01b362997c3e4Dmitry Shmidt *
10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Side Effects:
10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *----------------------------------------------------------------------------
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt*/
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*lint -e{801} we know that 'goto' is deprecated - but it's cleaner in this case */
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtEAS_RESULT SMF_ParseHeader (EAS_HW_DATA_HANDLE hwInstData, S_SMF_DATA *pSMFData)
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_RESULT result;
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_I32 i;
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U16 division;
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 chunkSize;
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 chunkStart;
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 temp;
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    EAS_U32 ticks;
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* rewind the file and find the end of the header chunk */
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_HEADER_SIZE)) != EAS_SUCCESS)
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        goto ReadError;
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        goto ReadError;
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* determine the number of tracks */
1059c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, pSMFData->fileOffset + SMF_OFS_NUM_TRACKS)) != EAS_SUCCESS)
1060c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        goto ReadError;
1061c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &pSMFData->numStreams, EAS_TRUE)) != EAS_SUCCESS)
1062c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        goto ReadError;
1063c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
106450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    /* limit the number of tracks */
106550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    if (pSMFData->numStreams > MAX_SMF_STREAMS)
106650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    {
106750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "SMF file contains %u tracks, playing %d tracks\n", pSMFData->numStreams, MAX_SMF_STREAMS); */ }
106850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        pSMFData->numStreams = MAX_SMF_STREAMS;
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    } else if (pSMFData->numStreams == 0)
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        /* avoid 0 sized allocation */
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        return EAS_ERROR_PARAMETER_RANGE;
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    }
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* get the time division */
10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    if ((result = EAS_HWGetWord(hwInstData, pSMFData->fileHandle, &division, EAS_TRUE)) != EAS_SUCCESS)
10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        goto ReadError;
10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* setup default timebase for 120 bpm */
1080c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData->ppqn = 192;
1081c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (!division || division & 0x8000)
1082c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"No support for SMPTE code timebase\n"); */ }
1083c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    else
1084c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        pSMFData->ppqn = (division & 0x7fff);
1085c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    pSMFData->tickConv = (EAS_U16) (((SMF_DEFAULT_TIMEBASE * 1024) / pSMFData->ppqn + 500) / 1000);
1086c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt
1087c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    /* dynamic memory allocation, allocate memory for streams */
1088c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    if (pSMFData->streams == NULL)
1089c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt    {
1090c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt        pSMFData->streams = EAS_HWMalloc(hwInstData,sizeof(S_SMF_STREAM) * pSMFData->numStreams);
109150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        if (pSMFData->streams == NULL)
109250b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            return EAS_ERROR_MALLOC_FAILED;
109350b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
109450b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        /* zero the memory to insure complete initialization */
109550b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        EAS_HWMemSet((void *)(pSMFData->streams), 0, sizeof(S_SMF_STREAM) * pSMFData->numStreams);
109650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt    }
109750b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    /* find the start of each track */
10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    chunkStart = (EAS_U32) pSMFData->fileOffset;
11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    ticks = 0x7fffffffL;
11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    pSMFData->nextStream = NULL;
11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    for (i = 0; i < pSMFData->numStreams; i++)
11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt    {
11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt        for (;;)
110650b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt        {
11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
110850b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            /* calculate start of next chunk - checking for errors */
110950b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            temp = chunkStart + SMF_CHUNK_INFO_SIZE + chunkSize;
111050b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            if (temp <= chunkStart)
111150b691dc36a8075e8f594e8bea93cb524fa6b1d2Dmitry Shmidt            {
1112                { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Error in chunk size at offset %d\n", chunkStart); */ }
1113                return EAS_ERROR_FILE_FORMAT;
1114            }
1115            chunkStart = temp;
1116
1117            /* seek to the start of the next chunk */
1118            if ((result = EAS_HWFileSeek(hwInstData, pSMFData->fileHandle, (EAS_I32) chunkStart)) != EAS_SUCCESS)
1119                goto ReadError;
1120
1121            /* read the chunk identifier */
1122            if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &temp, EAS_TRUE)) != EAS_SUCCESS)
1123                goto ReadError;
1124
1125            /* read the chunk size */
1126            if ((result = EAS_HWGetDWord(hwInstData, pSMFData->fileHandle, &chunkSize, EAS_TRUE)) != EAS_SUCCESS)
1127                goto ReadError;
1128
1129            /* make sure this is an 'MTrk' chunk */
1130            if (temp == SMF_CHUNK_TYPE_TRACK)
1131                break;
1132
1133            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING,"Unexpected chunk type: 0x%08x\n", temp); */ }
1134        }
1135
1136        /* initalize some data */
1137        pSMFData->streams[i].ticks = 0;
1138        pSMFData->streams[i].fileHandle = pSMFData->fileHandle;
1139
1140        /* NULL the file handle so we don't try to close it twice */
1141        pSMFData->fileHandle = NULL;
1142
1143        /* save this file position as the start of the track */
1144        pSMFData->streams[i].startFilePos = (EAS_I32) chunkStart + SMF_CHUNK_INFO_SIZE;
1145
1146        /* initalize the MIDI parser data */
1147        EAS_InitMIDIStream(&pSMFData->streams[i].midiStream);
1148
1149        /* parse the first delta time in each stream */
1150        if ((result = SMF_GetDeltaTime(hwInstData, &pSMFData->streams[i])) != EAS_SUCCESS)
1151                goto ReadError;
1152
1153        if (pSMFData->streams[i].ticks < ticks)
1154        {
1155            ticks = pSMFData->streams[i].ticks;
1156            pSMFData->nextStream = &pSMFData->streams[i];
1157        }
1158
1159        /* more tracks to do, create a duplicate file handle */
1160        if (i < (pSMFData->numStreams - 1))
1161        {
1162            if ((result = EAS_HWDupHandle(hwInstData, pSMFData->streams[i].fileHandle, &pSMFData->fileHandle)) != EAS_SUCCESS)
1163                goto ReadError;
1164        }
1165    }
1166
1167    /* update the time of the next event */
1168    if (pSMFData->nextStream)
1169        SMF_UpdateTime(pSMFData, pSMFData->nextStream->ticks);
1170
1171    return EAS_SUCCESS;
1172
1173    /* ugly goto: but simpler than structured */
1174    ReadError:
1175        if (result == EAS_EOF)
1176            return EAS_ERROR_FILE_FORMAT;
1177        return result;
1178}
1179
1180/*----------------------------------------------------------------------------
1181 * SMF_UpdateTime()
1182 *----------------------------------------------------------------------------
1183 * Purpose:
1184 * Update the millisecond time base by converting the ticks into millieconds
1185 *
1186 * Inputs:
1187 *
1188 *
1189 * Outputs:
1190 *
1191 *
1192 * Side Effects:
1193 *
1194 *----------------------------------------------------------------------------
1195*/
1196static void SMF_UpdateTime (S_SMF_DATA *pSMFData, EAS_U32 ticks)
1197{
1198    EAS_U32 temp1, temp2;
1199
1200    if (pSMFData->flags & SMF_FLAGS_CHASE_MODE)
1201        return;
1202
1203    temp1 = (ticks >> 10) * pSMFData->tickConv;
1204    temp2 = (ticks & 0x3ff) * pSMFData->tickConv;
1205    pSMFData->time += (EAS_I32)((temp1 << 8) + (temp2 >> 2));
1206}
1207
1208