📄 cdda_app.cpp
字号:
/* Stop the DR */
DRStop(CddaAppControl.tDR);
DRDetachStream(CddaAppControl.tDR, DR_STREAM_MAIN);
/* Unregister for DR events */
DRReset(CddaAppControl.tDR);
/* detach DR event handler */
DRDetachEvent(CddaAppControl.tDR);
/* Unregister for iStreamCtrl events */
PEDetachEvent(CddaAppControl.tPE, cddaPEEventCallback);
if (TRUE == CddaAppControl.fCddaAppStarted)
{
cddaAppStopNav();
}
/* Set global pointers to NULL */
CddaAppControl.tLoader = NULL;
CddaAppControl.tDR = NULL;
CddaAppControl.tPE = NULL;
CddaAppControl.State = CDDA_STATE_UNITIALIZED;
return (OS_OK);
}
/**
* Retrieve the play state of the CDDA Navigator.
*
* @param none.
*
* @return OS_STATUS - Status / error code.
*/
CDDA_StateInfo CddaAppGetState(void)
{
return (CddaAppControl.State);
}
/**
* Define the CDDA application event handler.
*
* @param EventSource - Source that triggered call to this event handler.
* @param ulEventCode - Event code passed to this event handler.
* @param pEventInfo - Additional event information passed to this event handler.
*
* @return OS_STATUS - Status / error code.
*
* @note PE_EVENT_END_OF_STREAM is what triggers the process for what to play after a clip or track
* has finished playing. The current state, repeat mode and track number are inputs to the algorithm.
*/
OS_STATUS CddaAppEventHandler(CddaAppEventSource EventSource, ULONG ulEventCode, PVOID pEventInfo)
{
uint32 uiStatus;
OS_STATUS status = OS_OK;
CDDA_CommandMsg CddaCmdMsg;
BOOLEAN fSend = TRUE;
CDDA_TrackInfo CurrentTrack;
PE_ISTREAMCTRL_PLAYRATE pePlayRate;
ULONG ulStatus;
/* DR Event Handler */
if (CDDAAPP_EVENTSOURCE_DR == EventSource)
{
switch (ulEventCode)
{
case DR_EVENT_BUFFER_EMPTY:
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): DR_EVENT_BUFFER_EMPTY\n", __FUNCTION__));
break;
case DR_EVENT_COMMAND_BUFFER_EMPTY:
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): DR_EVENT_COMMAND_BUFFER_EMPTY\n", __FUNCTION__));
break;
case DR_EVENT_ERROR:
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): DR_EVENT_ERROR\n", __FUNCTION__));
break;
case DR_EVENT_COMMAND_ERROR:
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): DR_EVENT_COMMAND_ERROR\n", __FUNCTION__));
break;
default:
DBGPRINT(CDDAAPP_DEBUG, ("\n%s(): Unknown DR event (0x%X) received\n", __FUNCTION__, ulEventCode));
status = OS_FAILURE;
break;
}
}
/* PE Event Handler */
else if (CDDAAPP_EVENTSOURCE_PE == EventSource)
{
switch (ulEventCode)
{
case PE_EVENT_POSITION:
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s(): PE_EVENT_POSITION\n", __FUNCTION__));
CddaAppControl.ulCurrentPETime = *((ULONG*)pEventInfo);
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s(): %d T %08x TR %08x D %08x DR %08x\n", __FUNCTION__, CddaAppGetCurrentTrack(),
CddaAppGetPlayTime(0), CddaAppGetPlayTime(1), CddaAppGetPlayTime(2), CddaAppGetPlayTime(3)));
break;
case PE_EVENT_BEG_OF_STREAM:
break;
case PE_EVENT_END_OF_STREAM:
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): PE_EVENT_END_OF_STREAM %08x\n\n", __FUNCTION__, CddaAppGetPlayTime(3)));
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): %d T %08x TR %08x D %08x DR %08x\n", __FUNCTION__, CddaAppGetCurrentTrack(),
CddaAppGetPlayTime(0), CddaAppGetPlayTime(1), CddaAppGetPlayTime(2), CddaAppGetPlayTime(3)));
/* Get the current DR status */
DRGetStatus(CddaAppControl.tDR, DR_STREAM_MAIN, DR_STATCMD_BUFFERS, &uiStatus);
CddaCmdMsg.sSpeed = 0;
/* If the DR idle, prepare to start the next track, provided not at last track. */
if ( (uiStatus & DR_STATUS_TRACK_BUFFER_EMPTY) && ((uiStatus & DR_STATUS_QUEUE_BUFFER) == 0) )
{
/* If we are currently fast rewinding:
* 1. Start playing the current track from the beginning if we are in repeat mode CDDA_REPEAT_TRACK.
* 2. If we are hitting the beginning of the first track, transition to full stop.
* 3. If we are hitting the beginning of a higher track, begin fast-rewinding through previous track.
*/
if ( CddaAppControl.State == CDDA_STATE_FAST_RWD )
{
if (CddaAppControl.RepeatMode == CDDA_REPEAT_TRACK)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
}
else
{
if (CddaAppControl.CurrentTrack.bPoint == CddaAppControl.TOC.bFirstTrackNumber)
{
CddaCmdMsg.bCommand = CDDA_CMD_PLAY;
CddaCmdMsg.bTrackNumber = CddaAppControl.TOC.bFirstTrackNumber;
}
else
{
CddaCmdMsg.bCommand = CDDA_CMD_FAST_RWD;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint - 1;
}
}
}
/* If we are currently fast forwarding:
* 1. If we are hitting the end of the last track:
* a. Go to first track if we are in REPEAT_ALL
* b. Go to beginning of current track if we are in REPEAT_TRACK
* c. Go in to full stop.
* 2. If we are hitting the end of a lower track:
* a. Begin fast-forwarding through next track.
* b. Go to beginning of current track if we are in REPEAT_TRACK
*/
else if ( CddaAppControl.State == CDDA_STATE_FAST_FWD )
{
if (CddaAppControl.CurrentTrack.bPoint == CddaAppControl.TOC.bLastTrackNumber)
{
if (CddaAppControl.RepeatMode == CDDA_REPEAT_TRACK)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
}
else if (CddaAppControl.RepeatMode == CDDA_REPEAT_ALL)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.TOC.bFirstTrackNumber;
}
else
{
/* Sending two stop commands to get a full stop state */
/* @todo Add a full stop command */
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
if (OS_OK != uiStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
}
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
}
}
else
{
if (CddaAppControl.RepeatMode == CDDA_REPEAT_TRACK)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
}
else
{
CddaCmdMsg.bCommand = CDDA_CMD_FAST_FWD;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint + 1;
}
}
}
/* If we are currently in normal play mode:
* 1. If we are in REPEAT_AB:
* a. Cancel last A point and update A point to beginning of next track if we do not have B point.
* b. If we do have B point perform another AB repeat on current clip.
* 2. If we are in REPEAT_TRACK repeat current track.
* 3. If we are in REPEAT_ALL and at the last track, go to first track.
* 4. If we are at last track and no repeat, go to full stop.
* 5. If we are at lower track, start playing next track.
*/
else
{
if (CddaAppControl.RepeatMode == CDDA_REPEAT_AB)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): End Stream: CDDA_REPEAT_AB\n", __FUNCTION__));
if (CddaAppControl.bABRepeatCount == 1)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): End Stream: bABRepeatCount == 1\n", __FUNCTION__));
cddaGetTrackLBAs(CddaAppControl.CurrentTrack.bPoint + 1, &CurrentTrack);
CddaAppControl.ulRepeatATime = CurrentTrack.ulStartLBA;
if (CddaAppControl.CurrentTrack.bPoint == CddaAppControl.TOC.bLastTrackNumber)
{
/* Sending two stop commands to get a full stop state */
/* @todo Add a full stop command */
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
if (OS_OK != uiStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
}
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
}
else
{
CddaCmdMsg.bCommand = CDDA_CMD_NEXT_TRACK;
}
}
else
{
CddaCmdMsg.bCommand = CDDA_CMD_REPEAT_AB;
}
}
else if (CddaAppControl.RepeatMode == CDDA_REPEAT_TRACK)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
}
else if (CddaAppControl.RandomMode == TRUE)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = (BYTE)g_RandomList[g_RandomCur++];
}
else
{
if (CddaAppControl.CurrentTrack.bPoint == CddaAppControl.TOC.bLastTrackNumber)
{
if (CddaAppControl.RepeatMode == CDDA_REPEAT_ALL)
{
CddaCmdMsg.bCommand = CDDA_CMD_GOTO_TRACK;
CddaCmdMsg.bTrackNumber = CddaAppControl.TOC.bFirstTrackNumber;
}
else
{
/* Sending two stop commands to get a full stop state */
/* @todo Add a full stop command */
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
if (OS_OK != uiStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
}
CddaCmdMsg.bCommand = CDDA_CMD_STOP;
}
}
else
{
CddaCmdMsg.bCommand = CDDA_CMD_NEXT_TRACK;
}
}
}
if (fSend == TRUE)
{
uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
if (OS_OK != uiStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
}
}
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -