Nav_CDDA.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:127k
- /****************************************************************************************
- * Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
- *
- * File: $Workfile: Nav_CDDA.c $
- *
- * Description:
- * ============
- *
- *
- * Log:
- * ====
- * $Revision: 134 $
- * Last Modified by $Author: Chaol $ at $Modtime: 04-04-02 15:40 $
- ****************************************************************************************
- * Updates:
- ****************************************************************************************
- * $Log: /I76/I76_Common/I76_Reference/Playcore/Nav_CDDA/Nav_CDDA.c $
- *
- * 134 04-04-02 15:40 Chaol
- * fix type
- *
- * 133 04-04-02 15:14 Chaol
- * increase CDDST detect time
- *
- * 132 04-04-02 10:37 Williaml
- * It may be down playing HDCD disc when check if it's a CD-DTS disc
- *
- * 131 04-04-01 23:38 Leslie
- * Change type definition
- *
- * 130 4/01/04 10:49p Johnk
- * support HW POWER_ON_RESUME for S1 spec
- *
- * 129 04-03-30 16:10 Williaml
- * set the play mode to normal from program, intro or shuffle after full
- * stop
- *
- * 128 04-03-27 15:32 Hansenw
- *
- * 127 3/26/04 5:02p Aidenl
- * TF changes 2
- *
- * 126 04-03-24 15:11 Angieh
- * For Alco,support previous func when play the first track.
- *
- * 125 04-03-22 16:41 Chaol
- * fix micro define
- *
- * 124 04-03-22 11:37 Chaol
- * enable CDTS detect code, it begin to work in version 00.2b
- *
- * 123 04-03-19 12:03 Chaol
- * fix _isValidCDDTS
- *
- * 122 04-03-17 17:46 Chaol
- * remove this code temp because ADP can't support CDDTS detect now
- *
- * 121 04-03-17 11:39 Chaol
- * add CDDTS support
- *
- * 120 3/16/04 7:15p Rinata
- *
- * 118 04-03-09 23:40 Wesleyj
- *
- * 117 04-02-25 20:21 Chaol
- * fix CDDA VFD bug
- *
- * 116 2/20/04 6:11p Glenl
- * Merged S1 code
- *
- * 115 04-02-13 17:20 Chaol
- * increase the CDDTS detect time
- *
- * 114 1/25/04 8:20 Nmaurer
- * Add drv_ prefix to Drive routines
- *
- * 113 12/30/03 10:13a Chaol
- * change function _isValidCDDTS
- *
- * 112 12/23/03 2:49p Chaol
- * change function _isValidCDDTS
- *
- * 111 12/22/03 4:25p Chaol
- * change function _isValidCDDTS to support CDDTS
- *
- * 110 9/29/03 11:54a Chaol
- *
- * 106 03-08-22 15:24 Chaol
- * to support DTS output analog and SPDIF at the same time, check
- * SUPPORT_DTS_ANALOG_AND_SPDIF for detail
- *
- * 105 8/18/03 1:46p Mikex
- * roll back to reopen the introduction function
- *
- * 104 8/12/03 9:38a Mikex
- * close the introductive function for CDDA
- *
- * 103 8/12/03 9:24a Francisw
- * Do not display "Rep Off" OSD message when the "SkipF" or "SkipB" button
- * is pressed following the "Rep A-B" button.
- *
- * 102 03-07-28 17:03 Leslie
- * Check in changes for Task Force
- *
- * 101 03-07-22 17:07 Mikelv
- * support cdda de_emphasis
- *
- * 100 03-07-16 17:44 Mikelv
- * If current played item is the first one in the program list,then
- * prohibit skipb.(as required by customer)
- *
- * 99 03-07-14 20:38 Mikelv
- * support scan in intro mode
- *
- * 98 03-07-11 17:29 Mikelv
- * For repeat single mode,we give drive 2*200ms to detect track
- * transition,and 6*200ms for other conditions,
- *
- * 97 03-07-10 22:52 Leslie
- * Roll back Jane's change about disable Scan in Intro mode
- *
- * 95 7/10/03 5:19p Clifflv
- * Enlarge m_bLocationChanging margin for scan backward
- *
- * 94 03-07-07 22:28 Mikelv
- * when destruct cd nav,set volume to be maximum.(for vestel)
- *
- * 93 03-07-07 15:42 Tonnyg
- * when mode changed, clear all bookmarks
- *
- * 92 03-07-06 1:39 Leslie
- * Change CDDA_TRACK_CHANGE_DETECTION_COUNTER from 6 to 2
- *
- * 91 7/04/03 5:00a Stephaneh
- * Removed fixed from Frank regarding CDDTS. There is no need to add such
- * a variable. There is already a function called CDDA_IsCDDTS() that
- * return the right information.
- *
- * 90 03-07-03 14:43 Mikelv
- * For cdda's program play being set in pst_stop state,one condition
- * should be removed from OnModeChange().(bug193)
- *
- * 89 03-07-03 14:12 Mikelv
- * OnIntro() should call OnModeChang() function since the pst mode
- * changed(bug218)
- *
- * 88 03-07-03 12:03 Frankm
- * Leslie suggest to add one member to gns.cdda.
- *
- * 87 03-06-30 18:21 Janeg
- * Move bIsCDDAIntroMode to SHARED_INFO.
- * Clear resume address when restart.
- *
- * 86 03-06-30 16:46 Leslie
- *
- * 85 03-06-27 21:09 Leslie
- * Not use software CD_TRACK_CHECK_BY_DECODER compile switch
- *
- * 84 03-06-26 19:09 Wesleyj
- * fixed can not continue FB when playing CD
- *
- * 83 03-06-26 16:58 Wesleyj
- * Update track number in onplaybackfinished()
- *
- * 82 03-06-25 11:40 Hannahh
- *
- * 81 03-06-19 17:39 Hannahh
- *
- * 80 03-06-19 11:06 Mikelv
- * add condition to avoid system sending "Playback finishied" event, when
- * drive is just starting to play new track.
- *
- * 79 03-06-17 15:00 Fwang
- * Optimize NVM_BMK parameter.
- *
- * 78 03-06-09 18:28 Tonnyg
- * correct shuffle switch in resumable stop state
- *
- * 77 03-06-02 18:23 Fwang
- * Set NVM bookmark by parameter
- *
- * 76 03-05-28 11:19 Fwang
- * Specified auto postion in NVM_BMK_SET()
- *
- * 75 03-05-28 9:40 Fwang
- * Set bookmark type in NVM_BMK_SET()
- *
- * 74 03-05-27 22:42 Fwang
- * Add NVM bookmark
- *
- * 73 03-05-21 21:41 Leslie
- * Notify UI operation error for time search if time is invalid
- *
- * 72 03-05-21 15:12 Billt
- * Added normal finish condition to avoid press STOP twice and PLAY
- * quickly and it starts playbacking 2nd track
- *
- * 71 03-05-16 22:21 Leslie
- * New error recovery implementation
- *
- * 70 03-05-10 13:47 Mikelv
- * For cddts,get time from driver
- *
- * 69 03-05-07 17:37 Mikelv
- * fix the bug that when jump to previous chapter,the osd and vfd's time
- * are wrong.
- *
- * 68 03-05-06 15:45 Dingming
- * add margin for cancel mark A detection
- *
- * 67 03-05-04 16:53 Dingming
- * for some case, the ucode is not loaded correctly
- *
- * 66 03-04-28 15:18 Leslie
- * Clear Resume Bookmark before start CDDA intro playback
- *
- * 65 03-04-23 20:46 Mikelv
- * For everytime call onscan() function,reset the current positon,no
- * matter whether it is already pst_scan or not.
- *
- * 64 03-04-17 17:52 Tonnyg
- * fix the bug that can't set A-B after set A/A-B then repeat single
- *
- * 63 03-04-17 14:51 Tonnyg
- * Prohibit pre/next when repeat single, just jump to the beginning, same
- * as DVD.
- *
- * 62 4/14/03 3:30p Lyncolnc
- * Modify the previous change.
- *
- * 61 4/14/03 2:03p Lyncolnc
- * Immediately after subcode buffer is cleared when going to a new track,
- * the current location read may be an invalid negative number. Do not use
- * it in the error recovery value.
- *
- * 60 4/10/03 4:41p Lyncolnc
- * In CDDA FF, sometimes track number info cannot be updated on OSD/FP.
- * This can be solved by refreshing the count-down in scantrack().
- *
- * 59 03-04-07 14:47 Billt
- * don't cancel repeat when play from stopresume
- *
- * 58 4/03/03 4:39p Lyncolnc
- * Problem: When playing track 10, press Prev to play track 9. If drive
- * takes time to seek/read, error may happen when Core thinks it is
- * playing track 9 but OnTick() thinks it is playing track 10 because it
- * reads the subcode buffer which is not updated. Rendezvous will happen
- * and causes UI/Core to jump to track 10, but in fact track 9 is being
- * played.
- * Solution: Clear subcode buffer when needed. Avoid reading old subcode
- * info.
- *
- * 57 03-04-02 20:53 Leslie
- * Emergency eject for CDDA Disc loading
- *
- * 57 03-03-25 19:16 Leslie
- *
- * 56 03-03-22 19:00 Leslie
- * Fix CDDA Pause to Scan noise problem
- *
- * 55 03-03-15 18:04 Leslie
- *
- * 54 03-03-11 17:33 Dingming
- * CDDTS bug fixing for SPDIF
- *
- * 53 03-03-07 18:42 Leslie
- * Fix the wrong calculation problem with CDDA playback start address
- *
- * 53 3/06/03 3:12p Yarone
- * Removed pach for Drive response too long - fixed in drive module
- *
- * 52 03-03-04 11:44 Hannahh
- * remove the customer name from all project.
- *
- * 51 03-03-03 13:27 Leslie
- * Update with changes
- *
- * 51 03-02-27 17:57 Dingming
- * bug fixing for cdts
- *
- * 50 03-02-27 15:16 Leslie
- * Update with ZCH change
- * Fix Multi-Session CDDA problems
- *
- * 49 2/26/03 9:46p Tomasp
- * Synchronization with ZCH database
- *
- * 49 03-02-24 13:49 Hannahh
- * Replace printf to debug
- *
- * 48 2/21/03 11:04a Stephaneh
- * Removed useless statement
- *
- * 47 2/21/03 7:16a Stephaneh
- * Cleaned subcode and error recovery info when full stop
- *
- * 46 03-02-19 22:07 Leslie
- *
- * 46 03-02-19 15:41 Leslie
- * Add GET_CDDTS_MSF_FROM_DRIVE
- *
- * 45 03-02-11 11:39 Leslie
- * Add Get Total Elapsed Time
- *
- * 44 03-02-09 15:10 Dingming
- * macro name change
- *
- * 43 2/07/03 10:46p Tomasp
- * - changed SW feature selection to compilation switch
- *
- * 42 03-01-24 20:32 Leslie
- * Cancel PlayMode/Repeat mode when entering IntroPlay Mode
- *
- * 41 03-01-18 2:44 Leslie
- * Change CDDA_SUPPORT_DTS_DECODING
- *
- * 40 03-01-15 18:48 Dingming
- * code clean up
- *
- * 39 03-01-09 4:38 Leslie
- * CDDA Intro playback supported
- *
- * 38 12/25/02 5:56p Leslie
- * Code cleanup
- *
- * 37 12/09/02 6:07p Leslie
- * Code cleanup
- *
- * 36 11/29/02 7:55a Leslie
- * Fix no track number update in fast playback
- *
- * 35 11/10/02 10:09a Leslie
- * Add delay for Trackchange detection in case the servo seeking is not
- * stable or fast
- *
- * 34 10/30/02 12:19a Leslie
- * Check if event is NULL before send it
- *
- * 39 6/23/02 10:33 Rinata
- * fixed CDDTS - Handle changing of audio setting digital <-->analog
- *
- * 38 4/06/02 18:54 Nirm
- * - Added CDDA_PROHIBIT_SCAN_ACROSS_PROGRAM_ENTRIES, to allow control
- * over whether or not Program-entries are scanned when in
- * Program/Shuffle.
- *
- * 37 3/06/02 20:01 Nirm
- * - Fixed a problem in the Rendezvous and Playback-Finished detection
- * mechanism, which caused false or duplicate detections;
- * - Added support of Silent-Playback of Data-Tracks, via
- * CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS.
- *
- * 36 3/06/02 11:15 Nirm
- * - Code cleanup.
- *
- * 35 27/05/02 18:52 Nirm
- * - Cleaned-up compilation-warnings.
- *
- * 34 23/05/02 18:12 Ettim
- * Calling directly to OnPlaybackFinished to prevent race between
- * IE_CORE_CDNAV_FINISHED and IE_CORE_TICK.
- *
- * 33 20/05/02 9:58 Ettim
- * Using Array_ instead of sc_read/write ..
- *
- * 32 7/05/02 16:41 Ettim
- * Added PowerOnResume playback support.
- *
- * 31 5/05/02 17:56 Ettim
- * Added support in CDEXTRA.
- *
- * 30 2/05/02 16:08 Ettim
- * Setting a longer wait time in the CDDTS detection sequence.
- *
- * 29 29/04/02 16:55 Nirm
- * - Code cleanup.
- *
- * 28 4/25/02 12:17 Rinata
- * update gcst.mCDDTSDetected according to _isValidCDDTS
- *
- * 27 23/04/02 9:31 Nirm
- * - Added dependency in "Config.h".
- *
- * 26 22/04/02 18:34 Ettim
- * Performing Mute when trying to play a data track (FFM bug CDDA:#1,#2)
- *
- * 25 21/04/02 9:51 Ettim
- * Using the _isValidCDDTS function to determine audio sid - CDDTS or
- * CDDA.
- *
- * 24 18/04/02 11:43 Ettim
- * Added CDDTS support.
- *
- * 23 16/04/02 15:23 Ettim
- * Integration with CDDTS. Work is still im progress.
- *
- * 22 4/14/02 16:35 Rinata
- * move the init of gcst.mCDDTSDetected to CDDTS_UN_INITIALIZE to teh
- * constructor of teh CDDA , for all other disc types it init to
- * CDDTS_NOT_DETECTED
- *
- * 21 4/14/02 15:16 Rinata
- * Support DTS, CDTS
- *
- * 20 12/04/02 13:42 Nirm
- * - Fixed wrong indication of COP_NEXT_CHAPTER on the last Program-List
- * Entry.
- *
- * 19 4/01/02 19:30 Ettim
- * Removed a few warning messages.
- *
- * 18 25/03/02 20:59 Nirm
- * Added #include.
- *
- * 17 3/14/02 11:11 Ettim
- * Removing from Globsdef.h variables that are used only by the CDDA
- * navigator, and declaring them locally in Nav_CDDA.c
- *
- * 16 4/03/02 20:49 Nirm
- * Integrated support for Full-Stop.
- *
- * 15 7/02/02 16:33 Nirm
- * - Fixed resumption of playback when using
- * CDDA_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES.
- *
- * 12 1/17/02 16:39 Ettim
- * removed the include for the stubs.h file
- *
- * 11 1/16/02 16:16 Ettim
- * Updating the macro PE_CD_SetDiscType to get only 1 argument.
- *
- * 10 16/01/02 11:51 Atai
- * Change debug printing
- *
- * 9 1/14/02 11:15 Ettim
- *
- * 8 1/13/02 18:18 Ettim
- *
- * 7 9/01/02 15:43 Nirm
- * Corrected Include-Paths.
- ****************************************************************************************/
-
- #include "Config.h" // Global Configuration - do not remove!
- #ifdef _DEBUG
- #define IFTRACE if (gTraceNavigator)
- #include "DebugDbgMain.h"
- #endif
- #include "IncludeSysDefs.h"
- #include "Includemath-macro.h"
- #include "Kernelker_api.h"
- #include "KernelEventDef.h"
- #include "PlaycoreCoremaincoregdef.h"
- #include "PlaycoreDataStructuresArray.h"
- #include "PlaycoreNav_CDDApe_cd.h"
- #include "PlaycoreNav_CDDANav_CDDA.h"
- #include "PlaycoreNav_CDDAcdnav_err.h"
- #include "PlaycorePlayModeplaymode.h"
- #include "PlaycoreScPadscmgr.h"
- #include "PlaycoreTimingTiming.h"
- #include "PlaycoreExceptionException.h"
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- #include "PlaycoreCoremainnvm_bmk.h"
- #endif
- #endif //EXINO2
- //Function prototypes
- void ForceCDTSmicrocde(BOOL enable );
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- BOOL CDDANAV_NvmBmk_Match(NVM_GENERIC_BMK* pGenric_bmk);
- void CDDANAV_NvmBmk_Set( WORD sc_handle);
- void CDDANAV_NvmBmk_Play(NVM_GENERIC_BMK *pGenric_bmk);
- #endif
- #endif //EXINO2
- extern BOOL g_in_full_stop;
- extern BYTE ucDriveErrorMsgCount;//LX070303:
- #ifdef D_USE_VARIABLE_FOR_LIB
- extern WORD cdda_skip_back_threshold;
- #endif
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Constants
- #define CDDTS_DECODING_ATTEMPT_SZ 300
- #define CDDTS_SEEK_MARGIN_SZ 0 //SeanLiu_0524_2004_A
- #define DRIVER_SEEK_MARGIN 100 //DM050603
- #define CDDA_TRACK_CHANGE_DETECTION_COUNTER_6 0x06
- #define CDDA_TRACK_CHANGE_DETECTION_COUNTER_2 0x02
- #define INTRO_PLAYBACK_TIME 10 //10 second
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- #define CDDA_ERROR_JUMP_GAP_SECONDS 2
- #endif
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Macros
- #define SHARED_INFO gns.cdda
- #define CDDAMessageGap SHARED_INFO.CDDAMessageGap
- #define g_pCDDANav SHARED_INFO.g_pCDDANav
- #define g_bIsCDDTS SHARED_INFO.g_bIsCDDTS
- #define g_hTrackInfoCache SHARED_INFO.g_hTrackInfoCache
- #define uPrevTrackNumber SHARED_INFO.uPrevTrackNumber
- #define MARKAB_FINISH_GAP 4
- ////////////////////////////////////////////////////////////////////////////////////////////////
- // Globals
- #ifdef CDDA_ERROR_RECOVERY
- CONST DWORD g_miCDDANSPBErrorJumpTbl[CDDA_ERROR_RETRY_NUM] =
- {
- // in term of seconds
- 1,
- 2,
- 4,
- 8,
- 15,
- 30,
- 45,
- 60,
- 90,
- 120,
- 150,
- 180,
- 210,
- 240,
- 270,
- 300,
- 360,
- 420,
- 600,
- 900
- };
- #endif
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Private Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // _isValidCDDTS() -
- // asas
- //
- // Input:
- // Op - The type of operation being invoked
- // Event - The event to route
- // Param - An optional parameter for the event being routed
- //
- // Output:
- // Zero if the routing is successful.
- BOOL _isValidCDDTS(DWORD dwStartAddr, DWORD uBlocksCnt)
- {
- BOOL bIsValid = FALSE;
- int retry_cnt=1500;
- dbg_printf(("_isValidCDDTSn"));
-
- if (Exception_catchAndRethrow(EXCEPTION_MEDIUM_EJECTED))
- {
- tr_printf(("HHHHHHn"));
- return FALSE;
- }
- DEC_MuteOutput(MUTE_DETECT_REQUEST, MUTE_SETTING_ON);
- DEC_MuteSPDIF(MUTE_DETECT_REQUEST, MUTE_SETTING_ON);
- DEC_SetSID(DEC_SID_TYPE_AUDIO, DEC_ASID_CD_DETECT);
-
- PE_CD_PlaySegment(NoVideo, CDDETECT_SID , dwStartAddr+(uBlocksCnt/2), //CDDTS_SEEK_MARGIN_SZ, fix the bug for DTS-ES supporting(jump to middle of the first track to check DTS head)
- MIN(CDDTS_DECODING_ATTEMPT_SZ, uBlocksCnt), eNormalSpeed, 0);
- while(retry_cnt > 0x0)
- {
- switch(PE_CD_GetCdDetectType())
- {
- case CD_DETECT_CDDA :
- bIsValid = FALSE;
- retry_cnt = 0x0;
- break;
- case CD_DETECT_CDTS :
- bIsValid = TRUE;
- retry_cnt = 0x0;
- break;
- default :
- delay_us(10000UL);
- retry_cnt --;
- }
- }
- PE_CD_AbortPlayback(TRUE);
- DEC_MuteOutput(MUTE_DETECT_REQUEST, MUTE_SETTING_OFF);
- DEC_MuteSPDIF(MUTE_DETECT_REQUEST, MUTE_SETTING_OFF);
-
- return (bIsValid);
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Public Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // int CDDA_Navigator(HDLR_OP Op, EVENT Event, void *Param) -
- // The main router for CDDA-Navigation Events.
- //
- // Input:
- // Op - The type of operation being invoked
- // Event - The event to route
- // Param - An optional parameter for the event being routed
- //
- // Output:
- // Zero if the routing is successful.
- int CDDA_Navigator(HDLR_OP Op, EVENT Event, void *Param)
- {
- switch (Op)
- {
- case HDLR_ENTER: Constructor();
- break;
- case HDLR_EXIT: Destructor();
- break;
- case HDLR_EVENT:
- switch (Event)
- {
- case IE_CORE_PAUSE:
- OnStop(ePause);
- break;
- case IE_CORE_STOP:
- //IFDEF(Cdda_Macro.bCDDA_ALLOW_RESUME)
- OnStop((TRUE == (BOOL)Param) ? eFullStop : eStopResume);
- //ELSE
- // OnStop(eFullStop);
- //ENDIF //CDDA_ALLOW_RESUME
- break;
- case IE_CORE_RESTART:
- #ifdef EXINO2 // ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- if(GetResumeLeadOutInfo() == gns.cdda.wTotalPlaybackTime)
- {
- ClearResumeLeadOutInfo();
- restore_CDDA_info();
- }
- else
- #endif //HW_POWER_ON_RESUME
- #else //EXINO2
- #ifdef HW_POWER_ON_RESUME
-
- ClearMarker(eResumePlayback, 0);
- if((TRUE == (BOOL)Param)&&(NVM_BMK_Play()))
- {
- dbg_printf(("nNVM Bookmark restart. "));
- }
-
- else
- #endif //HW_POWER_ON_RESUME
- #endif //EXINO2
- {
- #ifdef K1_WL
- //add by wl040708 for resume play after full stop
- if (resume_play_request)
- {
- memcpy(&(g_pCDDANav->m_CurrPosition), &(g_pCDDANav->m_ResumePlayback), sizeof(CDDA_Marker));
- resume_play_request = FALSE;
- }
- else
- //add by wl040708 for resume play after full stop
- #endif
- {
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- (g_pCDDANav->m_ResumePlayback).dwAddress=-1;
- }
- }
- // Fall-Through!
- case IE_CORE_PLAY:
- OnPlay();
- break;
- case IE_CORE_NEXT_CHAPTER:
- OnNextItem();
- break;
- case IE_CORE_PREVIOUS_CHAPTER:
- OnPreviousItem();
- break;
- case IE_CORE_GOTO_ENTRY:
- case IE_CORE_MENU_NUMERICAL_SELECTION:
- OnNumericSelection((int)Param);
- break;
- case IE_CORE_CDNAV_RENDEZVOUS:
- if (IE_CORE_CDNAV_RENDEZVOUS == g_pCDDANav->m_evPendingEvent) {
- OnRendezvousPoint((enCDDA_RendezvousType)Param);
- g_pCDDANav->m_evPendingEvent= 0;
- }
- break;
- case IE_CORE_CDNAV_FINISHED:
- if (IE_CORE_CDNAV_FINISHED == g_pCDDANav->m_evPendingEvent) {
- OnPlaybackFinished();
- g_pCDDANav->m_evPendingEvent= 0;
- }
- break;
- case IE_CORE_PM_RESET:
- // reset the PM mode : program,repeat, random , reset play -A-B
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- PM_ClearRepeat();
- break;
- case IE_CORE_AB_REPEAT:
- if (0 == (int)Param) {
- OnCancelABRepeat();
- break;
- }
- if (PM_GetRepeatAB() & PM_REPEAT_AB_B) {
- OnCancelABRepeat();
- PM_SetRepeatAB(0);
- }
- else { //after set A or A-B, set repeat single, then A will never be setted for the dwStartAddress is still there.
- if ((0 == PM_GetRepeatAB()))// && ((g_pCDDANav->m_PositionA).iPlaylistItem < 0)) // so I remove this condition, if this is necessary, let me know please, tonnyg
- {
- OnSetMarkerA();
- PM_SetRepeatAB(PM_REPEAT_AB_A);
- }
- else {
- OnSetMarkerB();
- PM_SetRepeatAB(PM_REPEAT_AB_B);
- }
- }
- break;
- case IE_CORE_SET_BOOKMARK:
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_SET((int)Param);
- #endif
- #endif
- SetMarker(eBookmark, (WORD)Param - 1);
- break;
- case IE_CORE_GOTO_BOOKMARK:
- OnGoToBookmark((WORD)Param - 1);
- break;
- case IE_CORE_SCAN:
- // If there is a Location-Change in progress,
- // reschedule this event for later.
- if (g_pCDDANav->m_bLocationChanging) {
- // If currently Pausing, then first resume Playback,
- // otherwise the target Location will never be reached.
- if (PST_PAUSE == gcs.pstate)
- OnPlay();
- ie_send_ex(IE_CORE_SCAN, Param);
- }
- else
- OnScan((int)Param);
- break;
- case IE_CORE_TICK_ONE_SEC:
- //<<<Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- #ifdef CDDA_ERROR_RECOVERY
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- if ( ( PST_PLAY == gcs.pstate ) || ( PST_SCAN == gcs.pstate ) ){
- if ( PE_CD_CheckAudioBufferFullness() )
- {
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- }
- }
- #endif
- #endif
- //Leslie_0118_2004_A>>>
- break;
- case IE_CORE_TICK_200:
- OnTick();
- break;
- case IE_CORE_SEAMLESS_MODE_CHANGE:
- OnModeChange();
- break;
- case IE_CORE_GOTO_TIME:
- OnGotoTime((ULONG)Param);
- #ifdef EXINO2
- ie_send(IE_UI_REFRESH_TIME);
- #endif
- break;
- case IE_CORE_GOTO_DISC_TIME:
- #ifdef D_ENABLE_DISC_TIMESEARCH
- OnGotoDiscTime((ULONG)Param);
- #endif
- break;
- case IE_CORE_CDNAV_INTRO:
- OnIntro();//rollback to reopen the introductive function //mikex 03-08-12: close the introductive function
- break;
- //#ifndef NO_WATCHDOG
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- case IE_CORE_DRIVE_READ_FAIL:
- #ifdef CDDA_ERROR_RECOVERY
- //<<<Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- if ((PST_PLAY != gcs.pstate) && (PST_SCAN != gcs.pstate)){
- tr_printf(("Return from IE_CORE_DRIVE_READ_FAIL, since not in PLAY or SCAN Staten"));
- return;
- }
-
- dbg_printf(("CDDA_Nav: DriveDriver_ReadFail encountered.n"));
- if ( (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount > CDDA_ERROR_RETRY_NUM ){
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- tr_printf(("Retry time expires, stop the playbackn"));
- OnStop(eFullStop );
- break;
- }
- if ( ( PST_SCAN == gcs.pstate ) && ( ( g_pCDDANav->m_iScanSpeed) < 0 ) ){
- if ( ( PE_CD_GetCurrentLocation() > (g_pCDDANav->m_ErrorRecoveryInfo).dwParam )
- && ( (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount > 0 ) ){
- }else
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam = PE_CD_GetCurrentLocation();
- }else
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam = PE_CD_GetCurrentLocation();
- tr_printf(("Stuck at point %lx, Retry Count %02xn",
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam, (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount));
- PerformErrorRecovery();
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount++;
- //Leslie_0118_2004_A>>>
- #else
- dbg_printf(("CDDA_Nav: DriveDriver_ReadFail encountered.n"));
- // Force Error-Recovery
- // (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= 1;
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= PE_CD_GetCurrentLocation();
- PerformErrorRecovery();
- #endif
- break;
- #endif//WATCHDOG_TRIGGERED_BY_FE
- //#endif //NO_WATCHDOG
- case EVENT_CLASS_CORE:
- #ifdef _DEBUG
- OnStatusReport();
- #endif //_DEBUG
- break;
- default:
- dbg_printf(("CDDA_Nav: Unexpected Event %xn",Event & 0xFF));
- break;
- }
- break;
- default:
- dbg_printf((" CDDA_Nav: Unknown Operation requested %dn", Op));
- break;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Private Services
- /////////////////////////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void Constructor() -
- // A Constructor for a CDDA-Navigator instance.
- //
- // Input:
- // None
- //
- // Output:
- // None. The Navigator is constructed.
- //
- // Remarks:
- // This method constructs a new CDDA-Navigator, whose internal data and status
- // are kept in the CDDA_Nav structure passed to the method.
- #ifndef D_NO_DECODE_ENCRYPT_CDDA
- extern BOOL bIsCopyControlCDDA;
- #endif
- static void Constructor()
- {
- int iTrack, iSlot, iEntriesCnt;
- TrackInfo tiFirstTrack, tiLastTrack;
- BOOL bFirstCDDATrackFound = FALSE;
- INT8 iDataTrackCnt = 0;
- dbg_printf(("CDDA Nav Constructor()n"));
- dbg_printf(("--> Size of CDDA Navigator is: %dn", (int)sizeof(S_CDDA_GLOBALS)));
- #ifndef EXINO2 //ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_Hook(BMK_CDDA, CDDANAV_NvmBmk_Match, CDDANAV_NvmBmk_Set, CDDANAV_NvmBmk_Play);
- NVM_BMK_Verify();
- #endif
- #endif
- CDDAMessageGap.MARKABReachGap = 0;
- //configure the disc type to CDDA by default
- PE_CD_SetDiscType(DEC_DISC_TYPE_CDDA);
- iEntriesCnt= PE_CD_GetTracksCnt();
- #ifndef D_NO_DECODE_ENCRYPT_CDDA
- if(bIsCopyControlCDDA)
- iEntriesCnt--;
- #endif
- // Cache the entire TOC information, for later use
- g_hTrackInfoCache= Array_construct(iEntriesCnt, sizeof(TrackInfo), NULL);
- if (NULL == g_hTrackInfoCache) {
- dbg_printf(("Failed to allocate resources for the Tracks-Info Cache.n"));
- return;
- }
- for (iTrack=1; iTrack <= iEntriesCnt; iTrack++) {
- if (! PE_CD_GetTrackInfo(iTrack, &tiFirstTrack)) {
- dbg_printf(("Failed to retrieve Track information for Track #%d.n", iTrack));
-
- Array_destruct(g_hTrackInfoCache);
- g_hTrackInfoCache= NULL;
- return;
- }
- Array_setAt(g_hTrackInfoCache, (iTrack - 1), (BYTE *)&tiFirstTrack);
- }
- //Allocating the SVCD Navigator struct
- g_pCDDANav = (CDDA_Nav_Info *)malloc(sizeof(CDDA_Nav_Info));
- if (NULL == g_pCDDANav) {
- dbg_printf(("Failed to allocate resources for the CDDA Navigator struct.n"));
- return;
- }
- //initializing the rand seed
- srand((UINT16)timing_get_clock());
- #ifdef CDTEXT_SUPPORT
- // Read disc's CDTEXT name if available
- SHARED_INFO.pDiscCDText= (UINT32)PE_CD_GetCDTEXTInfo(0);
- #ifdef _DEBUG
- if (SHARED_INFO.pDiscCDText) {
- dbg_printf(("Disc name: %sn", SHARED_INFO.pDiscCDText));
- }
- #endif //_DEBUG
- #endif //CDTEXT_SUPPORT
- // Initialize the default Program-List to a sequencial playback of the entire disc
- PM_InitializeProgramList();
- SET_COP_MASK(0xFFFFFFFFL);
- CLEAR_COP_MASK(COP_SLOW | COP_STEP | COP_ZOOM | COP_PANNING |
- COP_ROOT_MENU | COP_AUDIO_CHANGE | COP_SUBPIC_CHANGE | COP_ANGLE_CHANGE |
- COP_RETURN);
- // Search for the First CDDA Track on this Disc, and initialize the Program-List
- // to play sequencially from that Track.
- g_pCDDANav->m_uFirstCDDA_Track= 1;
- for (iTrack=1, iSlot=1; iTrack <= iEntriesCnt; iTrack++)
- {
- #ifdef CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- PM_SetProgramListEntry((WORD)iSlot++, (WORD)iTrack);
- g_pCDDANav->m_uLastCDDA_Track = (WORD)iTrack;
- #else
- UINT8 uTrackCtrlField;
- UINT32 uDummy;
- if (! PE_CD_GetTrackTOC(iTrack, &uTrackCtrlField, &uDummy, &uDummy)) {
- tr_printf(("FATAL: Failed to collect TOC info for Track #%dn", iTrack));
- continue;
- }
- if (((uTrackCtrlField & 0x0F) == 0x4)
- #ifndef D_NO_DECODE_ENCRYPT_CDDA
- && (!bIsCopyControlCDDA)
- #endif
- ) {
- #ifdef D_CDDA_ADD_DATATRACK_IN_PROGM_LIST
- // Stivenz_1102_2004: No need m_uFirstCDDA_Track if we also set data track;
- iDataTrackCnt++;
- #else
- // This is a Data Track - Skip it, assuming that the next one will be
- // a CDDA Track.
- if (! bFirstCDDATrackFound) {
- g_pCDDANav->m_uFirstCDDA_Track= (iTrack + 1);
- bFirstCDDATrackFound = TRUE;
- }
- #endif // #ifdef D_CDDA_ADD_DATATRACK_IN_PROGM_LIST
-
- }
- else {
- // This is a CDDA Track - add it to the Program-List
- // <<<Stiven_1101_2004: Set track-num of the nearest audio track as the track-num of data track
- #ifdef D_CDDA_ADD_DATATRACK_IN_PROGM_LIST
- while(iDataTrackCnt!=0)
- {
- // Set track-num of first audio-track we meet as the track-num of all data-track we have counted just now.
- PM_SetProgramListEntry((WORD)iSlot++, (WORD)iTrack);
- iDataTrackCnt--;
- }
- #else
- // Stivenz_1102_2004: No need if we also set data track;
- if (! bFirstCDDATrackFound) {
- g_pCDDANav->m_uFirstCDDA_Track= iTrack;
- bFirstCDDATrackFound = TRUE;
- }
- #endif // #ifdef D_CDDA_ADD_DATATRACK_IN_PROGM_LIST
- // Stiven_1101_2004 >>>
- PM_SetProgramListEntry((WORD)iSlot++, (WORD)iTrack);
- g_pCDDANav->m_uLastCDDA_Track = (WORD)iTrack;
- }
- #endif //CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- }
- // <<<Stiven_1101_2004: Set track-num of the nearest audio track as the track-num of data track
- // in case of the data tracks locate in the end of tracks.
- #ifdef D_CDDA_ADD_DATATRACK_IN_PROGM_LIST
- // If data-track locate in the end of CDDA, we set the track-num of last audio-track as it track-num
- iTrack -=(iDataTrackCnt+1);
- while(iDataTrackCnt!=0)
- {
- PM_SetProgramListEntry((WORD)iSlot++, (WORD)iTrack);
- iDataTrackCnt--;
- }
- #endif
- // Stiven_1101_2004 >>>
-
- //reading the first track content from the table we already filled
- Array_getAt(g_hTrackInfoCache, (g_pCDDANav->m_uFirstCDDA_Track-1), (BYTE *)&tiFirstTrack);
- #ifdef CD_TRACK_CHECK_BY_DECODER
- // Try to identify if the Audio contents is actually CDDTS:
- gcst.mCDDTSDetected= CDDTS_UN_INITIALIZE;
- g_bIsCDDTS= FALSE;
- g_pCDDANav->g_bIsCDDTS_BAK = g_bIsCDDTS;
-
- //Checking to see if the current stream is a valid CDDTS stream.
- if (_isValidCDDTS(tiFirstTrack.dwStartAddress, tiFirstTrack.ulBlocksCnt))
- {
- dbg_printf(("CDDTS_SIDn"));
-
- #if (defined(DTS_DISABLE) || defined(CD_DTS_DECODE_DISABLE) )
- g_pCDDANav->m_eCurrAudSID= CDDA_SID;
- #else
- g_pCDDANav->m_eCurrAudSID= CDDTS_SID;
- #endif
- gcst.mCDDTSDetected= CDDTS_DETECTED;
- g_bIsCDDTS= TRUE;
- }
- else
- {
- dbg_printf(("CDDA_SIDn"));
- g_bIsCDDTS= FALSE;
- g_pCDDANav->m_eCurrAudSID= CDDA_SID;
- gcst.mCDDTSDetected= CDDTS_NOT_DETECTED;
- }
- #else
- g_bIsCDDTS= FALSE;
- g_pCDDANav->m_eCurrAudSID= CDDA_SID;
- #endif //CD_TRACK_CHECK_BY_DECODER
- g_pCDDANav->g_bIsCDDTS_BAK = g_bIsCDDTS; //DM080902 back cddts flag
- // Initialize the Playback-Mode
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- // Initialize the current Position to the first item on the Playlist
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- (g_pCDDANav->m_CurrPosition).dwAddress= -1;
- // Initialize the A->B Markers to "Non-Valid"
- ClearMarker(eMarkerA, 0);
- ClearMarker(eMarkerB, 0);
- // Initialize the Bookmarks to "Non-Valid"
- for (iSlot=0; iSlot < CDDA_MAX_BOOKMARKS; iSlot++)
- ClearMarker(eBookmark, iSlot);
- // Initialize the Resume-Playback position to "Restart"
- ClearMarker(eResumePlayback, 0);
- // No pending notifcation-requests or Mode Change
- g_pCDDANav->m_uRendezvousPoint= 0;
- g_pCDDANav->m_bPendingModeChange= FALSE;
- g_pCDDANav->m_evPendingEvent= 0;
- // Update the current Playback-Mode
- g_pCDDANav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- // Initialize Scanning mode to "OFF"
- g_pCDDANav->m_iScanSpeed= 0;
- // Initialize the settings of the Global variables
- SHARED_INFO.iCurrentTime= 0;
- SHARED_INFO.uCurrentTrackNumber= 1;
- // Initialize the mode of sound mode DM090902
- SHARED_INFO.bArtificialSoundMode = 1;
- g_pCDDANav->m_bLocationChanging = FALSE;
- //reading the last track info from the table we already filled
- Array_getAt(g_hTrackInfoCache, (g_pCDDANav->m_uLastCDDA_Track - 1), (BYTE *)&tiLastTrack);
- SHARED_INFO.wTotalPlaybackTime= (WORD)((tiLastTrack.dwStartAddress + tiLastTrack.ulBlocksCnt - tiFirstTrack.dwStartAddress) / CDDA_BLOCKS_PER_SEC);
- SHARED_INFO.uTotalCDDATracksCnt = (UINT8)(g_pCDDANav->m_uLastCDDA_Track);
- #ifdef CDDA_USE_ABSOLUTE_TIME
- SHARED_INFO.wRemainingPlaybackTime = SHARED_INFO.wTotalPlaybackTime;
- #else
- SHARED_INFO.wRemainingPlaybackTime = (WORD)(tiFirstTrack.ulBlocksCnt / CDDA_BLOCKS_PER_SEC);
- #endif //CDDA_USE_ABSOLUTE_TIME
- #ifdef S1_GUI
- // For flt display during program play
- gns.cdda.iPlaylistItemForFLT = 1;
- #endif
- gcs.pstate= PST_STOP; // Currently in STOP mode
- // Reset the Error-Recovery mechanism
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= 0;
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
-
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = 0xFF;
- SHARED_INFO.bIsCDDAIntroMode = 0;
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void Destructor() -
- // A Destructor for a CDDA-Navigator instance.
- //
- // Input:
- // None.
- //
- // Output:
- // None. The Navigator's structures destroyed.
- //
- // Remarks:
- // This method destructs an existing instance of the CDDA-Navigator.
- static void Destructor()
- {
- dbg_printf(("CDDA_Destructor()n"));
- #ifdef EXINO2 // ZKR JK0331 : for power_on_resume for EEPORM
- #ifdef HW_POWER_ON_RESUME
- if (g_power_state == POWER_SEQUENCE_OFF_REQUESTED)
- {
- if( g_in_full_stop != TRUE )
- {
- if(gcs.pstate !=PST_STOP)
- SetMarker(eResumePlayback, 0);
- save_CDDA_info();
- SetResumeLeadOutInfo();
- }
- }
- #endif // HW_POWER_ON_RESUME
- #else //EXINO2
- #ifdef HW_POWER_ON_RESUME
- NVM_BMK_UnHook();
- #endif
- #endif
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- PE_CD_AbortPlayback(FALSE);
- PE_CD_DisplayLogo();
- gcs.pstate= PST_STOP;
- g_in_full_stop = TRUE; /* forces next PLAY to be mapped to RESTART */
- //free from SDRAM
- if (NULL != g_hTrackInfoCache) {
- Array_destruct(g_hTrackInfoCache);
- g_hTrackInfoCache= NULL;
- }
- if (NULL != g_pCDDANav)
- free(g_pCDDANav);
- #ifdef NO_ANLOG_OUTPUT_WHEN_SETTING_DTS_DIGITAL
- ie_send_ex(IE_CORE_UPDATE_PS, (void *)((((DWORD)PS_UPDATE_VOLUME_SETTING)<<16) + 0x7FFF));
- //set volume to be max
- #endif
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void SetMarker(enCDDA_MarkerType eMarkerType, WORD uBookmarkNumber) -
- // Records the current playback position in the desired Marker.
- //
- // Input:
- // eMarkerType - Identifies which Marker is to be used for recording
- // uBookmarkNumber - If a Bookmark is being recorded, identifies the serial number
- // of the requested Bookmark within the list of available Bookmarks
- //
- // Output:
- // None. The requested Marker is recorded.
- //
- // Remarks:
- // If an attempt is made to record a non-existent Bookmark, the recording is aborted.
- static void SetMarker(enCDDA_MarkerType eMarkerType, WORD uBookmarkNumber)
- {
- CDDA_Marker *pMarker= NULL;
- // Select the appropriate Marker to set
- switch (eMarkerType)
- {
- case eMarkerA: pMarker= &(g_pCDDANav->m_PositionA);
- break;
- case eMarkerB: pMarker= &(g_pCDDANav->m_PositionB);
- break;
- case eResumePlayback:
- pMarker= &(g_pCDDANav->m_ResumePlayback);
- break;
- case eBookmark: if (uBookmarkNumber >= CDDA_MAX_BOOKMARKS)
- pMarker= NULL;
- else
- pMarker= &(g_pCDDANav->m_Bookmarks[uBookmarkNumber]);
- break;
- }
- if (NULL != pMarker) {
- pMarker->iPlaylistItem= (g_pCDDANav->m_CurrPosition).iPlaylistItem;
- // Record the current position
- if (g_pCDDANav->m_bLocationChanging)
- pMarker->dwAddress= g_pCDDANav->m_dwTargetLocation;
- else
- pMarker->dwAddress= PE_CD_GetDecoderCurrentLocationLBN();
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void ClearMarker(enCDDA_MarkerType eMarkerType, WORD uBookmarkNumber) -
- // Clears the desired Marker.
- //
- // Input:
- // eMarkerType - Identifies which Marker is to be cleared
- // uBookmarkNumber - If a Bookmark is being cleared, identifies the serial number
- // of the requested Bookmark within the list of available Bookmarks
- //
- // Output:
- // None. The requested Marker is cleared.
- //
- // Remarks:
- // If an attempt is made to clear a non-existent Bookmark, the clearing is aborted.
- static void ClearMarker(enCDDA_MarkerType eMarkerType, WORD uBookmarkNumber)
- {
- CDDA_Marker *pMarker= NULL;
- // Select the appropriate Marker to set
- switch (eMarkerType)
- {
- case eMarkerA: pMarker= &(g_pCDDANav->m_PositionA);
- break;
- case eMarkerB: pMarker= &(g_pCDDANav->m_PositionB);
- break;
- case eResumePlayback:
- pMarker= &(g_pCDDANav->m_ResumePlayback);
- break;
- case eBookmark: if (uBookmarkNumber >= CDDA_MAX_BOOKMARKS)
- pMarker= NULL;
- else
- pMarker= &(g_pCDDANav->m_Bookmarks[uBookmarkNumber]);
- break;
- }
- if (NULL != pMarker) {
- pMarker->iPlaylistItem= -1;
- pMarker->dwAddress= -1;
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // BOOL InvokePlayback() -
- // Invokes playback of a segment/Track.
- //
- // Input:
- // bUseMarkers - TRUE if the PositionA and PositionB Markers should be used as the
- // boundaries of the segment to play. Otherwise, FALSE.
- //
- // Output:
- // TRUE if the playback was successfully invoked. FALSE otherwise.
- //
- // Remarks:
- // This method can be used for one of two purposes:
- // 1. To start the playback of a specific segment, when in REPEAT_AB mode;
- // 2. To start playback of at least a single Track from its beginning / resume playback
- // of a Track from the last known position.
- //
- // When Form 1 of the call is used (via supplying bUseMarkers= TRUE), the method
- // instructs the PE to play only the segment starting at m_PositionA and ending
- // at m_PositionB.
- //
- // When From 2 of the call is used (via supplying bUseMarkers= FALSE), the method
- // will start playback either from the last position where it was interrupted (this is
- // indicated by a valid m_ResumePlayback Marker), or from the beginning of the Track.
- //
- // If there's a Linear-sequence of Tracks, then the method schedules a Rendezvous-Point
- // at the first Track-boundary in the sequence.
- static BOOL InvokePlayback(void)
- {
- int iCurrItem= (int)(g_pCDDANav->m_CurrPosition).iPlaylistItem;
- ULONG ulTrackSize, uBlocksToPlayCnt;
- DWORD dwTrackStartAddr, dwPlaybackStartAddr;
- BOOL bLinearSequenceFound= FALSE;
- TrackInfo tiCurrTrack;
- DWORD dwFirstPlayTrackStartAddress=0,dwLastPlayTrackEndAddress = 0;
- // Extract the Track-information for the current playlist-item
- WORD uCurrTrackNumber= PM_GetProgramListEntry(iCurrItem);
- // Reading the current track's content from the table we already filled
- Array_getAt(g_hTrackInfoCache, (uCurrTrackNumber - 1), (BYTE *)&tiCurrTrack);
- dwTrackStartAddr= tiCurrTrack.dwStartAddress;
- ulTrackSize= tiCurrTrack.ulBlocksCnt;
- // Save the Starting address of the current Track
- g_pCDDANav->m_aCurrTrack[0]= dwTrackStartAddr;
- g_pCDDANav->m_aCurrTrack[1]= (dwTrackStartAddr + ulTrackSize);
- if (-1 == (g_pCDDANav->m_CurrPosition).dwAddress) {
- dbg_printf(("Playing Item #%d from the beginning.n", iCurrItem));
-
- g_bIsCDDTS = g_pCDDANav->g_bIsCDDTS_BAK; //DM080902 resume cddts flag
- dwPlaybackStartAddr= dwTrackStartAddr;
- uBlocksToPlayCnt= ulTrackSize;
- //in case we use absolute time we don't want to reset the time dislpayed between tracks transition
- #ifndef CDDA_USE_ABSOLUTE_TIME
- // Clear the Elapsed-Time, if the Item is going to be played from its beginning
- SHARED_INFO.iCurrentTime= 0;
- #endif //CDDA_USE_ABSOLUTE_TIME
- }
- else {
- dbg_printf(("Resuming playback of Item #%d.n", iCurrItem));
- dwPlaybackStartAddr= (g_pCDDANav->m_CurrPosition).dwAddress;
- uBlocksToPlayCnt= ulTrackSize - ((g_pCDDANav->m_CurrPosition).dwAddress - dwTrackStartAddr);
- // Invalidate the Resume-Playback Marker, that was just used
- (g_pCDDANav->m_CurrPosition).dwAddress= -1;
- }
- dwFirstPlayTrackStartAddress = dwPlaybackStartAddr;
-
- // For CDDA, try locating Linear-Sequences within the current playlist
- if (! g_bIsCDDTS) {
- // At this point, it is known that at least the Current Track must be played until its end.
- // Now calculate whether a linear Track-sequence exists in the playlist. If so, request a sequential
- // playback of the entire linear-series, in order to allow smooth transitions between adjacent tracks.
- while (iCurrItem < (int)(PM_GetProgramSize() - 1)) {
- // Check if the current item and the next one are adjacent Tracks
- if (PM_GetProgramListEntry(iCurrItem+1) != (1 + PM_GetProgramListEntry(iCurrItem))){ // If no adjacency found, break search
- dwLastPlayTrackEndAddress = tiCurrTrack.dwStartAddress + tiCurrTrack.ulBlocksCnt;
- uBlocksToPlayCnt = dwLastPlayTrackEndAddress - dwFirstPlayTrackStartAddress;
- break;
- }
-
- bLinearSequenceFound= TRUE;
- Array_getAt(g_hTrackInfoCache, (PM_GetProgramListEntry(iCurrItem+1) - 1), (BYTE *)&tiCurrTrack);
- // // Add the entire Track to the playback sequence
- // uBlocksToPlayCnt += tiCurrTrack.ulBlocksCnt;
- // if ( iCurrItem == (int)(g_pCDDANav->m_CurrPosition).iPlaylistItem ){
- // dwFirstPlayTrackStartAddress = tiCurrTrack.dwStartAddress;
- // }
-
- iCurrItem++;
- }
- if ( iCurrItem >= (int)(PM_GetProgramSize() - 1 ) ){
- dwLastPlayTrackEndAddress = tiCurrTrack.dwStartAddress + tiCurrTrack.ulBlocksCnt;
- uBlocksToPlayCnt = dwLastPlayTrackEndAddress - dwFirstPlayTrackStartAddress;
- }
- }
- // Record the boundaries of the current Segment
- g_pCDDANav->m_aCurrSegment[0]= dwPlaybackStartAddr;
- g_pCDDANav->m_aCurrSegment[1]= (dwPlaybackStartAddr + uBlocksToPlayCnt);
- // Initiate Error-Recovery from Playback-Hangup
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= (2 * CDDA_PB_HANGUP_TIMEOUT);
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= dwPlaybackStartAddr;
-
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
-
- g_pCDDANav->m_bLocationChanging= TRUE;
- g_pCDDANav->m_dwTargetLocation= dwPlaybackStartAddr;
- // For CD-DTS discs, determine the validity of the stream
- if (g_bIsCDDTS)
- {
- if(_isValidCDDTS(dwTrackStartAddr, ulTrackSize)) //SeanLiu_0524_2004_B
- {
- // A valid CD-DTS stream -- decode it
- #if (defined(DTS_DISABLE) || defined(CD_DTS_DECODE_DISABLE) )
- g_pCDDANav->m_eCurrAudSID= CDDA_SID;
- #else
- g_pCDDANav->m_eCurrAudSID= CDDTS_SID;
- #endif
- gcst.mCDDTSDetected= CDDTS_DETECTED;
- dbg_printf(("CDDTS_SIDn"));
- }
- else
- {
- // An invalid CD-DTS stream -- treat it as a CDDA stream
- g_bIsCDDTS = FALSE;
- g_pCDDANav->m_eCurrAudSID= CDDA_SID;
- gcst.mCDDTSDetected= CDDTS_NOT_DETECTED;
- dbg_printf(("CDDA_SIDn"));
- }
- }
- if (! PE_CD_PlaySegment(NoVideo, g_pCDDANav->m_eCurrAudSID, dwPlaybackStartAddr, uBlocksToPlayCnt,
- eNormalSpeed, 0))
- {
- dbg_printf(("Failed to playback the current itemn"));
- return FALSE;
- }
- if (bLinearSequenceFound) {
- // If a Linear-Sequence was found, then schedule a Rendezvous-Point at the beginning of
- // the second Item on the sequence. This notification is needed in order to keep track of
- // playlist-items transitions during the playback.
- g_pCDDANav->m_uRendezvousPoint= (uCurrTrackNumber + 1);
- dbg_printf(("Scheduling a Rendezvous-Point for: %dn", (uCurrTrackNumber + 1)));
- }
- else {
- g_pCDDANav->m_uRendezvousPoint= 0;
- }
- if (PST_PAUSE == gcs.pstate) {
- #ifdef CDDA_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES)
- PE_CD_PausePlayback(FALSE, g_pCDDANav->m_eCurrAudSID);
- gcs.pstate= PST_PLAY;
- #else
- OnStop(ePause);
- #endif //CDDA_PROHIBIT_PAUSE_ACROSS_ITEM_BOUNDARIES
- }
- if (PST_STOP == gcs.pstate)
- gcs.pstate= PST_PLAY;
- // Update the Global variables
- SHARED_INFO.uCurrentTrackNumber= uCurrTrackNumber;
- //jeanz_0411_2005 Fix bug :stop randomly when a track is finished in shuffle mode.
- if(PM_IsRepeatSingle()||PM_IsPlaybackProgram(g_PlayModeInfo.iPlaybackMode) || PM_IsPlaybackShuffle(g_PlayModeInfo.iPlaybackMode))
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_2;
- else
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_6;
- #ifdef CDTEXT_SUPPORT
- SHARED_INFO.pTrackCDText = (UINT32)PE_CD_GetCDTEXTInfo((BYTE)SHARED_INFO.uCurrentTrackNumber);
- #ifdef _DEBUG
- if (SHARED_INFO.pTrackCDText) {
- dbg_printf(("Track #%d name: %sn", SHARED_INFO.uCurrentTrackNumber, SHARED_INFO.pTrackCDText));
- }
- #endif //_DEBUG
- #endif //CDTEXT_SUPPORT
- return TRUE;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void CalculateRecoveryAddress() -
- // Calculates a destination address for attempting Error-Recovery.
- //
- // Input:
- // dwErrorAddress - Holds the LBN where the Error occurred.
- // bForward - Indicates whether the recovery address should be in the forward
- // direction, or not.
- //
- // Output:
- // None.
- //
- // Remarks:
- // If the Error Address is met for the first time, Recovery will be attempted from the
- // exact same place.
- // For successive occurrences of the Error, a Linear offset is used to advance through
- // the Segment.
- #define LINEAR_ERROR_RECOVERY_OFFSET 10
- static DWORD CalculateRecoveryAddress(DWORD dwErrorAddress, BOOL bForward)
- {
- static DWORD dwLastError= 0;
- static UINT8 uOccurrences= 0;
- // Check if this is the first time that we've seen this Address
- if (dwErrorAddress != dwLastError) {
- uOccurrences= 0; // Restart the mechanism for this Address
- dwLastError= dwErrorAddress;
- }
- // Begin Calculation of the Recovery Address
- if (1 == ++uOccurrences) {
- // At the first attempt, always try to replay the original segment
- return dwErrorAddress;
- }
- // Use a fixed linear offset for Recovery
- if (bForward)
- return (dwErrorAddress + LINEAR_ERROR_RECOVERY_OFFSET + (75L * uOccurrences));
- else
- return (dwErrorAddress - LINEAR_ERROR_RECOVERY_OFFSET - (75L * uOccurrences));
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void PerformErrorRecovery() -
- // Performs Error-Recovery, if needed.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // This function is expected to be called periodically in order to detecet an Error situation.
- // In response, this function will attempt to return the system to natural flow, if possible.
- static void PerformErrorRecovery()
- {
- BOOL bRecoveryNeeded= FALSE;
- BOOL bRecoveryAddressValid, bForwardDirection;
- DWORD dwCurrentLocation;
- DWORD dwRecoveryAddress;
- ULONG ulBlocksCnt;
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- // Get the Current Location, depending on the current Audio-SID
- if (CDDA_SID == g_pCDDANav->m_eCurrAudSID)
- dwCurrentLocation= PE_CD_GetDecoderCurrentLocationLBN();
- else
- dwCurrentLocation= PE_CD_GetCurrentLocation();
- // Check if there's need to activate Error-Recovery, by checking if the Timeout has expired.
- if (((g_pCDDANav->m_ErrorRecoveryInfo).uTimeout <= 0) ||
- (0 != --(g_pCDDANav->m_ErrorRecoveryInfo).uTimeout))
- return;
- // Make sure that the current state is either Play or Scan, otherwise there can be no
- // Playback-Hangup.
- if ((PST_PLAY != gcs.pstate) && (PST_SCAN != gcs.pstate))
- return;
- // Take care of Playback-Hangup:
- // Establish the current Direction of Playback/Scanning
- bForwardDirection= ( (PST_PLAY == gcs.pstate) || ((PST_SCAN == gcs.pstate) && (g_pCDDANav->m_iScanSpeed > 0)) );
- // Determine the need for Recovery
- if (g_pCDDANav->m_bLocationChanging) {
- // If this point is reached while the Location is changing, then there is need
- // for recovery.
- bRecoveryNeeded= TRUE;
- // Calculate the expected Recovery-Address
- dwRecoveryAddress= CalculateRecoveryAddress(g_pCDDANav->m_dwTargetLocation, bForwardDirection);
- g_pCDDANav->m_dwTargetLocation= dwRecoveryAddress;
- dbg_printf(("Possible Playback-Hangup (Location-Change) -- Recovering...n"));
- dbg_printf(("Curr= %08lx, param= %08lxn", dwCurrentLocation, dwRecoveryAddress));
- }
- else {
- // Calculate the expected Recovery-Address
- dwRecoveryAddress= CalculateRecoveryAddress((g_pCDDANav->m_ErrorRecoveryInfo).dwParam, bForwardDirection);
- // Recovery necessity is determined by the relation between the Current-Location, and
- // the last good known location, as held in the Recovery-Info Parameter.
- if (bForwardDirection)
- bRecoveryNeeded= (dwCurrentLocation <= (g_pCDDANav->m_ErrorRecoveryInfo).dwParam);
- else
- bRecoveryNeeded= (dwCurrentLocation >= (g_pCDDANav->m_ErrorRecoveryInfo).dwParam);
- #ifdef _DEBUG
- if (bRecoveryNeeded) {
- dbg_printf(("Possible Playback-Hangup (%s) -- Recovering...n",
- (bForwardDirection ? "Forward" : "Backwards Scan")));
- dbg_printf(("Curr= %08lx, param= %08lxn", dwCurrentLocation, dwRecoveryAddress));
- }
- #endif //_DEBUG
- }
- // Calculate the validity of the Recovery-Address, according to the Direction
- // of playback/scanning. In addition, calculate the required amount of Blocks
- // to play, in case the Recovery-Address is valid.
- if (bForwardDirection) {
- bRecoveryAddressValid= (dwRecoveryAddress < g_pCDDANav->m_aCurrSegment[1]);
- ulBlocksCnt= (g_pCDDANav->m_aCurrSegment[1] - dwRecoveryAddress);
- }
- else {
- bRecoveryAddressValid= (dwRecoveryAddress > g_pCDDANav->m_aCurrSegment[0]);
- ulBlocksCnt= (dwRecoveryAddress - g_pCDDANav->m_aCurrSegment[0]);
- }
- // Perform the actual recovery-attempt, if needed
- if (bRecoveryNeeded) {
- // Abort the current opertion, while maintaining Standby Mode
- PE_CD_AbortPlayback(TRUE);
- // Invoke the appropriate recovery method
- if (bRecoveryAddressValid) {
- // The Recovery Address is within the legal range: try to recover
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= dwRecoveryAddress;
-
- if ( PST_SCAN == gcs.pstate ){
- PE_CD_SetScan(TRUE, g_pCDDANav->m_eCurrAudSID, g_pCDDANav->m_iScanSpeed);
- }
-
- PE_CD_PlaySegment(NoVideo, g_pCDDANav->m_eCurrAudSID, dwRecoveryAddress, ulBlocksCnt,
- ((PST_SCAN == gcs.pstate) ? eSearch : eNormalSpeed),
- g_pCDDANav->m_iScanSpeed);
- //<<<TorranceF_1028_2005 Use to mute cd when scand
- //#ifdef CDDA_MUTE_ON_SCAN
- if ((CdMedia_Macro.bCDDA_MUTE_ON_SCAN)&&(PST_SCAN == gcs.pstate ))
- {
- tr_printf(("Mute the audio output for CDDA Watchdogn"));
- PE_CD_SetMute(TRUE);
-
- }
- //#endif
- }
- else {
- // The Recovery-Address breaches the legal range: emulate a Playback-Finished
- // Event, so that navigation can carry on as if no error occurred.
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
- }
- else {
- // So far so good - there's progress. Register the Current Location.
- if (dwCurrentLocation != drv_msf2lbn(0,0,0)) //ZCO LC041403: Ignore 00:00:00 values when subcode buffer is just cleared andb not yet updated with valid values.
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= dwCurrentLocation;
- }
- // Reschedule the next check
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= CDDA_PB_HANGUP_TIMEOUT;
- #else//WATCHDOG_TRIGGERED_BY_FE
- #ifndef CDDA_ERROR_RECOVERY
- if ((PST_PLAY != gcs.pstate) && (PST_SCAN != gcs.pstate))
- return;
- #endif
- // Take care of Playback-Hangup:
- // Establish the current Direction of Playback/Scanning
- bForwardDirection= ( (PST_PLAY == gcs.pstate) || ((PST_SCAN == gcs.pstate) && (g_pCDDANav->m_iScanSpeed > 0)) );
- #ifdef CDDA_ERROR_RECOVERY
- //<<<Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- if ( bForwardDirection )
- dwRecoveryAddress = (g_pCDDANav->m_ErrorRecoveryInfo).dwParam
- + g_miCDDANSPBErrorJumpTbl[(g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount] * CDDA_BLOCKS_PER_SEC;
- else
- dwRecoveryAddress = (g_pCDDANav->m_ErrorRecoveryInfo).dwParam
- - g_miCDDANSPBErrorJumpTbl[(g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount] * CDDA_BLOCKS_PER_SEC;
- //Leslie_0118_2004_A>>>
- #else
- if ( bForwardDirection )
- dwRecoveryAddress = (g_pCDDANav->m_ErrorRecoveryInfo).dwParam
- + (DWORD)(CDDA_ERROR_JUMP_GAP_SECONDS*CDDA_BLOCKS_PER_SEC);
- else
- dwRecoveryAddress = (g_pCDDANav->m_ErrorRecoveryInfo).dwParam
- - (DWORD)(CDDA_ERROR_JUMP_GAP_SECONDS*CDDA_BLOCKS_PER_SEC);
- #endif
- dbg_printf(("Possible Playback-Hangup (%s) -- Recovering...n",
- (bForwardDirection ? "Forward" : "Backwards Scan")));
- // dbg_printf(("Curr= %08lx, param= %08lxn", dwCurrentLocation, dwRecoveryAddress));
- // Calculate the validity of the Recovery-Address, according to the Direction
- // of playback/scanning. In addition, calculate the required amount of Blocks
- // to play, in case the Recovery-Address is valid.
- if (bForwardDirection) {
- bRecoveryAddressValid= (dwRecoveryAddress < g_pCDDANav->m_aCurrSegment[1]);
- ulBlocksCnt= (g_pCDDANav->m_aCurrSegment[1] - dwRecoveryAddress);
- }
- else {
- bRecoveryAddressValid= (dwRecoveryAddress > g_pCDDANav->m_aCurrSegment[0]);
- ulBlocksCnt= (dwRecoveryAddress - g_pCDDANav->m_aCurrSegment[0]);
- }
- // Perform the actual recovery-attempt, if needed
- // Abort the current opertion, while maintaining Standby Mode
- PE_CD_AbortPlayback(TRUE);
- // Invoke the appropriate recovery method
- if (bRecoveryAddressValid) {
- #ifdef CDDA_ERROR_RECOVERY
- tr_printf(("Error Retry address valid, doing retry now at %lxn", dwRecoveryAddress ) );
- #else
- tr_printf(("Error Retry address valid, doing retry nown"));
- #endif
- if ( PST_SCAN == gcs.pstate ){
- PE_CD_SetScan(TRUE, g_pCDDANav->m_eCurrAudSID, g_pCDDANav->m_iScanSpeed);
- }
-
- PE_CD_PlaySegment(NoVideo, g_pCDDANav->m_eCurrAudSID, dwRecoveryAddress, ulBlocksCnt,
- ((PST_SCAN == gcs.pstate) ? eSearch : eNormalSpeed),
- g_pCDDANav->m_iScanSpeed);
- //#ifdef CDDA_MUTE_ON_SCAN
- //<<<TorranceF_1028_2005 Use to mute cd when scand
- if ((CdMedia_Macro.bCDDA_MUTE_ON_SCAN)&&(PST_SCAN == gcs.pstate))
- {
- tr_printf(("Mute the audio output for CDDA Watchdogn"));
- PE_CD_SetMute(TRUE);
-
- }
- //#endif
- }
- else {
- // The Recovery-Address breaches the legal range: emulate a Playback-Finished
- // Event, so that navigation can carry on as if no error occurred.
- #ifndef CDDA_ERROR_RECOVERY
- tr_printf(("Error Retry out of range, current playback finishedn"));
- #else
- //<<<Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- g_pCDDANav->m_evPendingEvent= IE_CORE_CDNAV_FINISHED;
- //Leslie_0118_2004_A>>>
- #endif
- ie_send(IE_CORE_CDNAV_FINISHED);
- }
- #endif
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void ScanTrack(WORD uTrackNumber) -
- // Scans a single Track.
- //
- // Input:
- // uTrackNumber - Holds the Track number to scan.
- //
- // Output:
- // None.
- //
- // Remarks:
- // This function schedules playback of a single Track.
- // The assumption is, that this function is called from within a Scanning mode, so
- // that there is no need to call OnScan() again.
- // The function cancels any pending Rendezvous points, hence confining the entire
- // Scanning mechanism to the OnPlaybackFinished() event handler.
- static void ScanTrack(WORD uTrackNumber)
- {
- DWORD dwTrackStartAddress;
- ULONG ulTrackSize;
- TrackInfo tiTrack;
- //reading the track info
- Array_getAt(g_hTrackInfoCache, (uTrackNumber - 1), (BYTE *)&tiTrack);
- dwTrackStartAddress = tiTrack.dwStartAddress;
- //<<<ML0714 add for scanning in intro mode
- if((TRUE == SHARED_INFO.bIsCDDAIntroMode)&&(g_pCDDANav->m_iScanSpeed < 0))
- ulTrackSize = INTRO_PLAYBACK_TIME*CDDA_BLOCKS_PER_SEC;
- else
- //>>>ML0714 add for scan in intro mode
- ulTrackSize = tiTrack.ulBlocksCnt;
- // Purge any Rendezvous point (unneeded for Track scan)
- g_pCDDANav->m_uRendezvousPoint= 0;
- // Update Current-Track and Scanning-related information
- //<<<ML0714 add for scan in intro mode
- if((TRUE == SHARED_INFO.bIsCDDAIntroMode)&&(g_pCDDANav->m_iScanSpeed > 0))
- // Clear the Elapsed-Time, if the Item is going to be scanned from the beginning
- SHARED_INFO.iCurrentTime= 0;
- //>>>ML0714 add for scanning in intro mode
- g_pCDDANav->m_aCurrTrack[0]= dwTrackStartAddress;
- g_pCDDANav->m_aCurrTrack[1]= (dwTrackStartAddress + ulTrackSize);
- g_pCDDANav->m_aCurrSegment[0]= g_pCDDANav->m_aCurrTrack[0];
- g_pCDDANav->m_aCurrSegment[1]= g_pCDDANav->m_aCurrTrack[1];
- //jeanz_0411_2005 Fix bug :stop randomly when a track is finished in shuffle mode.
- if(PM_IsRepeatSingle()||PM_IsPlaybackProgram(g_PlayModeInfo.iPlaybackMode) || PM_IsPlaybackShuffle(g_PlayModeInfo.iPlaybackMode))
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_2; //ZCO LC041003
- else
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_6;
- // Initiate Error-Recovery
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= (2 * CDDA_PB_HANGUP_TIMEOUT);
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
- if (g_pCDDANav->m_iScanSpeed > 0)
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= g_pCDDANav->m_aCurrSegment[0];
- else
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= g_pCDDANav->m_aCurrSegment[1];
- if (CDDTS_SID != g_pCDDANav->m_eCurrAudSID)
- g_pCDDANav->m_bLocationChanging= TRUE;
- g_pCDDANav->m_dwTargetLocation= (g_pCDDANav->m_ErrorRecoveryInfo).dwParam;
- PE_CD_SetScan(TRUE, g_pCDDANav->m_eCurrAudSID, g_pCDDANav->m_iScanSpeed);
- #ifdef EXINO2
- // navigator should update track/time information earlier during scan.
- SHARED_INFO.uCurrentTrackNumber = uTrackNumber;
- if (g_pCDDANav->m_iScanSpeed > 0)
- SHARED_INFO.iCurrentTime = 0;
- #endif // EXINO2
- if (! PE_CD_PlaySegment(NoVideo, g_pCDDANav->m_eCurrAudSID, dwTrackStartAddress, ulTrackSize,
- eSearch, g_pCDDANav->m_iScanSpeed))
- {
- dbg_printf(("FATAL: ScanTrack() Failed to Scan Track.n"));
- }
- //#ifdef CDDA_MUTE_ON_SCAN
- //<<<TorranceF_1028_2005 Use to mute cd when scand
- if (CdMedia_Macro.bCDDA_MUTE_ON_SCAN)
- {
- PE_CD_SetMute(TRUE);
- }
- //#else
- #ifdef CDDTS_MUTE_ON_SCAN
- if (g_pCDDANav->m_eCurrAudSID == CDDTS_SID)
- // Force Mute, since the Playback is about to be re-invoked
- PE_CD_SetMute(TRUE);
- #endif //CDDTS_MUTE_ON_SCAN
- //#endif //CDDA_MUTE_ON_SCAN
- return;
- }
- static void CancelRepeatModes(BYTE uModesMask)
- {
- BOOL bRepeatModeChanged= FALSE;
- // Cancel "Repeat Single" if it is in effect
- if ((uModesMask & PM_REPEAT_SINGLE) && PM_IsRepeatSingle()) {
- PM_SetRepeatSingle(FALSE);
- bRepeatModeChanged= TRUE;
- }
- // Cancel "Repeat All" if it is in effect
- if ((uModesMask & PM_REPEAT_ALL) && PM_IsRepeatAll()) {
- PM_SetRepeatAll(FALSE);
- bRepeatModeChanged= TRUE;
- }
- // Cancel "Repeat A-B" if it is in effect
- if ((uModesMask & PM_REPEAT_AB_MASK) && (0 != PM_GetRepeatAB())) {
- PM_SetRepeatAB(0);
- OnCancelABRepeat();
- bRepeatModeChanged= TRUE;
- }
- if (bRepeatModeChanged)
- ie_send(IE_UI_STATE_CHANGE);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // Event Handlers
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnTick() -
- // Handles an IE_CORE_TICK_200 Event.
- //
- // Input:
- // None
- //
- // Output:
- // None.
- //
- // Remarks:
- // This method is responsible for issuing either IE_CORE_CDNAV_RENDEZVOUS or
- // IE_CORE_CDNAV_FINISHED. The method checks if a notification of either kind was scheduled,
- // and if it was - then a comparison is made between the current location and the scheduled
- // location.
- // If there is a match (within a reasonable threshold range), the appropriate event is
- // sent.
- //
- // A notification of type IE_CORE_CDNAV_FINISHED has precedence over IE_CORE_CDNAV_RENDEZVOUS,
- // and is always checked first.
- static void OnTick()
- {
- TrackInfo tiCurrTrack;
- BYTE ucCtrlField, ucTrackNumber;
- DWORD dwCurrLocation;
- BOOL bTrackTransitionDetected= FALSE;
- EVENT evEvent= 0;
- void *EventParam= 0;
- #ifdef GET_CDDTS_MSF_FROM_DRIVE
- DWORD dwCDDTSCurrLocation;
- //Getting MSF from Drive for CDDTS disc, since I64 STEP_A ADP is not abloe to get sub code from bitstream
- if ( g_bIsCDDTS )
- dwCDDTSCurrLocation = PE_CD_GetCurrentLocation();
- #endif//GET_CDDTS_MSF_FROM_DRIVE
- #ifdef CDDA_GETTIME_FROM_DRIVER
- dwCurrLocation= PE_CD_GetCurrentLocation();
- #else
- dwCurrLocation= PE_CD_GetDecoderCurrentLocationLBN();
- #endif
- #ifdef S1_GUI
- gns.cdda.iPlaylistItemForFLT= (g_pCDDANav->m_CurrPosition).iPlaylistItem;
- #endif
- // Update the global Location variable and the Elapsed-Time, provided that there is
- // no Location-Change in progress
- if ((PST_PAUSE != gcs.pstate) && (PST_STOP != gcs.pstate) &&
- (! g_pCDDANav->m_bLocationChanging))
- {
- int iSign;
- UINT8 uMinute, uSecond, uFrame;
- // Calculate the elapsed-time according to the current MSF, as
- // reported from the Decoder via Sub-Code Q
- // Get Total Elapsed Time
- if ( ( g_pCDDANav->m_aCurrTrack[0] <= dwCurrLocation ) && ( dwCurrLocation <= g_pCDDANav->m_aCurrTrack[1] ) )
- gns.cdda.wTotalElapsedTime = (WORD)(dwCurrLocation/CDDA_BLOCKS_PER_SEC);
- else
- gns.cdda.wTotalElapsedTime = (WORD)(g_pCDDANav->m_aCurrTrack[0]/CDDA_BLOCKS_PER_SEC);
-
- #ifdef CDDA_USE_ABSOLUTE_TIME
- #ifdef CDDA_GETTIME_FROM_DRIVER
- SHARED_INFO.iCurrentTime= dwCurrLocation;
- #else
- if (PE_CD_GetDecoderCurrentLocationMSF(eAbsoluteLocation,
- &uMinute, &uSecond, &uFrame, &iSign))
- {
- int iCurrentTime= (60 * uMinute) + uSecond;
- SHARED_INFO.iCurrentTime= iCurrentTime;
- }
- #endif//CDDA_GETTIME_FROM_DRIVER
- #else//CDDA_USE_ABSOLUTE_TIME
- #ifdef CDDA_GETTIME_FROM_DRIVER
- {
- tiCurrTrack.ulBlocksCnt = 0;
- Array_getAt(g_hTrackInfoCache, (SHARED_INFO.uCurrentTrackNumber - 1), (BYTE *)&tiCurrTrack);
- SHARED_INFO.iCurrentTime= (dwCurrLocation - tiCurrTrack.dwStartAddress)/CDDA_BLOCKS_PER_SEC;
- }
- #else
- if (PE_CD_GetDecoderCurrentLocationMSF(eRelativeLocation,
- &uMinute, &uSecond, &uFrame, &iSign))
- {
- int iCurrentTime= (int)(iSign * ((60 * uMinute) + uSecond));
- if (iSign < 0)
- iCurrentTime--;
-
- if( iCurrentTime < 0)
- iCurrentTime = 0;
- SHARED_INFO.iCurrentTime= iCurrentTime;
- }
- #endif//CDDA_GETTIME_FROM_DRIVER
- #endif //CDDA_USE_ABSOLUTE_TIME
- //updating the remaining time
- #ifdef CDDA_USE_ABSOLUTE_TIME
- SHARED_INFO.wRemainingPlaybackTime = SHARED_INFO.wTotalPlaybackTime - (WORD)(SHARED_INFO.iCurrentTime);
- #else
- tiCurrTrack.ulBlocksCnt = 0;
-
- Array_getAt(g_hTrackInfoCache, (SHARED_INFO.uCurrentTrackNumber - 1), (BYTE *)&tiCurrTrack);
- SHARED_INFO.wRemainingPlaybackTime = (WORD)((WORD)(tiCurrTrack.ulBlocksCnt / CDDA_BLOCKS_PER_SEC) - (WORD)(SHARED_INFO.iCurrentTime));
- #endif //CDDA_USE_ABSOLUTE_TIME
- #ifdef GET_CDDTS_MSF_FROM_DRIVE
- if ( g_bIsCDDTS ){
- tiCurrTrack.ulBlocksCnt = 0;
- Array_getAt(g_hTrackInfoCache, (SHARED_INFO.uCurrentTrackNumber - 1), (BYTE *)&tiCurrTrack);
- SHARED_INFO.iCurrentTime = (int)((dwCDDTSCurrLocation - tiCurrTrack.dwStartAddress )/(DWORD)CDDA_BLOCKS_PER_SEC);
- SHARED_INFO.wRemainingPlaybackTime = (WORD)( (tiCurrTrack.dwStartAddress + (DWORD)tiCurrTrack.ulBlocksCnt- dwCDDTSCurrLocation)/(DWORD)CDDA_BLOCKS_PER_SEC);
- //<<<ML 051003 for cddts,get time from driver
- if (dwCurrLocation < tiCurrTrack.dwStartAddress || dwCurrLocation > tiCurrTrack.dwStartAddress+tiCurrTrack.ulBlocksCnt)
- {
- if ((1 == SHARED_INFO.uCurrentTrackNumber) && ((PST_SCAN == gcs.pstate) &&(g_pCDDANav->m_iScanSpeed < 0)))
- {
- dwCurrLocation = tiCurrTrack.dwStartAddress;
- }
- else
- {
- bTrackTransitionDetected= TRUE;
- for (ucTrackNumber=1;ucTrackNumber<=PE_CD_GetTracksCnt();ucTrackNumber++)
- {
- TrackInfo Track;
- DWORD o_pStartAddr;
- ULONG o_pSize;
-
- PE_CD_GetTrackTOC(ucTrackNumber, &ucCtrlField, &o_pStartAddr, &o_pSize);
-
- if( dwCurrLocation >= o_pStartAddr && dwCurrLocation < ( o_pStartAddr + o_pSize ))
- break;
- }
-
- if (ucTrackNumber > PE_CD_GetTracksCnt())
- ucTrackNumber = 1;
- }
- }
-
- SHARED_INFO.ucCurrentTrackInfo= ucCtrlField;
- // Update the S/PDIF Audio information
- PE_CD_UpdateAudioSPDIF();
- //>>>ML 051003 for cddts,get time from driver
- }
- #endif//GET_CDDTS_MSF_FROM_DRIVE
- // Update Track information
- #ifdef CDDA_GETTIME_FROM_DRIVER
- {
- if (dwCurrLocation < tiCurrTrack.dwStartAddress || dwCurrLocation > tiCurrTrack.dwStartAddress+tiCurrTrack.ulBlocksCnt)
- {
- if ((1 == SHARED_INFO.uCurrentTrackNumber) && ((PST_SCAN == gcs.pstate) &&(g_pCDDANav->m_iScanSpeed < 0)))
- {
- #ifndef CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- dwCurrLocation = tiCurrTrack.dwStartAddress;
- #endif
- }
- else
- {
- bTrackTransitionDetected= TRUE;
- for (ucTrackNumber=1;ucTrackNumber<=PE_CD_GetTracksCnt();ucTrackNumber++)
- {
- TrackInfo Track;
- DWORD o_pStartAddr;
- ULONG o_pSize;
-
- PE_CD_GetTrackTOC(ucTrackNumber, &ucCtrlField, &o_pStartAddr, &o_pSize);
-
- if( dwCurrLocation >= o_pStartAddr && dwCurrLocation < ( o_pStartAddr + o_pSize ))
- break;
- }
-
- if (ucTrackNumber > PE_CD_GetTracksCnt())
- ucTrackNumber = 1;
- }
- }
- #ifdef CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- //checking if the current track is a data track, meaning it should not be played
- if ((ucCtrlField & 0x0D) == 0x04) {
- PE_CD_SetMute(TRUE);
- }
- else {
- PE_CD_SetMute(FALSE);
- }
- #endif //CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- SHARED_INFO.ucCurrentTrackInfo= ucCtrlField;
- // Update the S/PDIF Audio information
- PE_CD_UpdateAudioSPDIF();
- }
- #else//#ifdef CDDA_GETTIME_FROM_DRIVER
- if (PE_CD_GetDecoderCurrentTrackInfo(&ucCtrlField, &ucTrackNumber)) {
- // Detect a Track-transition
- if ( ((WORD)ucTrackNumber != SHARED_INFO.uCurrentTrackNumber) && (0 != ucTrackNumber) )
- {
- PE_CD_ResetDecoderCurrentLocationMSF(); //ZCO LC040303: Clear old subcode info.
- if (( g_pCDDANav->ucCDDATrackChangeDetectionCounter != 0xFF ) && ( g_pCDDANav->ucCDDATrackChangeDetectionCounter-- == 0 )){
- bTrackTransitionDetected= TRUE;
- }
- }
- #ifdef EXINO2
- // When repeat single, playback the next track a short time in specific disc.
- if( PM_IsRepeatSingle() && PE_CD_GetCurrentLocation() > g_pCDDANav->m_aCurrTrack[1] )
- {
- PE_CD_SetMute(TRUE);
- bTrackTransitionDetected= TRUE;
- }
- #endif
- #ifdef CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- //checking if the current track is a data track, meaning it should not be played
- if ((ucCtrlField & 0x0D) == 0x04) {
- PE_CD_SetMute(TRUE);
- }
- else {
- PE_CD_SetMute(FALSE);
- }
- #endif //CDDA_SILENT_PLAYBACK_OF_DATA_TRACKS
- SHARED_INFO.ucCurrentTrackInfo= ucCtrlField;
- // Update the S/PDIF Audio information
- PE_CD_UpdateAudioSPDIF();
- }
- #endif//CDDA_GETTIME_FROM_DRIVER
- }
- // Check for normal Finish condition
- // ZCO SH021903:Added condition "&& (gns.cdda.iCurrentTime != 0)" to avoid system sending
- // "Playback finishied" event, when drive is just starting to play new track.
- // Wrong phenomenon happens when from NSPB, user press Stop twice and quickly press PLAY to restart NSPB
- // <<< SEC shKang050804 : because gns.cdda.iCurrentTime is zero, cannot go to the next track in shuffle mode.
- // So check the gns.cdda.iCurrentTime only for normal playback mode.
- #ifdef EXINO2
- if ( ((PST_PLAY == gcs.pstate) && PE_CD_IsPlaybackFinished() &&
- ((gns.cdda.iCurrentTime != 0 && PM_IsPlaybackNormal(PM_GetPlaybackMode())) || (!PM_IsPlaybackNormal(PM_GetPlaybackMode()))) )
- ||((PST_SCAN == gcs.pstate) && PE_CD_IsPlaybackFinished())
- ||((PST_PLAY == gcs.pstate) && (INTRO_PLAYBACK_TIME == gns.cdda.iCurrentTime) && ((TRUE == SHARED_INFO.bIsCDDAIntroMode)))
- ||((PST_SCAN == gcs.pstate) && (INTRO_PLAYBACK_TIME <= SHARED_INFO.iCurrentTime) && ((TRUE == SHARED_INFO.bIsCDDAIntroMode)))//ML0714 add for scanning in intro mode
- )
- #else // EXINO2
- if ( ((PST_PLAY == gcs.pstate) && PE_CD_IsPlaybackFinished() && (gns.cdda.iCurrentTime != 0))
- ||((PST_SCAN == gcs.pstate) && PE_CD_IsPlaybackFinished())
- ||((PST_PLAY == gcs.pstate) && (INTRO_PLAYBACK_TIME == gns.cdda.iCurrentTime) && ((TRUE == SHARED_INFO.bIsCDDAIntroMode)))
- ||((PST_SCAN == gcs.pstate) && (INTRO_PLAYBACK_TIME <= SHARED_INFO.iCurrentTime) && ((TRUE == SHARED_INFO.bIsCDDAIntroMode)))//ML0714 add for scanning in intro mode
- )
- #endif // EXINO2
- // SEC shKang050804 >>>
- {
- if (IE_CORE_CDNAV_FINISHED != g_pCDDANav->m_evPendingEvent) {
- #ifdef WATCHDOG_TRIGGERED_BY_FE
- if ( ucDriveErrorMsgCount > 0 )
- return;
- #endif
- g_pCDDANav->m_evPendingEvent= IE_CORE_CDNAV_FINISHED;
- ie_send(IE_CORE_CDNAV_FINISHED);
- usleep(50000UL);
- }
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- // Call for Error-Recovery, if needed
- PerformErrorRecovery();
- #endif
- return;
- }
- // Check if there is a Location-Change in progress
- if (g_pCDDANav->m_bLocationChanging) {
- DWORD dwTargetRangeLow, dwTargetRangeHigh;
- // Check whether the Location-Change has been completed
- if ((PST_SCAN == gcs.pstate) && (g_pCDDANav->m_iScanSpeed < 0)) {
- // Backwards Scanning
- dwTargetRangeLow= (g_pCDDANav->m_dwTargetLocation - CDDA_POSITION_TOLERANCE +
- (g_pCDDANav->m_iScanSpeed * CDDA_BLOCKS_PER_SEC*2));
- dwTargetRangeHigh= g_pCDDANav->m_dwTargetLocation;
- }
- else {
- // Normal playback or Forward Scanning
- dwTargetRangeLow= g_pCDDANav->m_dwTargetLocation;
- dwTargetRangeHigh= (g_pCDDANav->m_dwTargetLocation + CDDA_POSITION_TOLERANCE +
- (g_pCDDANav->m_iScanSpeed * CDDA_BLOCKS_PER_SEC));
- }
- // If the Location-Change has finished, then signal this. Otherwise,
- // nothing else to do.
- #ifdef CDDA_PAUSE_ENABLED_FOR_SCAN
- if (dwCurrLocation >= dwTargetRangeLow)
- g_pCDDANav->m_bLocationChanging= FALSE;
- #else
- if ((dwCurrLocation >= dwTargetRangeLow) && (dwCurrLocation < dwTargetRangeHigh))
- g_pCDDANav->m_bLocationChanging= FALSE;
- #endif
- else {
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- // Call for Error-Recovery, if needed
- PerformErrorRecovery();
- return;
- #endif
- }
- }
- // Update the COP_MASK with regard to the Next-Chapter operation
- SET_COP_MASK(COP_NEXT_CHAPTER);
- // Update the COP_MASK with regard to the Pre-Chapter operation
- SET_COP_MASK(COP_PREVIOUS_CHAPTER);
- #ifndef CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- if (! PM_IsRepeatAll() &&
- ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (PM_GetProgramSize() - 1)))
- {
- // If the Current-Item is the last one on the Program-List, then Next is not allowed
- CLEAR_COP_MASK(COP_NEXT_CHAPTER);
- }
- //angieh_0324_2004:For Alco,support previous func when play the first track.
- #ifndef SKIP_TO_THE_BEGINING
- if (! PM_IsRepeatAll() &&
- ((g_pCDDANav->m_CurrPosition).iPlaylistItem == 1))
- {
- // If the Current-Item is the first one on the Program-List, then Pre is not allowed
- CLEAR_COP_MASK(COP_PREVIOUS_CHAPTER);
- }
- #endif //CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- #endif //CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- // Check for a Position-Rendezvous condition, or a special Finish condition.
- // Take care of A-B Repeat
- if (PM_GetRepeatAB() & PM_REPEAT_AB_B) {
- if ((PST_SCAN == gcs.pstate) && (g_pCDDANav->m_iScanSpeed < 0)) {
- // Handle a Backwards-scan (in this case, look for Position-A, rather than Position-B)
- if ((dwCurrLocation <= (g_pCDDANav->m_PositionA).dwAddress) &&
- ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (g_pCDDANav->m_PositionA).iPlaylistItem))
- {
- evEvent= IE_CORE_CDNAV_RENDEZVOUS;
- EventParam= (void *)ePositionA;
- }
- }
- else if (((g_pCDDANav->m_PositionB).dwAddress < dwCurrLocation) &&
- ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (g_pCDDANav->m_PositionB).iPlaylistItem))
- {
- // For Forward-scan, of Normal speed playback, look for Position-B
- if (0 == CDDAMessageGap.MARKABReachGap)
- {
- evEvent= IE_CORE_CDNAV_RENDEZVOUS;
- EventParam= (void *)ePositionB;
- CDDAMessageGap.MARKABReachGap = MARKAB_FINISH_GAP;
- }
- }
- if (CDDAMessageGap.MARKABReachGap > 0)
- CDDAMessageGap.MARKABReachGap--;
- }
- else if (PM_GetRepeatAB() & PM_REPEAT_AB_A) {
- // Only Position-A is set:
- // If the Current position precedes Position-A (e.g. during Backwards-scan),
- // then cancel the setting.
- if (((dwCurrLocation + DRIVER_SEEK_MARGIN) <= (g_pCDDANav->m_PositionA).dwAddress) &&
- ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (g_pCDDANav->m_PositionA).iPlaylistItem))
- {
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- core_report_error( IE_UI_REPORT_ERROR, (void *)CDNAV_ERR_REPEAT_AB_PROHIBIT );
- }
- else
- {
- if((g_pCDDANav->m_CurrPosition).iPlaylistItem != (g_pCDDANav->m_PositionA).iPlaylistItem)
- {
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- }
- }
- }
- #ifdef CDDA_DEEMPHASIS_ENABLE
- if(uPrevTrackNumber != gns.cdda.uCurrentTrackNumber)
- {
- UINT8 uTrackCtrlField;
- UINT32 uDummy;
-
- uPrevTrackNumber = gns.cdda.uCurrentTrackNumber;
-
- PE_CD_GetTrackTOC(uPrevTrackNumber, &ucCtrlField, &uDummy, &uDummy);
- #ifndef EXINO2 //ZKR ML220404 S1 Deemphisis set
- if (ucCtrlField&0x10)
- PE_CD_SetDeemphasis(TRUE);
- else
- PE_CD_SetDeemphasis(FALSE);
- #else
- #ifdef DAC_DSD1608
- if (ucCtrlField&0x01)
- PE_CD_SetDeemphasis(TRUE);
- else
- PE_CD_SetDeemphasis(FALSE);
- #endif
- #endif
- }
- #endif
- // Take care of End-of-Item (Track Transition)
- if (bTrackTransitionDetected) {
- // Check if there is a Rendezvous-point scheduled for the new Track
- if (ucTrackNumber == g_pCDDANav->m_uRendezvousPoint) {
- // Report a Rendezvous only if the current Playback Mode is neither Program
- // nor Shuffle (in which cases, the playback should be terminated immediately).
- if (PM_IsPlaybackProgram(g_pCDDANav->m_uCurrPlaybackMode) ||
- PM_IsPlaybackShuffle(g_pCDDANav->m_uCurrPlaybackMode))
- {
- evEvent= IE_CORE_CDNAV_FINISHED;
- }
- else {
- evEvent= IE_CORE_CDNAV_RENDEZVOUS;
- EventParam= (void *)eEndOfItem;
- }
- }
- else {
- // There was no Rendezvous-point shceduled
- if ((PST_PLAY == gcs.pstate) &&
- (PM_IsPlaybackProgram(g_pCDDANav->m_uCurrPlaybackMode) ||
- PM_IsPlaybackShuffle(g_pCDDANav->m_uCurrPlaybackMode)))
- {
- // For Normal playback during Program or Shuffle, there's need to
- // terminate playback immediately.
- //<<<LX102502: Track number is not udpated during drive seek, still holding previous track no.
- //need to double check it
- dbg_printf(("ucTrackNumber = %02x, SHARED_INFO.uCurrentTrackNumber = %02xn", ucTrackNumber, SHARED_INFO.uCurrentTrackNumber));
- if ( ucTrackNumber == ( SHARED_INFO.uCurrentTrackNumber + 1 ) ){
- evEvent= IE_CORE_CDNAV_FINISHED;
- }else
- dbg_printf(("Not issue playback finished during seekingn"));
- //LX102502>>>
- }
- else if (PST_SCAN == gcs.pstate) {
- // For Scanning, check the current Playback-Mode
- if (PM_IsRepeatSingle()) {
- // For Repeat-Single terminate playback immediately
- evEvent= IE_CORE_CDNAV_FINISHED;
- }
- else {
- // For any other Playback-Mode, just update the global information (i.e.
- // the new Track Number) - this cannot be done elsewhere, because Track
- // Transition might occur before the actual end of the Track as reported
- // in the TOC (when the Index field is 00).
- SHARED_INFO.uCurrentTrackNumber= ucTrackNumber;
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_6;
-
- #ifdef CDTEXT_SUPPORT
- SHARED_INFO.pTrackCDText= (UINT32)PE_CD_GetCDTEXTInfo(ucTrackNumber);
- #ifdef _DEBUG
- if (SHARED_INFO.pTrackCDText) {
- dbg_printf(("Track #%d name: %sn", SHARED_INFO.uCurrentTrackNumber, SHARED_INFO.pTrackCDText));
- }
- #endif //_DEBUG
- #endif //CDTEXT_SUPPORT
- }
- }
- #ifdef EXINO2
- // in disc repeat, final song play-> fist song play -> second play -> stop VFD bug fixed
- else if((PST_PLAY == gcs.pstate) &&PM_IsRepeatAll() )
- {
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_6;
- }
- #endif
- }
- }
- // Send any Event needed, as long as it is not already pending
- if ( (evEvent != g_pCDDANav->m_evPendingEvent) && ( 0 != evEvent ) ){//LX102902: Not send 0 event to RTOS
- g_pCDDANav->m_evPendingEvent= evEvent;
- ie_send_ex(evEvent, EventParam);
- }
- #ifndef WATCHDOG_TRIGGERED_BY_FE
- // Call for Error-Recovery, if needed
- PerformErrorRecovery();
- #endif
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnPlay() -
- // Handles an IE_CORE_PLAY Event.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- static void OnPlay()
- {
- dbg_printf(("OnPlay()n"));
- if(! IS_COP_ENABLE( COP_SETUP )) //kz 07082002
- SET_COP_MASK( COP_SETUP);
- // Make sure that there's really need to invoke playback
- if (PST_PLAY == gcs.pstate) {
- dbg_printf(("Already in Playback state. Ignoredn"));
- return;
- }
- #ifdef CDDA_DISPLAY_BACKGROUND_DURING_PLAYBACK
- // Display the Background, if needed
- if (PST_STOP == gcs.pstate)
- PE_CD_DisplayBackground(TRUE);
- #endif //CDDA_DISPLAY_BACKGROUND_DURING_PLAYBACK
- if (PST_PAUSE == gcs.pstate) {
- PE_CD_PausePlayback(FALSE, g_pCDDANav->m_eCurrAudSID);
- gcs.pstate= PST_PLAY;
- return;
- }
- if (PST_SCAN == gcs.pstate) {
- // Resume Normal playback, from the current location
- (g_pCDDANav->m_CurrPosition).dwAddress= PE_CD_GetDecoderCurrentLocationLBN();
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Cancel the on-going Scan
- OnScan(0);
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to resume Normal-Speed Playback.n"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- // Check if the playback needs to be resumed from a previously recorded position
- if (-1 != (g_pCDDANav->m_ResumePlayback).dwAddress) {
- dbg_printf(("Resuming playbackn"));
- memcpy(&(g_pCDDANav->m_CurrPosition), &(g_pCDDANav->m_ResumePlayback), sizeof(CDDA_Marker));
- ClearMarker(eResumePlayback, 0); // Mark that this Marker has been used
- }
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Error: Failed to invoke playbackn"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnPlaybackFinished() -
- // Handles an IE_CORE_CDNAV_FINISHED Event.
- //
- // Input:
- //
- // Output:
- // None.
- //
- // Remarks:
- // An Event of type PLAYBACK_FINISHED is encountered when the PE has finished presenting
- // the entire segemnt which was previously requested by a call to InvokePlayback().
- // This happens at the end of a linear-Track-sequence.
- //
- // This method is responsible for selecting the next linear-Track-sequence to play, or
- // rewinding to the beginning of the Playlist (if the last item has been reached).
- static void OnPlaybackFinished()
- {
- BOOL bCancelOngoingScanning;
- dbg_printf(("OnPlaybackFinished()n"));
- // Force a Full-Stop, just in case
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Cancel Error-Recovery
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= 0;
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
- // Determine whether or not ongoing Scanning should be cancelled
- if (PM_IsPlaybackProgram(g_pCDDANav->m_uCurrPlaybackMode) ||
- PM_IsPlaybackShuffle(g_pCDDANav->m_uCurrPlaybackMode))
- {
- #ifdef CDDA_PROHIBIT_SCAN_ACROSS_PROGRAM_ENTRIES
- // For Program or Shuffle Playback, always cancel any ongoing Scanning
- bCancelOngoingScanning= TRUE;
- #else
- bCancelOngoingScanning= FALSE;
- #endif //CDDA_PROHIBIT_SCAN_ACROSS_PROGRAM_ENTRIES
- }
- else
- {
- #ifdef CDDA_PROHIBIT_SCAN_ACROSS_TRACK_BOUNDARIES
- bCancelOngoingScanning= TRUE;
- #else
- bCancelOngoingScanning= FALSE;
- #endif //CDDA_PROHIBIT_SCAN_ACROSS_TRACK_BOUNDARIES
- }
- // Take care of Backwards Scanning
- if ((PST_SCAN == gcs.pstate) && (g_pCDDANav->m_iScanSpeed < 0)) {
- if (bCancelOngoingScanning) {
- // Stop Scanning, and resume Normal playback
- OnScan(0);
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to playback the next itemn"));
- gcs.pstate= PST_STOP;
- }
- ie_send(IE_UI_STATE_CHANGE);
- }
- else {
- // Continue Scanning, if appropriate
- if ((1 == (g_pCDDANav->m_CurrPosition).iPlaylistItem) || PM_IsRepeatSingle()) {
- // If this is the first item, or if there's need to repeat
- // the current Track, then resume normal playback from the beginning.
- OnScan(0);
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to playback the next itemn"));
- gcs.pstate= PST_STOP;
- }
- ie_send(IE_UI_STATE_CHANGE);
- }
- else {
- // Switch to the previous Item on the Program-List, while scanning
- WORD wCurrentTrackNumber= PM_GetProgramListEntry(--((g_pCDDANav->m_CurrPosition).iPlaylistItem));
- ScanTrack(wCurrentTrackNumber);
- }
- }
- return;
- }
- // Take care of Forward Playback/Scanning
- if ((PST_SCAN == gcs.pstate) && bCancelOngoingScanning) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- ie_send(IE_UI_STATE_CHANGE);
- }
- // Check for a pending Playback-Mode change
- if (g_pCDDANav->m_bPendingModeChange)
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Check if the Playback-Mode is "Single Repeat". If so, reschedule playback of the
- // current Playlist-Item again. This check is essential for the special case where the last
- // item on a Linear-Sequence or Playlist needs to be repeated.
- if (PM_IsRepeatSingle()) {
- // Resume Normal playback, if scanning
- if (PST_SCAN == gcs.pstate) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- ie_send(IE_UI_STATE_CHANGE);
- }
- if (! InvokePlayback()) {
- dbg_printf(("Error: Failed to invoke playbackn"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- // Check if the end of the Playlist has been reached. If so, then rewind the
- // Playlist. If the Playback-Mode is REPEAT_ALL, then also re-invoke the playback.
- if (++((g_pCDDANav->m_CurrPosition).iPlaylistItem) > (int)(PM_GetProgramSize() - 1)) {
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- // Cancel AB-Repeat, in case only Position-A was set
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- // If the current playback-mode is not "Repeat All", then don't re-invoke the playback
- if (! PM_IsRepeatAll()
- //jeanz_2004_0916 For cdda repeat program
- #ifdef D_REPEAT_PROGRAM_MODE
- && (PM_GetPlaybackMode() != PM_PLAYBACK_PROGRAM)
- #endif
- ) {
- OnStop(eFullStop);
- ie_send(IE_UI_STATE_CHANGE);
- return;
- }
- // Resume Normal playback, if Scanning
- if (PST_SCAN == gcs.pstate) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- ie_send(IE_UI_STATE_CHANGE);
- }
- }
-
- // Extract the Track-information for the current playlist-item
- SHARED_INFO.uCurrentTrackNumber = PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem);
- // Invoke playback of the next item(s) on the playlist
- if (PST_SCAN == gcs.pstate) {
- // Schedule a forward-scan of the current Item
- ScanTrack(PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem));
- }
- else {
- // Play-back the current Item from its beginning
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to play-back the next itemn"));
- gcs.pstate= PST_STOP;
- }
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // OnStop(enCDDA_StopType eType) -
- // Handles an IE_CORE_PAUSE or IE_CORE_STOP or IE_CORE_FULL_STOP Event.
- //
- // Input:
- // eType - The type of requested Stop
- //
- // Output:
- // None.
- static void OnStop(enCDDA_StopType eType)
- {
- dbg_printf(("OnStop()n"));
- switch (eType)
- {
- case ePause:
- dbg_printf(("OnPause()n"));
- if (PST_SCAN == gcs.pstate) {
- // First, cancel Scanning
- // OnScan(0);
- // Now, Abort playback
- PE_CD_AbortPlayback(TRUE);
- //#ifdef CDDA_MUTE_ON_SCAN
- // Force Mute, since the Playback is about to be re-invoked
- if (CdMedia_Macro.bCDDA_MUTE_ON_SCAN)
- {
- PE_CD_SetMute(TRUE);
- }
- //#else
- #ifdef CDDTS_MUTE_ON_SCAN
- if (g_pCDDANav->m_eCurrAudSID == CDDTS_SID)
- // Force Mute, since the Playback is about to be re-invoked
- PE_CD_SetMute(TRUE);
- #endif //CDDTS_MUTE_ON_SCAN
- //#endif //CDDA_MUTE_ON_SCAN
- // And now, re-invoke Playback from the same position, to allow resuming
- // of the Playback later.
- (g_pCDDANav->m_CurrPosition).dwAddress= PE_CD_GetDecoderCurrentLocationLBN();
- PE_CD_SetScan(FALSE, g_pCDDANav->m_eCurrAudSID, 0);
-
- if (! InvokePlayback()) {
- dbg_printf(("Failed to re-invoke Playback.n"));
- }
- }
- PE_CD_PausePlayback(TRUE, g_pCDDANav->m_eCurrAudSID);
- #ifdef CDDA_MUTE_ON_SCAN
- // Cancel existing Mute, if any
- // if ( !g_bIsCDDTS ){
- // tr_printf(("Cancel Mute from Scan to Pausen"));
- // PE_CD_SetMute(FALSE);
- // }
- #else
- #ifdef CDDTS_MUTE_ON_SCAN
- if (g_pCDDANav->m_eCurrAudSID == CDDTS_SID)
- // Force Mute, since the Playback is about to be re-invoked
- PE_CD_SetMute(FALSE);
- #endif //CDDTS_MUTE_ON_SCAN
- #endif //CDDA_MUTE_ON_SCAN
- gcs.pstate= PST_PAUSE;
- break;
- case eStopResume:
- dbg_printf(("Stopping playback. Current-position recorded:%dn",eType));
- case eFullStop:
- g_pCDDANav->m_uRendezvousPoint= 0; // Purge pending notification requests
- if (eStopResume == eType)
- {
- #ifdef D_CD_GRAPHIC_ENABLED
- //let CDG stop resume from current track instead of first track
- if( gcst.mCDGDetected )
- ClearMarker(eResumePlayback, 0);
- else
- #endif
- SetMarker(eResumePlayback, 0);
- }
- else
- {
- #ifndef K1_WL
- ClearMarker(eResumePlayback, 0);
- #endif
- //add by wl033004 for set the play mode to normal after full stop
- #ifdef K1_WL
- if ( PM_IsPlaybackProgram(PM_GetPlaybackMode()) || PM_IsPlaybackIntro(PM_GetPlaybackMode())
- #ifdef D_ENABLE_SHUFFLE_MODE
- || PM_IsPlaybackShuffle(PM_GetPlaybackMode())
- #endif
- )
- {
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- mode_set_private_program_size(0);
- OnModeChange();
- }
- #endif
- //add by wl033004 for set the play mode to normal after full stop
- // Rewind the Current-Position to the Program-Beginning
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- (g_pCDDANav->m_CurrPosition).dwAddress= -1;
- // <<< ZCO SH021903:Clean Error recovery info after full stop
- // Limit also wrong behavior of system when restart NSPB after pressing twice STOP and then quickly PLAY.
- g_pCDDANav->m_dwTargetLocation = -1;
- // ZCO SH021903 >>>
- // ZCO SH021903:Reset subcode info after a full stop
- // Avoid system reading outdated subcode information.
- PE_CD_ResetDecoderCurrentLocationMSF();
- #ifdef EXINO2
- g_in_full_stop = TRUE;
- #endif // EXINO2
- }
- PE_CD_AbortPlayback((eStopResume == eType) ? TRUE : FALSE);
- if (PST_STOP != gcs.pstate) {
- PE_CD_SetScan(FALSE, g_pCDDANav->m_eCurrAudSID, 0);
- // Cancel Scanning
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- gcs.pstate= PST_STOP;
- // Cancel any current Repeat-Modes
- if (eStopResume != eType) //BT0407: only full stop cancel repeat mode
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- // Cancel pending Mode-Changes
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Display the Logo
- PE_CD_DisplayLogo();
- }
-
- SHARED_INFO.bIsCDDAIntroMode = FALSE;
- break;
- }
- // Disable Error-Recovery
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= 0;
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= 0;
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnRendezvousPoint() -
- // Handles an IE_CORE_CDNAV_RENDEZVOUS Event.
- //
- // Input:
- // None.
- // Output:
- // None.
- //
- // Remarks:
- // An Event of type RENDEZVOUS_POINT is encountered when the PE has reached a predefined
- // point in the playback, which was previously determined by InvokePlayback().
- // This happens only on the boundaries of two sequencial Tracks/Play-Items, or when reaching
- // Position-A/B when in "Repeat A->B" Playback-Mode.
- //
- // When such an event occurs, there's need to either repeat the current Item (if
- // the Playback-Mode is REPEAT_SINGLE), or to continue playback of the next item.
- // In the latter, there's no need to repeat the request from the PE, but there is need
- // to update the internal value of m_iCurrPlaylistItem and to schedule a new Rendezvous-Point,
- // if appropriate.
- //
- // If the event occurs within the context of a "Repeat A->B" Playback-Mode, then there's need
- // to check whether Position-A/B has been reached. If yes, the playback is restarted from Position-A.
- // Otherwise, if Position-B is located within the next item, an appropriate Rendezvous-Point is set.
- static void OnRendezvousPoint(enCDDA_RendezvousType eType)
- {
- dbg_printf(("OnRendezvousPoint()n"));
- if ((ePositionA == eType) || (ePositionB == eType)) {
- dbg_printf(("Position%c encountered.n", (ePositionA == eType) ? 'A' : 'B'));
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Rewind to Position-A
- memcpy(&(g_pCDDANav->m_CurrPosition), &(g_pCDDANav->m_PositionA), sizeof(CDDA_Marker));
- // Eliminate any on-going Scanning
- if (PST_SCAN == gcs.pstate) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- }
- // Restart playback from Position-A
- if (! InvokePlayback()) {
- dbg_printf(("Failed to playback the current listn"));
- gcs.pstate= PST_STOP;
- }
- //Give proper time to loader to fucus
- usleep(50000UL);
- return;
- }
- // this is for eType == EndOfItem
- g_pCDDANav->m_uRendezvousPoint= 0; // Purge pending notification requests
- // Check if the Playback-Mode is "Single Repeat". If so, abort the current playback and
- // reschedule playback of the current Playlist-Item again.
- if (PM_IsRepeatSingle()) {
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Cancel "Repeat AB" if it is in effect
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- if (! InvokePlayback()) {
- dbg_printf(("Error: Failed to invoke playbackn"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- // Check for a pending Playback-Mode change
- if (g_pCDDANav->m_bPendingModeChange) {
- // Force a playback-mode change by pretending that a Linear-Sequence has ended playback
- g_pCDDANav->m_bPendingModeChange= FALSE;
- OnPlaybackFinished();
- return;
- }
- // The Playback-Mode is either "Normal", or "Repeat A->B" provided that Position-B is not within the next item.
- // Therefore, continue playback of the next item on the Playlist, and if it's not the last
- // within a linear-sequence, reschedule a Rendezvous-Point.
- if (PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem+1) ==
- (1 + PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem)))
- {
- TrackInfo tiCurrTrack;
- DWORD dwCurrTrackStartAddress;
- ULONG ulCurrTrackSize;
- WORD uCurrTrackNumber= PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem+1);
- // Update Current-Track information
- Array_getAt(g_hTrackInfoCache, (uCurrTrackNumber - 1), (BYTE *)&tiCurrTrack);
- dwCurrTrackStartAddress = tiCurrTrack.dwStartAddress;
- ulCurrTrackSize = tiCurrTrack.ulBlocksCnt;
- g_pCDDANav->m_aCurrTrack[0]= dwCurrTrackStartAddress;
- g_pCDDANav->m_aCurrTrack[1]= (dwCurrTrackStartAddress + ulCurrTrackSize);
- // Schedule a new Rendezvous-point for the beginning of the next Item (Track)
- g_pCDDANav->m_uRendezvousPoint= (uCurrTrackNumber + 1);
- dbg_printf(("Scheduling a Rendezvous-Point for: %dn", (uCurrTrackNumber + 1)));
- // Update the global information
- SHARED_INFO.uCurrentTrackNumber= uCurrTrackNumber;
- //jeanz_0411_2005 Fix bug :stop randomly when a track is finished in shuffle mode.
- if(PM_IsRepeatSingle()||PM_IsPlaybackProgram(g_PlayModeInfo.iPlaybackMode) || PM_IsPlaybackShuffle(g_PlayModeInfo.iPlaybackMode))
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_2;
- else
- g_pCDDANav->ucCDDATrackChangeDetectionCounter = CDDA_TRACK_CHANGE_DETECTION_COUNTER_6;
- #ifdef CDTEXT_SUPPORT
- SHARED_INFO.pTrackCDText= (UINT32)PE_CD_GetCDTEXTInfo((BYTE)SHARED_INFO.uCurrentTrackNumber);
- #ifdef _DEBUG
- if (SHARED_INFO.pTrackCDText) {
- dbg_printf(("Track #%d name: %sn", SHARED_INFO.uCurrentTrackNumber, SHARED_INFO.pTrackCDText));
- }
- #endif //_DEBUG
- #endif //CDTEXT_SUPPORT
- }
- (g_pCDDANav->m_CurrPosition).iPlaylistItem++;
- return;
- }
- static void OnModeChange()
- {
- dbg_printf(("OnModeChangen"));
- // Find-out what kind of mode has changed: the Playback-Mode or the Repeat-Mode
- // If the change is not in Playback-Mode, then nothing to do.
- if (g_pCDDANav->m_uCurrPlaybackMode == PM_GetPlaybackMode()) {
- dbg_printf(("No Playback-Mode change detected.n"));
- return;
- }
- // In case of a Playback-Mode change, cancel all current Repeat Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- core_clear_bookmark_info( 0 ); // clear all bookmarks
- // Detect a transition of type: Non-Shuffle -> Shuffle
- if (! PM_IsPlaybackShuffle(g_pCDDANav->m_uCurrPlaybackMode) && PM_IsPlaybackShuffle(PM_GetPlaybackMode())) {
- dbg_printf(("Non_Shuffle -> Shufflen"));
- // If the current Playback-Status is other than Stopped, shuffle the Program-List while
- // keeping the current item as the first item
- if ( gcs.pstate == PST_STOP && g_in_full_stop == TRUE)
- PM_ShuffleProgramList(FALSE, 0);
- else
- {
- PM_ShuffleProgramList(TRUE, (g_pCDDANav->m_CurrPosition).iPlaylistItem);
- g_pCDDANav->m_ResumePlayback.iPlaylistItem = 1;
- }
-
- // Now set the Current-Item to Item #1
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- g_pCDDANav->m_bPendingModeChange= TRUE;
- }
- // Detect a transition of type: Non-Normal -> Normal
- if (! PM_IsPlaybackNormal(g_pCDDANav->m_uCurrPlaybackMode) && PM_IsPlaybackNormal(PM_GetPlaybackMode())) {
- UINT16 uEntriesCnt;
- WORD uEntry;
- WORD uCurrTrack= (WORD) PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem);
- dbg_printf(("Non_Normal -> Normaln"));
- // Rebuild the Normal Program-List (sequential playback of the Tracks)
- PM_InitializeProgramList();
- //uEntriesCnt= (UINT16)PE_CD_GetTracksCnt();
- uEntriesCnt = (UINT16)g_pCDDANav->m_uLastCDDA_Track;
- // Initialize the Program-List to sequencial playback
- for (uEntry= g_pCDDANav->m_uFirstCDDA_Track; uEntry <= uEntriesCnt; uEntry++)
- PM_SetProgramListEntry((WORD)(uEntry - g_pCDDANav->m_uFirstCDDA_Track + 1), (WORD)uEntry);
- // Now update the Current Item to point at the Entry holding the current-Track,
- // if playback is currently in progress
- if ( gcs.pstate == PST_STOP && g_in_full_stop == TRUE)
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- else
- {
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= (uCurrTrack - g_pCDDANav->m_uFirstCDDA_Track + 1);
- g_pCDDANav->m_ResumePlayback.iPlaylistItem = g_pCDDANav->m_CurrPosition.iPlaylistItem;
- }
-
- }
- // Detect a transition of type: Non-Program -> Program
- if (! PM_IsPlaybackProgram(g_pCDDANav->m_uCurrPlaybackMode) && PM_IsPlaybackProgram(PM_GetPlaybackMode())) {
- dbg_printf(("Non-Program ->Program n"));
-
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= 1;
- //if (PST_STOP != gcs.pstate) {
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- if(PST_SCAN == gcs.pstate)
- OnScan(0);
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to re-invoke playback after playback-mode changen"));
- gcs.pstate= PST_STOP;
- }
- //}
- //ML0703 remove this condition for cdda's program play being set in pst_stop state
- }
- // Update the current Playback-Mode
- g_pCDDANav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnSetMarkerA() -
- // Handles an event of setting the first Marker for an A->B Repeat sequence.
- //
- // Input:
- // None.
- // Output:
- // None.
- //
- // Remarks:
- // The method calls for the setting of the MarkerA Marker.
- static void OnSetMarkerA()
- {
- dbg_printf(("OnSetMarkAn"));
- SetMarker(eMarkerA, 0);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnSetMarkerB() -
- // Handles an event of setting the second Marker for an A->B Repeat sequence.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method calls for the setting of the MarkerB Marker, and then it initiates the
- // REPEAT_AB Play-Mode.
- static void OnSetMarkerB()
- {
- dbg_printf(("OnSetMarkB()n"));
- // First, record the current position as MarkerB and stop playback
- SetMarker(eMarkerB, 0);
- // Prohibit an A-B Segment of less than 1 Second
- if (((g_pCDDANav->m_PositionB).dwAddress - (g_pCDDANav->m_PositionA).dwAddress) < 2*CDDA_BLOCKS_PER_SEC)
- {
- // Force a 1 Second gap between Point-A and Point-B
- (g_pCDDANav->m_PositionB).dwAddress= (g_pCDDANav->m_PositionA).dwAddress + 2*CDDA_BLOCKS_PER_SEC;
- }
- // Stop Playback
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Move the Current-Position to Point-A
- memcpy(&(g_pCDDANav->m_CurrPosition), &(g_pCDDANav->m_PositionA), sizeof(CDDA_Marker));
- // Invoke A-B Repeat, and start Playback
- PM_SetRepeatAB(PM_REPEAT_AB_B);
- // Schedule a playback using the Markers just set
- if (! InvokePlayback()) {
- dbg_printf(("Error: Failed to invoke playbackn"));
- gcs.pstate= PST_STOP;
- }
- ie_send(IE_UI_STATE_CHANGE);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnCancelABRepeat() -
- // Handles an event of cancelling the current REPEAT_AB Play-Mode.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method aborts the current Play-Mode by clearing both MarkerA and MarkerB, and
- // removing the REPEAT_AB Bit from the Play-Mode mask.
- // In addition, the method will re-sechedule a Rendezvous-Point, if needed,
- // in order to assure correct playback of the following items.
- static void OnCancelABRepeat()
- {
- dbg_printf(("OnCancelABRepeat()n"));
- // Clear the current setting of both markers
- ClearMarker(eMarkerA, 0);
- ClearMarker(eMarkerB, 0);
- PM_SetRepeatAB(0);
- ie_send(IE_UI_STATE_CHANGE);
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnGoToBookmark(WORD uBookmarkNumber) -
- // Handles an event of jumping to a certain point in the disc and starting playback
- // from that point.
- //
- // Input:
- // uBookmarkNumber - The serial number of the Bookmark to use as a destination,
- // assuming that it was previously set during an event.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method performs a unconditional jump to the point in the Disc that is marked
- // by the requested Bookmark. This Bookmark should have been set earlier, during
- // the handling of an event of type IE_CORE_SETBOOKMARK.
- static void OnGoToBookmark(WORD uBookmarkNumber)
- {
- dbg_printf(("OnGoToBookmark(%d)n", uBookmarkNumber));
- // Cancel pending Mode-Changes
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Make sure that the requested Bookmark is still valid
- if ((uBookmarkNumber >= CDDA_MAX_BOOKMARKS) ||
- (-1 == (g_pCDDANav->m_Bookmarks[uBookmarkNumber]).iPlaylistItem)) {
- dbg_printf(("Bookmark #%d",(int)uBookmarkNumber));
- dbg_printf((" is invalid. Ignored.n"));
- return;
- }
- // Stop any ongoing playback
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Cancel any current Repeat-Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- g_pCDDANav->m_uRendezvousPoint= 0;
- // Set the Current-Position to hold the selected Bookmark
- memcpy(&(g_pCDDANav->m_CurrPosition), &(g_pCDDANav->m_Bookmarks[uBookmarkNumber]), sizeof(CDDA_Marker));
- if (PST_SCAN == gcs.pstate) {
- // Cancel the on-going Scan
- OnScan(0);
- }
- if (PST_STOP != gcs.pstate) {
- // Cancel pending Mode-Changes
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Display the Logo
- PE_CD_DisplayLogo();
- }
-
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to playback current listn"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- static void OnScan(int iSpeed)
- {
- WORD uCurrentTrackNumber;
- ULONG ulBlocksCnt= 0;
- DWORD dwCurrLocation;
- TrackInfo tiCurrTrack;
- dbg_printf(("OnScan(%d)n", iSpeed));
- if ((PST_PLAY != gcs.pstate) && (PST_SCAN != gcs.pstate) && (PST_PAUSE != gcs.pstate)) {
- dbg_printf(("Cannot scan during a stop. Ignoredn"));
- return;
- }
- //CL, avoid driver jump to a unknown area
- if ((iSpeed < 0) && (1 == SI_CDDA_TRACK_NUM) && (0 == SI_CDDA_ELAPSED_TIME))
- return;
- // Record the current Scanning-speed
- g_pCDDANav->m_iScanSpeed= iSpeed;//((iSpeed >= 0) ? iSpeed : (iSpeed - 1));
- if (0 == iSpeed)
- {
- // Cancel the Scanning
- PE_CD_SetScan(FALSE, g_pCDDANav->m_eCurrAudSID, 0);
-
- //#ifdef CDDA_MUTE_ON_SCAN
- if (CdMedia_Macro.bCDDA_MUTE_ON_SCAN)
- {
- PE_CD_SetMute(TRUE);
- if (PS_GET_ANALOG_AUDIO_SETTING()!=NO_ANALOG_AUDIO)
- {
- ;//DEC_EX_MUTEOff();//tecobest gxd 20051028
- }
- }
-
-
- //#else
- #ifdef CDDTS_MUTE_ON_SCAN)
- if (g_pCDDANav->m_eCurrAudSID == CDDTS_SID)
- // Force Mute, since the Playback is about to be re-invoked
- PE_CD_SetMute(FALSE);
- #endif
- //#endif //CDDA_MUTE_ON_SCAN
- return;
- }
- //#ifdef CDDA_MUTE_ON_SCAN
- if((CdMedia_Macro.bCDDA_MUTE_ON_SCAN)&&(PST_PAUSE == gcs.pstate))
- {
- tr_printf(("Mute on Pause to Scann"));
- PE_CD_SetMute(TRUE);
- }
- //#endif
- //ML 042303
- //For everytime call this function,reset the current position,no matter whether it is already PST_SCAN or not.
- // Record the current position
- dwCurrLocation= PE_CD_GetDecoderCurrentLocationLBN();
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- // Start actual Scanning
- gcs.pstate= PST_SCAN;
- PE_CD_SetScan(TRUE, g_pCDDANav->m_eCurrAudSID, g_pCDDANav->m_iScanSpeed);
- // Extract information on the current Track
- uCurrentTrackNumber= PM_GetProgramListEntry((g_pCDDANav->m_CurrPosition).iPlaylistItem);
- //pCurrTrack= &g_aTrackInfoCache[uCurrentTrackNumber-1];
- Array_getAt(g_hTrackInfoCache, (uCurrentTrackNumber - 1), (BYTE *)&tiCurrTrack);
- // Cancel any pending Rendezvous point (since the Track is going to be scanned
- // until its end).
- g_pCDDANav->m_uRendezvousPoint= 0;
- // Continue playback according to the Scanning-Direction
- if (iSpeed > 0) {
- ulBlocksCnt= ((tiCurrTrack.dwStartAddress + tiCurrTrack.ulBlocksCnt) - dwCurrLocation);
- g_pCDDANav->m_aCurrSegment[0]= dwCurrLocation;
- g_pCDDANav->m_aCurrSegment[1]= (dwCurrLocation + ulBlocksCnt);
- }
- else {
- ulBlocksCnt= (dwCurrLocation - tiCurrTrack.dwStartAddress);
- g_pCDDANav->m_aCurrSegment[0]= tiCurrTrack.dwStartAddress;
- g_pCDDANav->m_aCurrSegment[1]= dwCurrLocation;
- }
- // Record Current-Track information
- g_pCDDANav->m_aCurrTrack[0]= tiCurrTrack.dwStartAddress;
- g_pCDDANav->m_aCurrTrack[1]= (tiCurrTrack.dwStartAddress + tiCurrTrack.ulBlocksCnt);
- // Set-up the Error-Recovery Information
- (g_pCDDANav->m_ErrorRecoveryInfo).uTimeout= CDDA_PB_HANGUP_TIMEOUT;
- (g_pCDDANav->m_ErrorRecoveryInfo).dwParam= dwCurrLocation;
-
- #ifdef CDDA_ERROR_RECOVERY
- //Leslie_0118_2004_A: Task Force III, implement CDDA Navigator Watchdog
- (g_pCDDANav->m_ErrorRecoveryInfo).ucRetryCount = 0;
- #endif
-
- if (! PE_CD_PlaySegment(NoVideo, g_pCDDANav->m_eCurrAudSID, g_pCDDANav->m_aCurrSegment[0], ulBlocksCnt,
- eSearch, g_pCDDANav->m_iScanSpeed))
- {
- dbg_printf(("Failed to re-invoke playbackn"));
- gcs.pstate= PST_STOP;
- return;
- }
- //#ifdef CDDA_MUTE_ON_SCAN
- if(CdMedia_Macro.bCDDA_MUTE_ON_SCAN)
- {
- PE_CD_SetMute(TRUE);
- //DEC_EX_MUTEOn();//tecobest gxd 20051020
- }
- //#else
- #ifdef CDDTS_MUTE_ON_SCAN)
- if (g_pCDDANav->m_eCurrAudSID == CDDTS_SID)
- // Force Mute, since the Playback is about to be re-invoked
- PE_CD_SetMute(TRUE);
- #endif
- //#endif //CDDA_MUTE_ON_SCAN
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnNextItem() -
- // Handles an event of selecting the next item in the Play-List.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method jumps to the next item on the Play-List, if the current item is not
- // already the last item on the list.
- static void OnNextItem()
- {
- dbg_printf(("OnNext()n"));
- // Check the current Playback-Status. If in Stop-mode, then resume playback.
- if (PST_STOP == gcs.pstate) {
- // Resume playback from the Item's beginning
- (g_pCDDANav->m_ResumePlayback).dwAddress= -1;
- OnPlay();
- return;
- }
- // Cancel any Scanning
- if (PST_SCAN == gcs.pstate) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- }
- #ifdef EXINO2
- if (PST_PAUSE == gcs.pstate) {
- gcs.pstate= PST_PLAY; // Cancel pause
- }
- #endif
- // Take care of A-B Repeat
- if (PM_GetRepeatAB() & PM_REPEAT_AB_B) {
- // If the Current Playlist Item contains Position-B, then cancel A-B Repeat (A-B Loop
- // scope has been exceeded).
- if ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (g_pCDDANav->m_PositionB).iPlaylistItem)
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- }
- // Take care of the last Item on the Playlist
- if ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (int)(PM_GetProgramSize() - 1))
- {
- #ifdef CDDA_WRAP_AROUND_ON_PROGRAM_EDGES)
- // Set the Current Item to Zero, so that the first Item on the Play-List
- // will be used (i.e. a wrap-around is performed).
- g_pCDDANav->m_CurrPosition.iPlaylistItem= 0;
- #else
- // Wrap-around if Repeat-All is on
- if (PM_IsRepeatAll()) {
- g_pCDDANav->m_CurrPosition.iPlaylistItem= 0;
- }
- else
- if(PM_IsRepeatSingle())
- {
- ; //add this though we prohibit skipf at the last track upper already.
- }
- else
- {
- dbg_printf(("Already playing the last item on the playlist. Ignoredn"));
- return;
- }
- #endif //CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- }
- // Clear the Resume Marker and Rendezvous point
- ClearMarker(eResumePlayback, 0);
- g_pCDDANav->m_uRendezvousPoint= 0;
- // Cancel pending Mode-Changes
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Select the next Item
- #ifndef EXINO2
- if(!PM_IsRepeatSingle()) // if repeat track, return to current track start
- #endif
- (g_pCDDANav->m_CurrPosition).iPlaylistItem++;
- if (PST_STOP != gcs.pstate) {
- // Stop the current playback, and re-invoke playback at the next item
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- if (! InvokePlayback()) {
- dbg_printf(("Error: Failed to invoke playbackn"));
- gcs.pstate= PST_STOP;
- }
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnPreviousItem() -
- // Handles an event of selecting the Previous item in the Play-List.
- //
- // Input:
- // None.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method jumps to the previous item on the Play-List, if the current item is not
- // already the first item on the list.
- static void OnPreviousItem()
- {
- int iTimeFromTrackStart = 0;
- dbg_printf(("OnPrevious()n"));
- // Check the current Playback-Status. If in Stop-mode, then resume playback.
- if (PST_STOP == gcs.pstate) {
- // Resume playback from the Item's beginning
- (g_pCDDANav->m_ResumePlayback).dwAddress= -1;
- OnPlay();
- return;
- }
- // Cancel any Scanning
- if (PST_SCAN == gcs.pstate) {
- OnScan(0);
- gcs.pstate= PST_PLAY;
- }
- #ifdef EXINO2
- // Cancelled pause because of forward skip doing.
- if (PST_PAUSE == gcs.pstate) {
- gcs.pstate= PST_PLAY;
- }
- #endif
- #ifdef CDDA_USE_ABSOLUTE_TIME
- {
- TrackInfo tiCurrTrack;
- PE_CD_GetTrackInfo(gns.cdda.uCurrentTrackNumber, &tiCurrTrack);
- iTimeFromTrackStart = gns.cdda.iCurrentTime - (tiCurrTrack.dwStartAddress / CDDA_BLOCKS_PER_SEC);
- }
- #else
- iTimeFromTrackStart = gns.cdda.iCurrentTime;
- #endif //CDDA_USE_ABSOLUTE_TIME
- //<<<<<angieh_0324_2004:For Alco,support previous func when play the first track.
- #ifdef SKIP_TO_THE_BEGINING
- if ((iTimeFromTrackStart <= CDDA_SKIP_BACK_THRESHOLD) || (1 == g_pCDDANav->m_CurrPosition.iPlaylistItem))
- #else
- #ifdef D_USE_VARIABLE_FOR_LIB
- if (iTimeFromTrackStart <= cdda_skip_back_threshold)
- #else
- if (iTimeFromTrackStart <= CDDA_SKIP_BACK_THRESHOLD)
- #endif
- #endif
- //angieh_0324_2004>>>>>
- {
- // Take care of the first Item on the Playlist
- if (1 == g_pCDDANav->m_CurrPosition.iPlaylistItem) {
- // Cancel A-B Repeat (if any)
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- #ifdef CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- // Set the Current Item to one past the Last item on the Play-List (i.e.
- // wrap-around is performed).
- g_pCDDANav->m_CurrPosition.iPlaylistItem= PM_GetProgramSize()-1;
- #else
- g_pCDDANav->m_CurrPosition.iPlaylistItem= 1;
- //dbg_printf(("Currently playing the first item on the Playlist. Ignored.n"));
- //return; //kz 07092002
- #endif //CDDA_WRAP_AROUND_ON_PROGRAM_EDGES
- }
- else //kz 07092002
- // Select the previous Item
- #ifdef EXINO2
- // if current elapsed time is smaller than 4sec, go to the top of the current track.
- if(/*!PM_IsRepeatSingle() && */SI_CDDA_ELAPSED_TIME < 4 ) // if repeat track, return to current track start
- #else
- if(!PM_IsRepeatSingle()) // if repeat track, return to current track start
- #endif
- g_pCDDANav->m_CurrPosition.iPlaylistItem--;
- }
- // Take care of A-B Repeat
- if (PM_GetRepeatAB() & PM_REPEAT_AB_B) {
- // If the Previous Playlist Item contains Position-A, then cancel A-B Repeat (A-B Loop
- // scope has been exceeded).
- if ((g_pCDDANav->m_CurrPosition).iPlaylistItem == (g_pCDDANav->m_PositionA).iPlaylistItem)
- CancelRepeatModes(PM_REPEAT_AB_MASK);
- }
- // Clear the Resume Marker and Rendezvous point
- ClearMarker(eResumePlayback, 0);
- g_pCDDANav->m_uRendezvousPoint= 0;
- // Cancel pending Mode-Changes
- g_pCDDANav->m_bPendingModeChange= FALSE;
- if (PST_STOP != gcs.pstate) {
- // Stop the current playback, and re-invoke playback at the next item
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- if (! InvokePlayback()) {
- dbg_printf(("ERROR: Failed to invoke playback.n"));
- gcs.pstate= PST_STOP;
- }
- }
- return;
- }
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // void OnNumericSelection(ULONG ulSelectedTrackNumber) -
- // Handles either a IE_CORE_GOTO_ENTRY or a IE_CORE_MENU_NUMERICAL_SELECTION Event.
- //
- // Input:
- // ulSelectedTrackNumber - Holds the serial number of the Track to play.
- //
- // Output:
- // None.
- //
- // Remarks:
- // The method stops the current playback (if any), and jumps unconditionally to play
- // the selected Program-List Entry.
- // already the first item on the list.
- static void OnNumericSelection(ULONG ulSelectedTrackNumber)
- {
- //WORD uLastTrackNumber= PE_CD_GetTracksCnt();
- WORD uLastTrackNumber= g_pCDDANav->m_uLastCDDA_Track;
- dbg_printf(("OnNumericSelection(%d)n", ulSelectedTrackNumber));
- // Verify that the selected number is legal
- if ((ulSelectedTrackNumber < g_pCDDANav->m_uFirstCDDA_Track) ||
- (ulSelectedTrackNumber > uLastTrackNumber))
- {
- dbg_printf(("Illegal Track-number selected. Ignored.n"));
- return;
- }
- if (! PM_IsPlaybackNormal(PM_GetPlaybackMode())) {
- #ifdef bCDDA_PROHIBIT_NUMERIC_SELECTION_FOR_PROGRAM
- dbg_printf(("Numeric-Selection is not allowed for Program or Shuffle. Ignored.n"));
- return;
- #else //CDDA_PROHIBIT_NUMERIC_SELECTION_FOR_PROGRAM
- // Force transition to Normal playback mode
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- OnModeChange();
- /* NirM 11/07/2001
- WORD uCurrTrackNumber;
- //
- dbg_printf(("Numeric selection in non-normal playmode.n"));
- PM_InitializeProgramList(0);
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- for (uCurrTrackNumber= g_pCDDANav->m_uFirstCDDA_Track; uCurrTrackNumber <= ulLastTrack; uCurrTrackNumber++ ) {
- PM_SetProgramListEntry((WORD)(uCurrTrackNumber - g_pCDDANav->m_uFirstCDDA_Track + 1), uCurrTrackNumber);
- }
- */
- #endif //CDDA_PROHIBIT_NUMERIC_SELECTION_FOR_PROGRAM
- }
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- ClearMarker(eResumePlayback, 0);
- // Cancel any current Repeat-Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- // Cancel any Scanning
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- // Purge any pending Rendezvous point or Mode-Change
- g_pCDDANav->m_uRendezvousPoint= 0;
- g_pCDDANav->m_bPendingModeChange= FALSE;
- // Set the Current Item to the equivalent of the selected Track (Playback mode is Normal)
- (g_pCDDANav->m_CurrPosition).iPlaylistItem= (int)(ulSelectedTrackNumber - g_pCDDANav->m_uFirstCDDA_Track + 1);
- (g_pCDDANav->m_CurrPosition).dwAddress= -1;
- // Invoke playback of the selected Item
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to invoke playback a SelectionList Item.n"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : OnGotoTime
- //
- // Purpose : Start playing the disc from a given time value.
- //
- // Input Parameters :
- // ULONG ulTime - time in seconds from the beginning of the current track
- // or beginning of the disc - depends on whether an absolute
- // time is used or a relative one (the default).
- //
- // Return Value : static void
- //
- // Description : Calculating the new address and the new item number to play.
- // In case a relative time is used:
- // - Start address is from the beginning of the current track.
- // - Providing the start address is valid, the new item to
- // play is the the current play item.
- // In case an absolute time is used:
- // - Start address is from the beginning of the disc.
- // - The new item to play is found by searching the TOC table
- // that was initialzed in the constructor.
- //////////////////////////////////////////////////////////////////////////////////
- static void OnGotoTime(ULONG ulTime)
- {
- DWORD dwStartAddress;
- #ifdef CDDA_USE_ABSOLUTE_TIME
- UINT16 uTracksCount, uCurrTrackNumber;
- #endif //CDDA_USE_ABSOLUTE_TIME
- dbg_printf(("OnGotoTime(%ld)n", ulTime));
- #ifdef CDDA_USE_ABSOLUTE_TIME
- //setting the start address from the beginning of the disc
- dwStartAddress = (ulTime * CDDA_BLOCKS_PER_SEC);
- //Make sure that the requested time is within cd bounderies
- if (ulTime > gns.cdda.wTotalPlaybackTime) {
- dbg_printf(("Illegal Time requested.n"));
- return;
- }
- // Rebuild the Normal Program-List (sequential playback of the Tracks)
- PM_InitializeProgramList();
- uTracksCount = (UINT16)g_pCDDANav->m_uLastCDDA_Track;
-
- // Initialize the Program-List to sequencial playback
- for (uCurrTrackNumber = g_pCDDANav->m_uFirstCDDA_Track; uCurrTrackNumber <= uTracksCount; uCurrTrackNumber++)
- PM_SetProgramListEntry((WORD)(uCurrTrackNumber - g_pCDDANav->m_uFirstCDDA_Track + 1), (WORD)uCurrTrackNumber);
- //setting the current play item according to the address by searching the TOC we
- //created in the constructor
- uCurrTrackNumber = 0;
- while (uCurrTrackNumber < (uTracksCount - 1))
- {
- TrackInfo tiCurrTrack;
- Array_getAt(g_hTrackInfoCache, (uCurrTrackNumber - 1), (BYTE *)&tiCurrTrack);
- // checking if the start address is within the current track bounderies
- if ((dwStartAddress >= tiCurrTrack.dwStartAddress) &&
- (dwStartAddress <= (tiCurrTrack.dwStartAddress + tiCurrTrack.ulBlocksCnt)))
- {
- (g_pCDDANav->m_CurrPosition).iPlaylistItem = uCurrTrackNumber;
- break;
- }
-
- uCurrTrackNumber++;
- }
- //in case shuffle mode was on
- if (PM_IsPlaybackShuffle(g_pCDDANav->m_uCurrPlaybackMode))
- {
- //cancle shuffle
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- //sending the ui an event for state changed
- ie_send(IE_UI_STATE_CHANGE);
- // Update the current Playback-Mode
- g_pCDDANav->m_uCurrPlaybackMode= PM_GetPlaybackMode();
-
- }
- #else //CDDA_USE_ABSOLUTE_TIME
- //Setting the start address relativly to the current track
- dwStartAddress= (g_pCDDANav->m_aCurrTrack[0] + (ulTime * CDDA_BLOCKS_PER_SEC));
- // Make sure that the requested Time is within the boundaries of the current Track
- if (dwStartAddress > g_pCDDANav->m_aCurrTrack[1]) {
- dbg_printf(("Illegal Time requested.n"));
- core_report_error( IE_UI_REPORT_ERROR, (void *) CDNAV_ERR_PROHIBITED_UOP );
-
- return;
- }
- //Setting the new item to be the current played item
- //(g_pCDDANav->m_CurrPosition).iPlaylistItem = gns.cdda.uCurrentTrackNumber;
- #endif //CDDA_USE_ABSOLUTE_TIME
- PE_CD_AbortPlayback(TRUE); // Maintain Standby mode
- ClearMarker(eResumePlayback, 0);
- // Cancel any current Repeat-Modes
- CancelRepeatModes(PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK);
- if (PST_SCAN == gcs.pstate)
- OnScan(0);
- g_pCDDANav->m_uRendezvousPoint= 0;
- g_pCDDANav->m_bPendingModeChange= FALSE;
- (g_pCDDANav->m_CurrPosition).dwAddress= dwStartAddress;
-
- gcs.pstate= PST_PLAY;
- if (! InvokePlayback()) {
- dbg_printf(("Failed to invoke playback a SelectionList Item.n"));
- gcs.pstate= PST_STOP;
- }
- return;
- }
- #ifdef D_ENABLE_DISC_TIMESEARCH
- /////////////////////////////////////////////////////////////////////////////////////////////////
- // static void OnGotoDiscTime(ULONG ulTime) -
- // Handles an IE_CORE_GOTO_DISC_TIME Event.
- //
- // Input:
- // ulTime - The absolute time, within the Whole Disc, to jump to.
- //
- // Output:
- // None. The playback is resumed from the requested time, if possible.
- //
- // Remarks:
- // None.
- static void OnGotoDiscTime(ULONG ulTime)
- {
- TrackInfo Track;
- DWORD dwStartAddress;
- WORD uCurrTrackNumber= 1, uLastTrack = PE_CD_GetTracksCnt();
- BOOL done = 0;
- dbg_printf(("OnGotoDiscTime(%ld)n", ulTime));
- if (! PE_CD_GetTrackInfo(uCurrTrackNumber, &Track)){
- dbg_printf(("Failed to access the TOC for Track %d.n", (int)uCurrTrackNumber));
- return;
- }
- dwStartAddress = ulTime*CDDA_BLOCKS_PER_SEC + Track.dwStartAddress;
- if ( !PE_CD_GetTrackInfo(uLastTrack, &Track)){
- dbg_printf(("Failed to access the TOC for Track %d.n", (int)uLastTrack));
- return;
- }
- if ( dwStartAddress > ( Track.dwStartAddress + Track.ulBlocksCnt ) ){
- dbg_printf(("Search time is out of lead out area.n"));
- core_report_error( IE_UI_REPORT_ERROR, (void *) CDNAV_ERR_PROHIBITED_UOP );
- return;
- }
- uCurrTrackNumber = 0;
- while( ( uCurrTrackNumber <= uLastTrack ) && ( !done ) ){
- uCurrTrackNumber ++;
- if(!PE_CD_GetTrackInfo(uCurrTrackNumber, &Track)){
- dbg_printf(("Failed to access the TOC for Track %d.n", (int)uCurrTrackNumber));
- return;
- }
-
- if ( ( dwStartAddress >= Track.dwStartAddress ) && ( dwStartAddress < ( Track.dwStartAddress + Track.ulBlocksCnt ) ) ){
- g_pCDDANav->m_CurrPosition.iPlaylistItem = uCurrTrackNumber;
- g_pCDDANav->m_CurrPosition.dwAddress = dwStartAddress;
- SHARED_INFO.uCurrentTrackNumber = g_pCDDANav->m_CurrPosition.iPlaylistItem;
- done = 1;
- }
- }
- //we must cancel all the playmode and scan, initilaize the playlist
- OnScan(0);
- CancelRepeatModes((PM_REPEAT_SINGLE | PM_REPEAT_ALL | PM_REPEAT_AB_MASK));
- PM_InitializeProgramList();
- PM_SetPlaybackMode(PM_PLAYBACK_NORMAL);
- //<<<MikeX_0917_2003_A: don't add the data track into the program list
- for(uCurrTrackNumber = 1; uCurrTrackNumber <= uLastTrack; uCurrTrackNumber++ ){
- UINT8 uTrackCtrlField;
- UINT32 uDummy;
- if (! PE_CD_GetTrackTOC(uCurrTrackNumber, &uTrackCtrlField, &uDummy, &uDummy)) {
- tr_printf(("FATAL: Failed to collect TOC info for Track #%dn", uCurrTrackNumber));
- continue;
- }
- if ((uTrackCtrlField & 0x0F) != 0x4)
- {
- // This is a CDDA Track - add it to the Program-List
- PM_SetProgramListEntry((WORD)uCurrTrackNumber, (WORD)uCurrTrackNumber);
- g_pCDDANav->m_uLastCDDA_Track = (WORD)uCurrTrackNumber;
- }
- }//MikeX_0917_2003_A>>>
- // Clear all Markers and Bookmarks
- ClearMarker(eResumePlayback, 0);
- ClearMarker(eMarkerA, 0);
- ClearMarker(eMarkerB, 0);
- if ( gcs.pstate != PST_STOP ){
- PE_CD_AbortPlayback(TRUE); // Maintain standby
- }
- if (!InvokePlayback()){
- dbg_printf(("Can't invoke playback for Disc Time Search.n"));
- }
- return;
- }
- #endif
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : CDDA_IsCDDTS
- // Purpose : return if CDDTS was detect
- // Input Parameters : none
- // Return Value : g_bIsCDDTS
- //////////////////////////////////////////////////////////////////////////////////
- BOOL CDDA_IsCDDTS(void)
- {
- if(g_disc_type == DEC_DISC_TYPE_CDDA)
- return g_bIsCDDTS;
- else
- return FALSE;
- }
- //////////////////////////////////////////////////////////////////////////////////
- // Function name : OnIntro
- //
- // Input Parameters : void
- //
- // Return Value : void
- //
- // Description : Begin to start intro playback or stop it.
- //////////////////////////////////////////////////////////////////////////////////
- void OnIntro(void)
- {
- if (TRUE != SHARED_INFO.bIsCDDAIntroMode)
- {
- dbg_printf(("Cancel Playmode/Repeat moden"));
- PM_SetPlaybackMode(0);
- PM_ClearRepeat();
- OnModeChange();
- SHARED_INFO.bIsCDDAIntroMode = TRUE;
- (g_pCDDANav->m_CurrPosition).iPlaylistItem = 1;
- ClearMarker(eResumePlayback, 0);
- OnPlay();
- }
- return;
- }
- #ifdef _DEBUG
- static void OnStatusReport()
- {
- dbg_printf(("Status Report for CDDA-Navigator:n"));
- dbg_printf(("tTotal number of items on Playlist: %dn", (int)(PM_GetProgramSize()-1)));
- dbg_printf(("tCurrent Playlist item: %dn", (int)(g_pCDDANav->m_CurrPosition).iPlaylistItem));
- return;
- }
- #endif //_DEBUG
- #ifdef EXINO2
- BOOL get_intro_mode(void)
- {
- return SHARED_INFO.bIsCDDAIntroMode;
- }
- // SEC BK.LIM070203>>>
- // <<< SEC BK.LIM070203: porting from exino code
- BOOL CDDA_Nav_Check_UOP(EVENT Event, void *Param)
- {
- BOOL bIsNextOp = FALSE;
- DWORD dwCurrentLocation = PE_CD_GetCurrentLocation();
- switch(Event){
- case IE_CORE_NEXT_CHAPTER:
- bIsNextOp = TRUE;
- case IE_CORE_PREVIOUS_CHAPTER:
- if ( gcs.pstate == PST_STOP )
- return FALSE;
- if ((( (g_pCDDANav->m_CurrPosition).iPlaylistItem == ( PM_GetProgramSize() - 1 )) && (bIsNextOp )) ||
- (( (g_pCDDANav->m_CurrPosition).iPlaylistItem == 1 ) && ( !bIsNextOp) && ( (dwCurrentLocation - g_pCDDANav->m_aCurrTrack[0]) <= 225) ) )//ZORAN LX010402
- if ( !PM_IsPlaybackShuffle(PM_GetPlaybackMode())) //Added by Billt 081602
- return FALSE; //Added by Billt 081602
- return TRUE;
- default:
- return FALSE;
- }
- }
- // SEC BK.LIM070203>>>
- #endif // EXINO2
- #ifdef EXINO2 // ZKR JK0331 : for power_on_resume in EEPROM
- #ifdef HW_POWER_ON_RESUME
- static WORD GetResumeLeadOutInfo(void)
- {
- WORD wLeadOut;
-
- if (eeprom_read(CDDA_LeadOut_Info_ADDR, (BYTE *)&wLeadOut, sizeof(WORD) ))
- return wLeadOut;
- else
- tr_printf(("Error on reading Lead Out info from EEPROM when do CDDA power on resume n"));
- //dbg_printf(("Error on reading Lead Out info from EEPROM when do CDDA power on resume n"));
- }
- static void SetResumeLeadOutInfo(void)
- {
- if (eeprom_write (CDDA_LeadOut_Info_ADDR, (BYTE *)&((gns.cdda).wTotalPlaybackTime), sizeof(WORD) ))
- return;
- else
- tr_printf(("Error on writing Lead Out info to EEPROMn"));
- //dbg_printf(("Error on writing Lead Out info to EEPROMn"));
- }
- void ClearResumeLeadOutInfo(void)
- {
- WORD wLeadOut;
- wLeadOut = 0x0000;
-
- // <<< ZKR GL021302 : Use eeprom_write()
- //if (eeprom_read(CDDA_LeadOut_Info_ADDR, (BYTE *)&wLeadOut, sizeof(WORD) ))
- if (eeprom_write(CDDA_LeadOut_Info_ADDR, (BYTE *)&wLeadOut, sizeof(WORD) ))
- // ZKR GL021302 >>>
- return;
- else
- tr_printf(("Error on cleanning CDDA Lead Out info from EEPROM when eject tray n"));
- //dbg_printf(("Error on cleanning CDDA Lead Out info from EEPROM when eject tray n"));
- }
- void save_CDDA_info(void)
- {
- g_pCDDANav->m_ResumePlayback.iPlaylistItem = SHARED_INFO.uCurrentTrackNumber;
- eeprom_write(PonCDDA, (BYTE *)&g_pCDDANav->m_ResumePlayback, sizeof(CDDA_Marker));
- }
- void restore_CDDA_info(void)
- {
- eeprom_read(PonCDDA, (BYTE *)&g_pCDDANav->m_ResumePlayback, sizeof(CDDA_Marker));
- }
- #endif//HW_POWER_ON_RESUME
- #else //EXINO2
- #ifdef HW_POWER_ON_RESUME
- BOOL CDDANAV_NvmBmk_Match(NVM_GENERIC_BMK* pGenric_bmk)
- {
- if (gns.cdda.wTotalPlaybackTime != pGenric_bmk->marker.cdda.wLeadOut)
- return FALSE;
- return TRUE;
- }
- void CDDANAV_NvmBmk_Set( WORD sc_handle)
- {
- WORD wSCTmp;
- BYTE b_temp;
- int i, offset;
- NVM_GENERIC_BMK* pGenric_bmk;
- offset = (int)&pGenric_bmk->marker.cdda.wLeadOut - (int)pGenric_bmk;
- sc_SetBytes(sc_handle, offset, sizeof(WORD), (BYTE *)&gns.cdda.wTotalPlaybackTime);
- if(gcs.pstate !=PST_STOP)
- SetMarker(eResumePlayback, 0);
- g_pCDDANav->m_ResumePlayback.iPlaylistItem = SHARED_INFO.uCurrentTrackNumber;
- offset = (int)&pGenric_bmk->marker.cdda.m_ResumePlayback - (int)pGenric_bmk;
- sc_SetBytes(sc_handle, offset, sizeof(CDDA_Marker), (BYTE *)&g_pCDDANav->m_ResumePlayback);
-
- return;
- }
- void CDDANAV_NvmBmk_Play(NVM_GENERIC_BMK *pGenric_bmk)
- {
- g_pCDDANav->m_ResumePlayback = pGenric_bmk->marker.cdda.m_ResumePlayback;
- return;
- }
- #endif //HW_POWER_ON_RESUME
- #endif //EXINO2
- #ifdef EXINO2
- // Check valid time or not for flt displaying correctly.
- BOOL IS_CDDA_Elapsed_time_valid(void)
- {
- DWORD dwCurrentLocation = PE_CD_GetCurrentLocation();
- return ((dwCurrentLocation >=g_pCDDANav->m_aCurrTrack[0])
- && (dwCurrentLocation <= g_pCDDANav->m_aCurrTrack[1]));
- }
- int get_CDDA_ScanSpeed(void)
- {
- return g_pCDDANav->m_iScanSpeed;
- }
- #endif
-