Home | History | Annotate | Download | only in lib_src
      1 /*----------------------------------------------------------------------------
      2  *
      3  * File:
      4  * jet.c
      5  *
      6  * Contents and purpose:
      7  * Implementation for JET sound engine
      8  *
      9  * Copyright (c) 2006 Sonic Network Inc.
     10 
     11  * Licensed under the Apache License, Version 2.0 (the "License");
     12  * you may not use this file except in compliance with the License.
     13  * You may obtain a copy of the License at
     14  *
     15  *      http://www.apache.org/licenses/LICENSE-2.0
     16  *
     17  * Unless required by applicable law or agreed to in writing, software
     18  * distributed under the License is distributed on an "AS IS" BASIS,
     19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     20  * See the License for the specific language governing permissions and
     21  * limitations under the License.
     22  *----------------------------------------------------------------------------
     23  * Revision Control:
     24  *   $Revision: 563 $
     25  *   $Date: 2007-02-13 20:26:23 -0800 (Tue, 13 Feb 2007) $
     26  *----------------------------------------------------------------------------
     27 */
     28 
     29 //#define LOG_NDEBUG 0
     30 #define LOG_TAG "JET_C"
     31 
     32 //#define DEBUG_JET
     33 
     34 #include "eas_data.h"
     35 #include "eas_smf.h"
     36 #include "jet_data.h"
     37 #include "eas_host.h"
     38 #include "eas_report.h"
     39 
     40 
     41 /* default configuration */
     42 static const S_JET_CONFIG jetDefaultConfig =
     43 {
     44     JET_EVENT_APP_LOW,
     45     JET_EVENT_APP_HIGH
     46 };
     47 
     48 /* function prototypes */
     49 extern EAS_RESULT EAS_IntSetStrmParam (S_EAS_DATA *pEASData, EAS_HANDLE pStream, EAS_INT param, EAS_I32 value);
     50 extern EAS_RESULT EAS_OpenJETStream (EAS_DATA_HANDLE pEASData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_HANDLE *ppStream);
     51 extern EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS);
     52 
     53 /*----------------------------------------------------------------------------
     54  * JET_ParseEvent()
     55  *----------------------------------------------------------------------------
     56  * Returns current status
     57  *----------------------------------------------------------------------------
     58 */
     59 EAS_PUBLIC void JET_ParseEvent (EAS_U32 event, S_JET_EVENT *pEvent)
     60 {
     61     pEvent->segment = (EAS_U8) ((event & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT);
     62     pEvent->track = (EAS_U8) ((event & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
     63     pEvent->channel = (EAS_U8) ((event & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT);
     64     pEvent->controller = (EAS_U8) ((event & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT);
     65     pEvent->value = (EAS_U8) (event & JET_EVENT_VAL_MASK);
     66 }
     67 
     68 #ifdef DEBUG_JET
     69 /*----------------------------------------------------------------------------
     70  * JET_DumpEvent
     71  *----------------------------------------------------------------------------
     72  * Advances queue read/write index
     73  *----------------------------------------------------------------------------
     74 */
     75 static void JET_DumpEvent (const char *procName, EAS_U32 event)
     76 {
     77     S_JET_EVENT sEvent;
     78     JET_ParseEvent(event, &sEvent);
     79     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "%s: SegID=%d, TrkID=%d, channel=%d, ctrl=%d, val=%d\n",
     80         procName, sEvent.segment, sEvent.track, sEvent.channel, sEvent.controller, sEvent.value); */ }
     81 }
     82 #endif
     83 
     84 /*----------------------------------------------------------------------------
     85  * JET_IncQueueIndex
     86  *----------------------------------------------------------------------------
     87  * Advances queue read/write index
     88  *----------------------------------------------------------------------------
     89 */
     90 EAS_INLINE EAS_U8 JET_IncQueueIndex (EAS_U8 index, EAS_U8 queueSize)
     91 {
     92     if (++index == queueSize)
     93         index = 0;
     94     return index;
     95 }
     96 
     97 /*----------------------------------------------------------------------------
     98  * JET_WriteQueue
     99  *----------------------------------------------------------------------------
    100  * Save event to queue
    101  *----------------------------------------------------------------------------
    102 */
    103 EAS_INLINE void JET_WriteQueue (EAS_U32 *pEventQueue, EAS_U8 *pWriteIndex, EAS_U8 readIndex, EAS_U8 queueSize, EAS_U32 event)
    104 {
    105     EAS_U8 temp;
    106 
    107     /* check for queue overflow */
    108     temp = JET_IncQueueIndex(*pWriteIndex, queueSize);
    109     if (temp == readIndex)
    110     {
    111         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "JET_Event: Event queue overflow --- event ignored!\n"); */ }
    112         return;
    113     }
    114 
    115     /* save in queue and advance write index */
    116     pEventQueue[*pWriteIndex] = event;
    117     *pWriteIndex = temp;
    118 }
    119 
    120 /*----------------------------------------------------------------------------
    121  * JET_ReadQueue
    122  *----------------------------------------------------------------------------
    123  * Read event to queue
    124  *----------------------------------------------------------------------------
    125 */
    126 EAS_INLINE EAS_BOOL JET_ReadQueue (EAS_U32 *pEventQueue, EAS_U8 *pReadIndex, EAS_U8 writeIndex, EAS_U8 queueSize, EAS_U32 *pEvent)
    127 {
    128 
    129     /* check for empty queue */
    130     if (*pReadIndex == writeIndex)
    131         return EAS_FALSE;
    132 
    133     /* save in queue and advance write index */
    134     *pEvent = pEventQueue[*pReadIndex];
    135     *pReadIndex = JET_IncQueueIndex(*pReadIndex, queueSize);
    136     return EAS_TRUE;
    137 }
    138 
    139 /*----------------------------------------------------------------------------
    140  * JET_NextSegment
    141  *----------------------------------------------------------------------------
    142  * Advances segment number
    143  *----------------------------------------------------------------------------
    144 */
    145 EAS_INLINE EAS_INT JET_NextSegment (EAS_INT seg_num)
    146 {
    147     if (++seg_num == SEG_QUEUE_DEPTH)
    148         seg_num = 0;
    149     return seg_num;
    150 }
    151 
    152 /*----------------------------------------------------------------------------
    153  * JET_PrepareSegment()
    154  *----------------------------------------------------------------------------
    155  * Prepare a segment for playback
    156  *----------------------------------------------------------------------------
    157 */
    158 static EAS_RESULT JET_PrepareSegment (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
    159 {
    160     EAS_RESULT result;
    161     S_JET_SEGMENT *p;
    162 
    163     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_PrepareSegment: %d\n", queueNum); */ }
    164 
    165     p = &easHandle->jetHandle->segQueue[queueNum];
    166     result = EAS_Prepare(easHandle, p->streamHandle);
    167     if (result != EAS_SUCCESS)
    168         return result;
    169 
    170     /* pause segment - must be triggered by play or end of previous segment */
    171     result = EAS_Pause(easHandle, p->streamHandle);
    172     if (result != EAS_SUCCESS)
    173         return result;
    174     p->state = JET_STATE_READY;
    175 
    176     /* set calback data */
    177     result = EAS_IntSetStrmParam(easHandle, p->streamHandle, PARSER_DATA_JET_CB, queueNum);
    178     if (result != EAS_SUCCESS)
    179         return result;
    180 
    181     /* set DLS collection */
    182     if (p->libNum >= 0)
    183     {
    184         result = EAS_IntSetStrmParam(easHandle, p->streamHandle,
    185             PARSER_DATA_DLS_COLLECTION, (EAS_I32) easHandle->jetHandle->libHandles[p->libNum]);
    186         if (result != EAS_SUCCESS)
    187             return result;
    188     }
    189 
    190     /* set transposition */
    191     if (p->transpose)
    192     {
    193         result = EAS_SetTransposition(easHandle, p->streamHandle, p->transpose);
    194         if (result != EAS_SUCCESS)
    195             return result;
    196     }
    197 
    198     return result;
    199 }
    200 
    201 /*----------------------------------------------------------------------------
    202  * JET_StartPlayback()
    203  *----------------------------------------------------------------------------
    204  * Start segment playback
    205  *----------------------------------------------------------------------------
    206 */
    207 static EAS_RESULT JET_StartPlayback (EAS_DATA_HANDLE easHandle, EAS_I32 queueNum)
    208 {
    209     EAS_RESULT result = EAS_SUCCESS;
    210     S_JET_SEGMENT *pSeg;
    211 
    212     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_StartPlayback %d\n", queueNum); */ }
    213 
    214     /* if next segment is queued, start playback */
    215     pSeg = &easHandle->jetHandle->segQueue[queueNum];
    216     if (pSeg->streamHandle != NULL)
    217     {
    218         result = EAS_Resume(easHandle, pSeg->streamHandle);
    219         easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_PLAYING;
    220 
    221         /* set mute flags */
    222         if ((result == EAS_SUCCESS) && (pSeg->muteFlags != 0))
    223             result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
    224     }
    225     return result;
    226 }
    227 
    228 /*----------------------------------------------------------------------------
    229  * JET_CloseSegment
    230  *----------------------------------------------------------------------------
    231  * Closes stream associated with a segment
    232  *----------------------------------------------------------------------------
    233 */
    234 EAS_INLINE EAS_INT JET_CloseSegment (EAS_DATA_HANDLE easHandle, EAS_INT queueNum)
    235 {
    236     EAS_RESULT result;
    237 
    238     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_CloseSegment %d\n", queueNum); */ }
    239 
    240     /* close the segment */
    241     result = EAS_CloseFile(easHandle, easHandle->jetHandle->segQueue[queueNum].streamHandle);
    242     if (result != EAS_SUCCESS)
    243         return result;
    244 
    245     easHandle->jetHandle->segQueue[queueNum].streamHandle = NULL;
    246     easHandle->jetHandle->segQueue[queueNum].state = JET_STATE_CLOSED;
    247     easHandle->jetHandle->numQueuedSegments--;
    248     return result;
    249 }
    250 
    251 /*----------------------------------------------------------------------------
    252  * JetParseInfoChunk()
    253  *----------------------------------------------------------------------------
    254  * Parses the JET info chunk
    255  *----------------------------------------------------------------------------
    256 */
    257 static EAS_RESULT JetParseInfoChunk (EAS_DATA_HANDLE easHandle, EAS_I32 pos, EAS_I32 chunkSize)
    258 {
    259     EAS_RESULT result;
    260     EAS_U32 infoType;
    261     EAS_U32 temp;
    262 
    263     /* offset to data */
    264     result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
    265     if (result != EAS_SUCCESS)
    266         return result;
    267 
    268     /* read the entire chunk */
    269     result = EAS_SUCCESS;
    270     while ((result == EAS_SUCCESS) && (chunkSize > 0))
    271     {
    272 
    273         /* get info infoType */
    274         result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &infoType, EAS_TRUE);
    275         if (result != EAS_SUCCESS)
    276             break;
    277 
    278         /* get info field */
    279         result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &temp, EAS_FALSE);
    280         if (result == EAS_SUCCESS)
    281 
    282         switch (infoType)
    283         {
    284             case INFO_NUM_SMF_CHUNKS:
    285                 if (temp >= JET_MAX_SEGMENTS) {
    286                     return EAS_ERROR_INCOMPATIBLE_VERSION;
    287                 }
    288                 easHandle->jetHandle->numSegments = (EAS_U8) temp;
    289                 break;
    290 
    291             case INFO_NUM_DLS_CHUNKS:
    292                 if (temp >= JET_MAX_DLS_COLLECTIONS) {
    293                     return EAS_ERROR_INCOMPATIBLE_VERSION;
    294                 }
    295                 easHandle->jetHandle->numLibraries = (EAS_U8) temp;
    296                 break;
    297 
    298             case INFO_JET_VERSION:
    299                 /* check major version number */
    300                 if ((temp & 0xff000000) != (JET_VERSION & 0xff000000))
    301                     return EAS_ERROR_INCOMPATIBLE_VERSION;
    302                 break;
    303 
    304             default:
    305                 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET info type 0x%08x", infoType); */ }
    306                 break;
    307         }
    308 
    309         chunkSize -= 8;
    310     }
    311 
    312     /* allocate pointers for chunks to follow */
    313 
    314     return result;
    315 }
    316 
    317 /*----------------------------------------------------------------------------
    318  * JET_OpenFile()
    319  *----------------------------------------------------------------------------
    320  * Opens a JET content file for playback
    321  *----------------------------------------------------------------------------
    322 */
    323 EAS_PUBLIC EAS_RESULT JET_OpenFile (EAS_DATA_HANDLE easHandle, EAS_FILE_LOCATOR locator)
    324 {
    325     EAS_RESULT result;
    326     EAS_U32 chunkType;
    327     EAS_I32 pos;
    328     EAS_I32 chunkSize;
    329     EAS_INT smfChunkNum;
    330     EAS_INT dlsChunkNum;
    331     EAS_I32 dataSize = 0; /* make lint happy */
    332 
    333     /* make sure that we don't have an open file */
    334     if (easHandle->jetHandle->jetFileHandle != NULL)
    335         return EAS_ERROR_FILE_ALREADY_OPEN;
    336 
    337     /* open the media file */
    338     result = EAS_HWOpenFile(easHandle->hwInstData, locator, &easHandle->jetHandle->jetFileHandle, EAS_FILE_READ);
    339     if (result != EAS_SUCCESS)
    340         return result;
    341 
    342     /* check header */
    343     result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
    344     if (result == EAS_SUCCESS)
    345     {
    346         if (chunkType != JET_HEADER_TAG)
    347         {
    348             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "File is not JET format\n"); */ }
    349             result = EAS_ERROR_UNRECOGNIZED_FORMAT;
    350         }
    351     }
    352     /* get the file data size */
    353     if (result == EAS_SUCCESS)
    354         result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &dataSize, EAS_FALSE);
    355 
    356     /* parse through the file to find contents */
    357     smfChunkNum = dlsChunkNum = 0;
    358     pos = chunkSize = 8;
    359     while ((result == EAS_SUCCESS) && (pos < dataSize))
    360     {
    361 
    362         /* offset to chunk data */
    363         result = EAS_HWFileSeek(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos);
    364         if (result != EAS_SUCCESS)
    365             break;
    366 
    367         /* get chunk size and type */
    368         result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkType, EAS_TRUE);
    369         if (result != EAS_SUCCESS)
    370             break;
    371 
    372         result = EAS_HWGetDWord(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &chunkSize, EAS_FALSE);
    373         if (result != EAS_SUCCESS)
    374             break;
    375         pos += 8;
    376 
    377         switch (chunkType)
    378         {
    379             case JET_INFO_CHUNK:
    380                 result = JetParseInfoChunk(easHandle, pos, chunkSize);
    381                 break;
    382 
    383             case JET_SMF_CHUNK:
    384                 if (smfChunkNum < easHandle->jetHandle->numSegments)
    385                     easHandle->jetHandle->segmentOffsets[smfChunkNum++] = pos;
    386                 else
    387                     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous SMF chunk"); */ }
    388                 break;
    389 
    390             case JET_DLS_CHUNK:
    391                 if (dlsChunkNum < easHandle->jetHandle->numLibraries)
    392                     result = DLSParser(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, pos, &easHandle->jetHandle->libHandles[dlsChunkNum++]);
    393                 else
    394                     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring extraneous DLS chunk"); */ }
    395                 break;
    396 
    397             case JET_APP_DATA_CHUNK:
    398                 easHandle->jetHandle->appDataOffset = pos;
    399                 easHandle->jetHandle->appDataSize = chunkSize;
    400                 break;
    401 
    402             case INFO_JET_COPYRIGHT:
    403                 break;
    404 
    405             default:
    406                 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Ignoring unrecognized JET chunk type 0x%08x", chunkType); */ }
    407                 break;
    408         }
    409 
    410         /* offset to next chunk */
    411         pos += chunkSize;
    412     }
    413 
    414     /* close file if something went wrong */
    415     if (result != EAS_SUCCESS)
    416         EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
    417 
    418     return result;
    419 }
    420 
    421 /*----------------------------------------------------------------------------
    422  * JET_GetAppData()
    423  *----------------------------------------------------------------------------
    424  * Returns location and size of application data in the JET file
    425  *----------------------------------------------------------------------------
    426 */
    427 EAS_RESULT JET_GetAppData (EAS_DATA_HANDLE easHandle, EAS_I32 *pAppDataOffset, EAS_I32 *pAppDataSize)
    428 {
    429 
    430     /* check for app chunk */
    431     if (easHandle->jetHandle->appDataSize == 0)
    432     {
    433         *pAppDataOffset = *pAppDataSize = 0;
    434         return EAS_FAILURE;
    435     }
    436 
    437     /* return app data */
    438     *pAppDataOffset = easHandle->jetHandle->appDataOffset;
    439     *pAppDataSize = easHandle->jetHandle->appDataSize;
    440     return EAS_SUCCESS;
    441 }
    442 
    443 /*----------------------------------------------------------------------------
    444  * JET_CloseFile()
    445  *----------------------------------------------------------------------------
    446  * Closes a JET content file and releases associated resources
    447  *----------------------------------------------------------------------------
    448 */
    449 EAS_PUBLIC EAS_RESULT JET_CloseFile (EAS_DATA_HANDLE easHandle)
    450 {
    451     EAS_INT index;
    452     EAS_RESULT result = EAS_SUCCESS;
    453 
    454     /* close open streams */
    455     for (index = 0; index < SEG_QUEUE_DEPTH; index++)
    456     {
    457         if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
    458         {
    459             result = JET_CloseSegment(easHandle, index);
    460             if (result != EAS_SUCCESS)
    461                 break;
    462         }
    463     }
    464 
    465     /* close the main file handle */
    466     if ((result == EAS_SUCCESS) && (easHandle->jetHandle->jetFileHandle != NULL))
    467     {
    468         result = EAS_HWCloseFile(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle);
    469         if (result == EAS_SUCCESS)
    470             easHandle->jetHandle->jetFileHandle = NULL;
    471     }
    472     return result;
    473 }
    474 
    475 /*----------------------------------------------------------------------------
    476  * JET_Init()
    477  *----------------------------------------------------------------------------
    478  * Initializes the JET library, allocates memory, etc. Call
    479  * JET_Shutdown to de-allocate memory.
    480  *----------------------------------------------------------------------------
    481 */
    482 EAS_PUBLIC EAS_RESULT JET_Init (EAS_DATA_HANDLE easHandle, const S_JET_CONFIG *pConfig, EAS_INT configSize)
    483 {
    484     S_JET_DATA *pJet;
    485     EAS_U8 flags = 0;
    486 
    487     /* sanity check */
    488     if (easHandle == NULL)
    489         return EAS_ERROR_HANDLE_INTEGRITY;
    490     if (easHandle->jetHandle != NULL)
    491         return EAS_ERROR_FEATURE_ALREADY_ACTIVE;
    492     if (pConfig == NULL)
    493         pConfig = &jetDefaultConfig;
    494 
    495     /* allocate the JET data object */
    496     pJet = EAS_HWMalloc(easHandle->hwInstData, sizeof(S_JET_DATA));
    497     if (pJet == NULL)
    498         return EAS_ERROR_MALLOC_FAILED;
    499 
    500     /* initialize JET data structure */
    501     EAS_HWMemSet(pJet, 0, sizeof(S_JET_DATA));
    502     easHandle->jetHandle = pJet;
    503     pJet->flags = flags;
    504 
    505     /* copy config data */
    506     if (configSize > (EAS_INT) sizeof(S_JET_CONFIG))
    507         configSize = sizeof(S_JET_CONFIG);
    508     EAS_HWMemCpy(&pJet->config, pConfig, configSize);
    509     return EAS_SUCCESS;
    510 }
    511 
    512 /*----------------------------------------------------------------------------
    513  * JET_Shutdown()
    514  *----------------------------------------------------------------------------
    515  * Frees any memory used by the JET library
    516  *----------------------------------------------------------------------------
    517 */
    518 EAS_PUBLIC EAS_RESULT JET_Shutdown (EAS_DATA_HANDLE easHandle)
    519 {
    520     EAS_RESULT result;
    521     int i;
    522 
    523     /* close any open files */
    524     result = JET_CloseFile(easHandle);
    525 
    526     /* free allocated data */
    527     for(i = 0 ; i < easHandle->jetHandle->numLibraries ; i++) {
    528         if(easHandle->jetHandle->libHandles[i] != NULL) {
    529             EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle->libHandles[i]);
    530             easHandle->jetHandle->libHandles[i] = NULL;
    531         }
    532     }
    533 
    534     EAS_HWFree(easHandle->hwInstData, easHandle->jetHandle);
    535     easHandle->jetHandle = NULL;
    536     return result;
    537 }
    538 
    539 /*----------------------------------------------------------------------------
    540  * JET_Status()
    541  *----------------------------------------------------------------------------
    542  * Returns current status
    543  *----------------------------------------------------------------------------
    544 */
    545 EAS_PUBLIC EAS_RESULT JET_Status (EAS_DATA_HANDLE easHandle, S_JET_STATUS *pStatus)
    546 {
    547     S_JET_SEGMENT *pSeg;
    548 
    549     pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
    550     if (pSeg->streamHandle != NULL)
    551     {
    552         pStatus->currentUserID = pSeg->userID;
    553         pStatus->segmentRepeatCount = pSeg->repeatCount;
    554     }
    555     else
    556     {
    557         pStatus->currentUserID = -1;
    558         pStatus->segmentRepeatCount = 0;
    559     }
    560 
    561     pStatus->paused = !(easHandle->jetHandle->flags & JET_FLAGS_PLAYING);
    562     pStatus->numQueuedSegments = easHandle->jetHandle->numQueuedSegments;
    563     pStatus->currentPlayingSegment = easHandle->jetHandle->playSegment;
    564     pStatus->currentQueuedSegment = easHandle->jetHandle->queueSegment;
    565     if (pSeg->streamHandle != NULL)
    566     {
    567         EAS_RESULT result;
    568         EAS_I32 location ;
    569         if ((result = EAS_GetLocation(easHandle, pSeg->streamHandle, &location)) == EAS_SUCCESS)
    570             if(location != 0)
    571             {
    572                 pStatus->location = location;
    573             }
    574     }
    575     return EAS_SUCCESS;
    576 }
    577 
    578 /*----------------------------------------------------------------------------
    579  * JET_GetEvent()
    580  *----------------------------------------------------------------------------
    581  * Checks for application events
    582  *----------------------------------------------------------------------------
    583 */
    584 EAS_PUBLIC EAS_BOOL JET_GetEvent (EAS_DATA_HANDLE easHandle, EAS_U32 *pEventRaw, S_JET_EVENT *pEvent)
    585 {
    586     EAS_U32 jetEvent;
    587     EAS_BOOL gotEvent;
    588 
    589     /* process event queue */
    590     gotEvent = JET_ReadQueue(easHandle->jetHandle->appEventQueue,
    591         &easHandle->jetHandle->appEventQueueRead,
    592         easHandle->jetHandle->appEventQueueWrite,
    593         APP_EVENT_QUEUE_SIZE, &jetEvent);
    594 
    595     if (gotEvent)
    596     {
    597         if (pEventRaw != NULL)
    598             *pEventRaw = jetEvent;
    599 
    600         if (pEvent != NULL)
    601             JET_ParseEvent(jetEvent, pEvent);
    602     }
    603 
    604     return gotEvent;
    605 }
    606 
    607 /*----------------------------------------------------------------------------
    608  * JET_QueueSegment()
    609  *----------------------------------------------------------------------------
    610  * Queue a segment for playback
    611  *----------------------------------------------------------------------------
    612 */
    613 EAS_PUBLIC EAS_RESULT JET_QueueSegment (EAS_DATA_HANDLE easHandle, EAS_INT segmentNum, EAS_INT libNum, EAS_INT repeatCount, EAS_INT transpose, EAS_U32 muteFlags, EAS_U8 userID)
    614 {
    615     EAS_FILE_HANDLE fileHandle;
    616     EAS_RESULT result;
    617     S_JET_SEGMENT *p;
    618 
    619     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_QueueSegment segNum=%d, queue=%d\n", segmentNum, easHandle->jetHandle->queueSegment); */ }
    620 
    621     /* make sure it's a valid segment */
    622     if (segmentNum >= easHandle->jetHandle->numSegments)
    623         return EAS_ERROR_PARAMETER_RANGE;
    624 
    625     /* make sure it's a valid DLS */
    626     if (libNum >= easHandle->jetHandle->numLibraries)
    627         return EAS_ERROR_PARAMETER_RANGE;
    628 
    629     /* check to see if queue is full */
    630     p = &easHandle->jetHandle->segQueue[easHandle->jetHandle->queueSegment];
    631     if (p->streamHandle != NULL)
    632         return EAS_ERROR_QUEUE_IS_FULL;
    633 
    634     /* initialize data */
    635     p->userID = userID;
    636     p->repeatCount = (EAS_I16) repeatCount;
    637     p->transpose = (EAS_I8) transpose;
    638     p->libNum = (EAS_I8) libNum;
    639     p->muteFlags = muteFlags;
    640     p->state = JET_STATE_CLOSED;
    641 
    642     /* open the file */
    643     result = EAS_OpenJETStream(easHandle, easHandle->jetHandle->jetFileHandle, easHandle->jetHandle->segmentOffsets[segmentNum], &p->streamHandle);
    644     if (result != EAS_SUCCESS)
    645         return result;
    646     p->state = JET_STATE_OPEN;
    647 
    648     /* if less than SEG_QUEUE_DEPTH segments queued up, prepare file for playback */
    649     if (++easHandle->jetHandle->numQueuedSegments < SEG_QUEUE_DEPTH)
    650     {
    651         result = JET_PrepareSegment(easHandle, easHandle->jetHandle->queueSegment);
    652         if (result != EAS_SUCCESS)
    653             return result;
    654     }
    655 
    656     /* create duplicate file handle */
    657     result = EAS_HWDupHandle(easHandle->hwInstData, easHandle->jetHandle->jetFileHandle, &fileHandle);
    658     if (result != EAS_SUCCESS)
    659         return result;
    660 
    661     easHandle->jetHandle->jetFileHandle = fileHandle;
    662     easHandle->jetHandle->queueSegment = (EAS_U8) JET_NextSegment(easHandle->jetHandle->queueSegment);
    663     return result;
    664 }
    665 
    666 /*----------------------------------------------------------------------------
    667  * JET_Play()
    668  *----------------------------------------------------------------------------
    669  * Starts playback of the file
    670  *----------------------------------------------------------------------------
    671 */
    672 EAS_PUBLIC EAS_RESULT JET_Play (EAS_DATA_HANDLE easHandle)
    673 {
    674     EAS_RESULT result;
    675     EAS_INT index;
    676     EAS_INT count = 0;
    677 
    678     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Play\n"); */ }
    679 
    680     /* sanity check */
    681     if (easHandle->jetHandle->flags & JET_FLAGS_PLAYING)
    682         return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
    683 
    684     /* resume all paused streams */
    685     for (index = 0; index < SEG_QUEUE_DEPTH; index++)
    686     {
    687         if (((index == easHandle->jetHandle->playSegment) && (easHandle->jetHandle->segQueue[index].state == JET_STATE_READY)) ||
    688             (easHandle->jetHandle->segQueue[index].state == JET_STATE_PAUSED))
    689         {
    690             result = JET_StartPlayback(easHandle, index);
    691             if (result != EAS_SUCCESS)
    692                 return result;
    693             count++;
    694         }
    695     }
    696 
    697     /* if no streams are playing, return error */
    698     if (!count)
    699         return EAS_ERROR_QUEUE_IS_EMPTY;
    700 
    701     easHandle->jetHandle->flags |= JET_FLAGS_PLAYING;
    702     return EAS_SUCCESS;
    703 }
    704 
    705 /*----------------------------------------------------------------------------
    706  * JET_Pause()
    707  *----------------------------------------------------------------------------
    708  * Pauses playback of the file
    709  *----------------------------------------------------------------------------
    710 */
    711 EAS_PUBLIC EAS_RESULT JET_Pause (EAS_DATA_HANDLE easHandle)
    712 {
    713     EAS_RESULT result;
    714     EAS_INT index;
    715     EAS_INT count = 0;
    716 
    717     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Pause\n"); */ }
    718 
    719     /* sanity check */
    720     if ((easHandle->jetHandle->flags & JET_FLAGS_PLAYING) == 0)
    721         return EAS_ERROR_NOT_VALID_IN_THIS_STATE;
    722 
    723     /* pause all playing streams */
    724     for (index = 0; index < SEG_QUEUE_DEPTH; index++)
    725     {
    726         if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
    727         {
    728             result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle);
    729             if (result != EAS_SUCCESS)
    730                 return result;
    731             easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].state = JET_STATE_PAUSED;
    732             count++;
    733         }
    734     }
    735 
    736     /* if no streams are paused, return error */
    737     if (!count)
    738         return EAS_ERROR_QUEUE_IS_EMPTY;
    739 
    740     easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
    741     return EAS_SUCCESS;
    742 }
    743 
    744 /*----------------------------------------------------------------------------
    745  * JET_SetMuteFlags()
    746  *----------------------------------------------------------------------------
    747  * Change the state of the mute flags
    748  *----------------------------------------------------------------------------
    749 */
    750 EAS_PUBLIC EAS_RESULT JET_SetMuteFlags (EAS_DATA_HANDLE easHandle, EAS_U32 muteFlags, EAS_BOOL sync)
    751 {
    752     S_JET_SEGMENT *pSeg;
    753 
    754     /* get pointer to current segment */
    755     pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
    756 
    757     /* unsynchronized mute, set flags and return */
    758     if (!sync)
    759     {
    760         if (pSeg->streamHandle == NULL)
    761             return EAS_ERROR_QUEUE_IS_EMPTY;
    762         pSeg->muteFlags = muteFlags;
    763         return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) muteFlags);
    764     }
    765 
    766 
    767     /* check for valid stream state */
    768     if (pSeg->state == JET_STATE_CLOSED)
    769         return EAS_ERROR_QUEUE_IS_EMPTY;
    770 
    771     /* save mute flags */
    772     pSeg->muteFlags = muteFlags;
    773 
    774     /* if repeating segment, set mute update flag */
    775     if (sync)
    776         pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
    777     return EAS_SUCCESS;
    778 }
    779 
    780 /*----------------------------------------------------------------------------
    781  * JET_SetMuteFlag()
    782  *----------------------------------------------------------------------------
    783  * Change the state of a single mute flag
    784  *----------------------------------------------------------------------------
    785 */
    786 EAS_PUBLIC EAS_RESULT JET_SetMuteFlag (EAS_DATA_HANDLE easHandle, EAS_INT trackNum, EAS_BOOL muteFlag, EAS_BOOL sync)
    787 {
    788     S_JET_SEGMENT *pSeg;
    789     EAS_U32 trackMuteFlag;
    790 
    791 
    792     /* setup flag */
    793     if ((trackNum < 0) || (trackNum > 31))
    794         return EAS_ERROR_PARAMETER_RANGE;
    795     trackMuteFlag = (1 << trackNum);
    796 
    797     /* get pointer to current segment */
    798     pSeg = &easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment];
    799 
    800     /* unsynchronized mute, set flags and return */
    801     if (!sync)
    802     {
    803         if (pSeg->streamHandle == NULL)
    804             return EAS_ERROR_QUEUE_IS_EMPTY;
    805         if (muteFlag)
    806             pSeg->muteFlags |= trackMuteFlag;
    807         else
    808             pSeg->muteFlags &= ~trackMuteFlag;
    809         return EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
    810     }
    811 
    812 
    813     /* check for valid stream state */
    814     if (pSeg->state == JET_STATE_CLOSED)
    815         return EAS_ERROR_QUEUE_IS_EMPTY;
    816 
    817     /* save mute flags and set mute update flag */
    818     if (muteFlag)
    819         pSeg->muteFlags |= trackMuteFlag;
    820     else
    821         pSeg->muteFlags &= ~trackMuteFlag;
    822     pSeg->flags |= JET_SEG_FLAG_MUTE_UPDATE;
    823     return EAS_SUCCESS;
    824 }
    825 
    826 /*----------------------------------------------------------------------------
    827  * JET_TriggerClip()
    828  *----------------------------------------------------------------------------
    829  * Unmute a track and then mute it when it is complete. If a clip
    830  * is already playing, change mute event to a trigger event. The
    831  * JET_Event function will not mute the clip, but will allow it
    832  * to continue playing through the next clip.
    833  *
    834  * NOTE: We use bit 7 to indicate an entry in the queue. For a
    835  * small queue, it is cheaper in both memory and CPU cycles to
    836  * scan the entire queue for non-zero events than keep enqueue
    837  * and dequeue indices.
    838  *----------------------------------------------------------------------------
    839 */
    840 EAS_PUBLIC EAS_RESULT JET_TriggerClip (EAS_DATA_HANDLE easHandle, EAS_INT clipID)
    841 {
    842     EAS_INT i;
    843     EAS_INT index = -1;
    844 
    845     /* check for valid clipID */
    846     if ((clipID < 0) || (clipID > 63))
    847         return EAS_ERROR_PARAMETER_RANGE;
    848 
    849     /* set active flag */
    850     clipID |= JET_CLIP_ACTIVE_FLAG;
    851 
    852     /* Reverse the search so that we get the first empty element */
    853     for (i = JET_MUTE_QUEUE_SIZE-1; i >= 0 ; i--)
    854     {
    855         if (easHandle->jetHandle->muteQueue[i] == clipID)
    856         {
    857             index = i;
    858             break;
    859         }
    860         if (easHandle->jetHandle->muteQueue[i] == 0)
    861             index = i;
    862     }
    863     if (index < 0)
    864         return EAS_ERROR_QUEUE_IS_FULL;
    865 
    866     easHandle->jetHandle->muteQueue[index] = (EAS_U8) clipID | JET_CLIP_TRIGGER_FLAG;
    867     return EAS_SUCCESS;
    868 }
    869 
    870 /*----------------------------------------------------------------------------
    871  * JET_Process()
    872  *----------------------------------------------------------------------------
    873  * Called during EAS_Render to process stream states
    874  *----------------------------------------------------------------------------
    875 */
    876 EAS_PUBLIC EAS_RESULT JET_Process (EAS_DATA_HANDLE easHandle)
    877 {
    878     S_JET_SEGMENT *pSeg;
    879     EAS_STATE state;
    880     EAS_INT index;
    881     EAS_INT playIndex;
    882     EAS_RESULT result = EAS_SUCCESS;
    883     EAS_BOOL endOfLoop = EAS_FALSE;
    884     EAS_BOOL startNextSegment = EAS_FALSE;
    885     EAS_BOOL prepareNextSegment = EAS_FALSE;
    886     EAS_U32 jetEvent;
    887 
    888     /* process event queue */
    889     while (JET_ReadQueue(easHandle->jetHandle->jetEventQueue,
    890         &easHandle->jetHandle->jetEventQueueRead,
    891         easHandle->jetHandle->jetEventQueueWrite,
    892         JET_EVENT_QUEUE_SIZE, &jetEvent))
    893     {
    894         S_JET_EVENT event;
    895 #ifdef DEBUG_JET
    896         JET_DumpEvent("JET_Process", jetEvent);
    897 #endif
    898         JET_ParseEvent(jetEvent, &event);
    899 
    900         /* check for end of loop */
    901         if ((event.controller == JET_EVENT_MARKER) &&
    902                 (event.value == JET_MARKER_LOOP_END) &&
    903                 (easHandle->jetHandle->segQueue[easHandle->jetHandle->playSegment].streamHandle != NULL))
    904             endOfLoop = EAS_TRUE;
    905     }
    906 
    907     /* check state of all streams */
    908     index = playIndex = easHandle->jetHandle->playSegment;
    909     for (;;)
    910     {
    911         pSeg = &easHandle->jetHandle->segQueue[index];
    912         if (pSeg->state != JET_STATE_CLOSED)
    913         {
    914 
    915             /* get playback state */
    916             result = EAS_State(easHandle, pSeg->streamHandle, &state);
    917             if (result != EAS_SUCCESS)
    918                 return result;
    919 
    920             /* process state */
    921             switch (pSeg->state)
    922             {
    923                 /* take action if this segment is stopping */
    924                 case JET_STATE_PLAYING:
    925                     if (endOfLoop || (state == EAS_STATE_STOPPING) || (state == EAS_STATE_STOPPED))
    926                     {
    927                         /* handle repeats */
    928                         if (pSeg->repeatCount != 0)
    929                         {
    930                             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render repeating segment %d\n", index); */ }
    931                             result = EAS_Locate(easHandle, pSeg->streamHandle, 0, EAS_FALSE);
    932                             if (result != EAS_SUCCESS)
    933                                 return result;
    934                             if (pSeg->repeatCount > 0)
    935                                 pSeg->repeatCount--;
    936 
    937                             /* update mute flags if necessary */
    938                             if (pSeg->flags & JET_SEG_FLAG_MUTE_UPDATE)
    939                             {
    940                                 result = EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
    941                                 if (result != EAS_SUCCESS)
    942                                     return result;
    943                                 pSeg->flags &= ~JET_SEG_FLAG_MUTE_UPDATE;
    944                             }
    945 
    946                         }
    947                         /* no repeat, start next segment */
    948                         else
    949                         {
    950                             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Render stopping queue %d\n", index); */ }
    951                             startNextSegment = EAS_TRUE;
    952                             pSeg->state = JET_STATE_STOPPING;
    953                             easHandle->jetHandle->playSegment = (EAS_U8) JET_NextSegment(index);
    954                         }
    955                     }
    956                     break;
    957 
    958                 /* if playback has stopped, close the segment */
    959                 case JET_STATE_STOPPING:
    960                     if (state == EAS_STATE_STOPPED)
    961                     {
    962                         result = JET_CloseSegment(easHandle, index);
    963                         if (result != EAS_SUCCESS)
    964                             return result;
    965                     }
    966                     break;
    967 
    968                 case JET_STATE_READY:
    969                     if (startNextSegment)
    970                     {
    971                         result = JET_StartPlayback(easHandle, index);
    972                         if (result != EAS_SUCCESS)
    973                             return result;
    974                         startNextSegment = EAS_FALSE;
    975                         prepareNextSegment = EAS_TRUE;
    976                     }
    977                     break;
    978 
    979                 case JET_STATE_OPEN:
    980                     if (prepareNextSegment)
    981                     {
    982                         result = JET_PrepareSegment(easHandle, index);
    983                         if (result != EAS_SUCCESS)
    984                             return result;
    985                         prepareNextSegment = EAS_FALSE;
    986                     }
    987                     break;
    988 
    989                 case JET_STATE_PAUSED:
    990                     break;
    991 
    992                 default:
    993                     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "JET_Render: Unexpected segment state %d\n", pSeg->state); */ }
    994                     break;
    995             }
    996         }
    997 
    998         /* increment index */
    999         index = JET_NextSegment(index);
   1000         if (index == playIndex)
   1001             break;
   1002     }
   1003 
   1004     /* if out of segments, clear playing flag */
   1005     if (easHandle->jetHandle->numQueuedSegments == 0)
   1006         easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
   1007 
   1008     return result;
   1009 }
   1010 
   1011 /*----------------------------------------------------------------------------
   1012  * JET_Event()
   1013  *----------------------------------------------------------------------------
   1014  * Called from MIDI parser when data of interest is received
   1015  *----------------------------------------------------------------------------
   1016 */
   1017 void JET_Event (EAS_DATA_HANDLE easHandle, EAS_U32 segTrack, EAS_U8 channel, EAS_U8 controller, EAS_U8 value)
   1018 {
   1019     EAS_U32 event;
   1020 
   1021     if (easHandle->jetHandle == NULL)
   1022         return;
   1023 
   1024     /* handle triggers */
   1025     if (controller == JET_EVENT_TRIGGER_CLIP)
   1026     {
   1027         S_JET_SEGMENT *pSeg;
   1028         EAS_INT i;
   1029         EAS_U32 muteFlag;
   1030 
   1031         for (i = 0; i < JET_MUTE_QUEUE_SIZE; i++)
   1032         {
   1033             /* search for event in queue */
   1034             if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_ID_MASK) == (value & JET_CLIP_ID_MASK))
   1035             {
   1036                 /* get segment pointer and mute flag */
   1037                 pSeg = &easHandle->jetHandle->segQueue[segTrack >> JET_EVENT_SEG_SHIFT];
   1038                 muteFlag = 1 << ((segTrack & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT);
   1039 
   1040                 /* un-mute the track */
   1041                 if ((easHandle->jetHandle->muteQueue[i] & JET_CLIP_TRIGGER_FLAG) && ((value & 0x40) > 0))
   1042                 {
   1043                     pSeg->muteFlags &= ~muteFlag;
   1044                     easHandle->jetHandle->muteQueue[i] &= ~JET_CLIP_TRIGGER_FLAG;
   1045                 }
   1046 
   1047                 /* mute the track */
   1048                 else
   1049                 {
   1050                     EAS_U32 beforeMute ;
   1051                     beforeMute = pSeg->muteFlags ;
   1052                     pSeg->muteFlags |= muteFlag;
   1053                     if (beforeMute != pSeg->muteFlags)
   1054                         easHandle->jetHandle->muteQueue[i] = 0;
   1055                 }
   1056                 EAS_IntSetStrmParam(easHandle, pSeg->streamHandle, PARSER_DATA_MUTE_FLAGS, (EAS_I32) pSeg->muteFlags);
   1057                 return;
   1058             }
   1059         }
   1060         return;
   1061     }
   1062 
   1063     /* generic event stuff */
   1064     event = (channel << JET_EVENT_CHAN_SHIFT) | (controller << JET_EVENT_CTRL_SHIFT) | value;
   1065 
   1066     /* write to app queue, translate queue index to segment number */
   1067     if ((controller >= easHandle->jetHandle->config.appEventRangeLow) && (controller <= easHandle->jetHandle->config.appEventRangeHigh))
   1068     {
   1069 
   1070         event |= easHandle->jetHandle->segQueue[(segTrack & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT].userID << JET_EVENT_SEG_SHIFT;
   1071 #ifdef DEBUG_JET
   1072         JET_DumpEvent("JET_Event[app]", event);
   1073 #endif
   1074         JET_WriteQueue(easHandle->jetHandle->appEventQueue,
   1075             &easHandle->jetHandle->appEventQueueWrite,
   1076             easHandle->jetHandle->appEventQueueRead,
   1077             APP_EVENT_QUEUE_SIZE,
   1078             event);
   1079     }
   1080 
   1081     /* write to JET queue */
   1082     else if ((controller >= JET_EVENT_LOW) && (controller <= JET_EVENT_HIGH))
   1083     {
   1084         event |= segTrack;
   1085 #ifdef DEBUG_JET
   1086         JET_DumpEvent("JET_Event[jet]", event);
   1087 #endif
   1088         JET_WriteQueue(easHandle->jetHandle->jetEventQueue,
   1089             &easHandle->jetHandle->jetEventQueueWrite,
   1090             easHandle->jetHandle->jetEventQueueRead,
   1091             JET_EVENT_QUEUE_SIZE,
   1092             event);
   1093     }
   1094 }
   1095 
   1096 /*----------------------------------------------------------------------------
   1097  * JET_Clear_Queue()
   1098  *----------------------------------------------------------------------------
   1099  * Clears the queue and stops play without a complete shutdown
   1100  *----------------------------------------------------------------------------
   1101 */
   1102 EAS_RESULT JET_Clear_Queue(EAS_DATA_HANDLE easHandle)
   1103 {
   1104     EAS_INT index;
   1105     EAS_RESULT result = EAS_SUCCESS;
   1106 
   1107     { /* dpp: EAS_ReportEx(_EAS_SEVERITY_INFO, "JET_Clear_Queue\n"); */ }
   1108 
   1109     /* pause all playing streams */
   1110     for (index = 0; index < SEG_QUEUE_DEPTH; index++)
   1111     {
   1112         if (easHandle->jetHandle->segQueue[index].state == JET_STATE_PLAYING)
   1113         {
   1114             result = EAS_Pause(easHandle, easHandle->jetHandle->segQueue[index].streamHandle);
   1115             if (result != EAS_SUCCESS)
   1116                 return result;
   1117 
   1118             easHandle->jetHandle->segQueue[index].state = JET_STATE_PAUSED;
   1119         }
   1120     }
   1121 
   1122     /* close all streams */
   1123     for (index = 0; index < SEG_QUEUE_DEPTH; index++)
   1124     {
   1125         if (easHandle->jetHandle->segQueue[index].streamHandle != NULL)
   1126         {
   1127             result = JET_CloseSegment(easHandle, index);
   1128             if (result != EAS_SUCCESS)
   1129                 return result;
   1130         }
   1131     }
   1132 
   1133     /* clear all clips */
   1134     for (index = 0; index < JET_MUTE_QUEUE_SIZE ; index++)
   1135     {
   1136         easHandle->jetHandle->muteQueue[index] = 0;
   1137     }
   1138 
   1139     easHandle->jetHandle->flags &= ~JET_FLAGS_PLAYING;
   1140     easHandle->jetHandle->playSegment = easHandle->jetHandle->queueSegment = 0;
   1141     return result;
   1142 }
   1143 
   1144