📄 cdda_app.cpp
字号:
pCddaTOC->pHeader = (CDDA_TOCHeaderInfo *) &CddaAppControl.TOC.bData;
/* Clear TOC buffer */
memset(CddaAppControl.TOC.bData, 0, CDDA_TOC_BUFFER_SIZE_BYTES);
/* Retrieve the a TOC header for the entire disc by asking for Session 0 */
ulStatus = LoaderGetTOC (CddaAppControl.tLoader, LOADER_TOC_CMD_FULL_TOC, 0, LOADER_TOC_MSF, CddaAppControl.TOC.bData, CDDA_TOC_HEADER_SIZE_BYTES);
if (LOADER_SUCCESS != ulStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): LoaderGetTOC failed.\n", __FUNCTION__, ulStatus));
return(CDDA_TOC_FAILURE);
}
/* Is a first session present? */
if (1 != pCddaTOC->pHeader->bFirstSessionNumber)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: First session was not found.\n", __FUNCTION__));
return(CDDA_NO_SESSION_FOUND);
}
/* We are looking for the highest numbered session with CDDA audio tracks on it */
for (i = pCddaTOC->pHeader->bLastSessionNumber; i >= pCddaTOC->pHeader->bFirstSessionNumber; i--)
{
/* Retrieve the TOC header from the session number specified in i */
ulStatus = LoaderGetTOC (CddaAppControl.tLoader, LOADER_TOC_CMD_FULL_TOC, i, LOADER_TOC_MSF, CddaAppControl.TOC.bData, CDDA_TOC_HEADER_SIZE_BYTES);
if (LOADER_SUCCESS != ulStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): LoaderGetTOC failed.\n", __FUNCTION__, ulStatus));
return(CDDA_TOC_FAILURE);
}
/* Reformat size of the full TOC based on the info given in the TOC header that was just received */
CddaAppControl.TOC.ulSize = (ULONG) ( ( ((ULONG) pCddaTOC->pHeader->bDataLength_MSB) << 8) | ((ULONG) pCddaTOC->pHeader->bDataLength_LSB) );
CddaAppControl.TOC.ulSize += CDDA_TOC_DATA_LENGTH_SIZE_BYTES;
/* Retrieve the TOC from the session number specified in i all the way to the highest session */
ulStatus = LoaderGetTOC (CddaAppControl.tLoader, LOADER_TOC_CMD_FULL_TOC, i, LOADER_TOC_MSF, CddaAppControl.TOC.bData, CddaAppControl.TOC.ulSize);
if (LOADER_SUCCESS != ulStatus)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): LoaderGetTOC failed.\n", __FUNCTION__, ulStatus));
return(CDDA_TOC_FAILURE);
}
/* Check the Control field of the first track of the first session that we retrieved, if it is audio, stop looking */
/* The upper two bits of the lower nibble are Control - they tell us if the track is audio data */
if ( 0 == (CddaAppControl.TOC.bData[5]&0x0C) )
{
DBGPRINT(DBG_ON(DBG_VERBOSE), ("%s(): The first track of this session is a audio track, using session %d.\n", __FUNCTION__, i));
/* Recalculate the actual size of the TOC we want: the previously read, higher-numbered sessions need to be subtracted off */
CddaAppControl.TOC.ulSize = (ULONG) ( ( ((ULONG) pCddaTOC->pHeader->bDataLength_MSB) << 8) | ((ULONG) pCddaTOC->pHeader->bDataLength_LSB) );
CddaAppControl.TOC.ulSize += CDDA_TOC_DATA_LENGTH_SIZE_BYTES;
CddaAppControl.TOC.ulSize -= ulIgnoreSize;
break;
}
/* Calculate the number of bytes to be subtracted off later */
ulIgnoreSize = (ULONG) ( ( ((ULONG) pCddaTOC->pHeader->bDataLength_MSB) << 8) | ((ULONG) pCddaTOC->pHeader->bDataLength_LSB) );
ulIgnoreSize += CDDA_TOC_DATA_LENGTH_SIZE_BYTES;
}
/* How many entries in the toc? */
CddaAppControl.TOC.ulNumberOfEntries = ( (CddaAppControl.TOC.ulSize - CDDA_TOC_HEADER_SIZE_BYTES) / CDDA_TOC_FULL_DESCRIPTOR_SIZE );
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("\n%s(): TOC Info: Locations: Header = 0x%p, Start Of Track Descriptors = 0x%p.\n",
__FUNCTION__, CddaAppControl.TOC.bData, (CddaAppControl.TOC.bData + CDDA_TOC_HEADER_SIZE_BYTES) ));
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): TOC Info: Size = %u, Entries = %u, First Session = %u, Last Session = %u.\n\n",
__FUNCTION__, CddaAppControl.TOC.ulSize, CddaAppControl.TOC.ulNumberOfEntries,
pCddaTOC->pHeader->bFirstSessionNumber, pCddaTOC->pHeader->bLastSessionNumber ));
return(CDDA_SUCCESS);
} /* end cddaRetrieveCddaTOC() */
/**
* Parse the CDDA table of contents.
*
* @param none
*
* @return ULONG status information.
*
* @note See Mt. Fuji Specification, Tables 374 and 369.
*/
static void cddaParseCddaTOC(void)
{
BYTE bEntry;
CDDA_TrackDescriptorInfo *pTDIEntry;
CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
/* Initialize pointer to start of track descriptors in TOC */
pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData + CDDA_TOC_HEADER_SIZE_BYTES);
/* Parse TOC and store necessary information */
for (bEntry = 0; bEntry < CddaAppControl.TOC.ulNumberOfEntries; bEntry++)
{
pTDIEntry = &(pTrackDescriptorInfo[bEntry]);
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] pTDIEntry = 0x%p.\n", __FUNCTION__, bEntry, pTDIEntry));
switch (pTDIEntry->bPoint)
{
/* First track number information */
case CDDA_TOC_FIRST_TNO:
CddaAppControl.TOC.bFirstTrackNumber = pTDIEntry->bPMinute;
CddaAppControl.TOC.bDiscType = pTDIEntry->bPSecond;
switch (CddaAppControl.TOC.bDiscType)
{
case CDDA_DISC_TYPE_CDDA_OR_CDROM:
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] %s disc type detected.\n\n", __FUNCTION__, bEntry, "CDDA or CD-ROM"));
break;
case CDDA_DISC_TYPE_CD_I:
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] %s disc type detected.\n\n", __FUNCTION__, bEntry, "CD-I"));
break;
case CDDA_DISC_TYPE_CDROM_XA:
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] %s disc type detected.\n\n", __FUNCTION__, bEntry, "CD-ROM XA"));
break;
default:
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): [Entry = %02u] ERROR: Invalid disc type (0x%X) detected.\n\n", __FUNCTION__, bEntry, CddaAppControl.TOC.bDiscType));
break;
}
break;
case CDDA_TOC_LAST_TNO:
CddaAppControl.TOC.bLastTrackNumber = pTDIEntry->bPMinute;
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] Last Track Number = %u.\n\n", __FUNCTION__, bEntry, CddaAppControl.TOC.bLastTrackNumber));
break;
case CDDA_TOC_LEADOUT:
CddaAppControl.TOC.LeadOut.bPMinute = pTDIEntry->bPMinute;
CddaAppControl.TOC.LeadOut.bPSecond = pTDIEntry->bPSecond;
CddaAppControl.TOC.LeadOut.bPFrame = pTDIEntry->bPFrame;
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] Lead-Out: MSF = 0x%02X : 0x%02X : 0x%02X.\n\n",
__FUNCTION__, bEntry, pTDIEntry->bPMinute, pTDIEntry->bPSecond, pTDIEntry->bPFrame));
break;
default:
if ( (CDDA_TOC_TRACK_MINIMUM <= pTDIEntry->bPoint) && (pTDIEntry->bPoint <= CDDA_TOC_TRACK_MAXIMUM) )
{
/* Store the TOC entry number corresponding to the track number. (Note: Not zero-based indexing.) */
CddaAppControl.TOC.bTrackToEntry[pTDIEntry->bPoint] = bEntry;
DBGPRINT(DBG_ON(CDDAAPP_TRACE_TOC), ("%s(): [Entry = %02u] Track %u mapped.\n\n", __FUNCTION__, bEntry, pTDIEntry->bPoint));
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): WARNING: [Entry = %02u] Track descriptor point value (0x%X) currently not supported.\n\n",
__FUNCTION__, bEntry, pTDIEntry->bPoint) );
}
break;
}
}
}
/**
* Retrieves a requested track LBA values.
*
* @param BYTE bRequestedTrack - Track number which requesting LBAs
* CDDA_TrackInfo *pRequestedTrackInfo - Pointer to return LBAs
*
* @return none
*/
static void cddaGetTrackLBAs(BYTE bRequestedTrack, CDDA_TrackInfo *pRequestedTrackInfo)
{
BYTE bEntry;
CDDA_MSF *pLeadOut;
CDDA_TrackDescriptorInfo *pTDIEntry;
CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
/* Initialize pointer to start of track descriptors in TOC */
pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData + CDDA_TOC_HEADER_SIZE_BYTES);
/* Translate requested track to TOC entry number, then set pointer */
bEntry = CddaAppControl.TOC.bTrackToEntry[bRequestedTrack];
pTDIEntry = &(pTrackDescriptorInfo[bEntry]);
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): Requested Track = %u, Last Track = %u, Entry = %u, pTDIEntry = 0x%p.\n",
__FUNCTION__, bRequestedTrack, CddaAppControl.TOC.bLastTrackNumber, bEntry, pTDIEntry));
/* Retrieve requested track info */
/* Set point and start LBA */
pRequestedTrackInfo->bPoint = bRequestedTrack;
pRequestedTrackInfo->ulStartLBA = MSF_TO_LBA(pTDIEntry->bPMinute, pTDIEntry->bPSecond, pTDIEntry->bPFrame);
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): [Entry = %02u] Start: MSF = 0x%02X : 0x%02X : 0x%02X, LBA = 0x%X.\n",
__FUNCTION__, bEntry, pTDIEntry->bPMinute, pTDIEntry->bPSecond, pTDIEntry->bPFrame, pRequestedTrackInfo->ulStartLBA));
/* Now, check if last track requested, then determine/translate to be able to set end LBA */
if (bRequestedTrack == CddaAppControl.TOC.bLastTrackNumber)
{
/* Last track requested; use Lead-Out area to determine end LBA */
pLeadOut = &CddaAppControl.TOC.LeadOut;
pRequestedTrackInfo->ulEndLBA = ((MSF_TO_LBA(pLeadOut->bPMinute, pLeadOut->bPSecond, pLeadOut->bPFrame)) - 1);
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): [Entry = %02u] End(LO): MSF = 0x%02X : 0x%02X : 0x%02X, LBA = 0x%X.\n",
__FUNCTION__, bEntry, pLeadOut->bPMinute, pLeadOut->bPSecond, pLeadOut->bPFrame, pRequestedTrackInfo->ulEndLBA));
}
else
{
/* Not last track requested; use next track to determine end LBA */
bEntry = CddaAppControl.TOC.bTrackToEntry[bRequestedTrack + 1];
pTDIEntry = &(pTrackDescriptorInfo[bEntry]);
pRequestedTrackInfo->ulEndLBA = ((MSF_TO_LBA(pTDIEntry->bPMinute, pTDIEntry->bPSecond, pTDIEntry->bPFrame)) - 1);
DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): [Entry = %02u] End: MSF = 0x%02X : 0x%02X : 0x%02X, LBA = 0x%X.\n",
__FUNCTION__, bEntry, pTDIEntry->bPMinute, pTDIEntry->bPSecond, pTDIEntry->bPFrame, pRequestedTrackInfo->ulEndLBA));
}
}
/**
* Receives event callbacks from the PE.
*
* @param event - enumerated event code (see pe_app.h)
*
* @return PE_STATUS
*/
static PE_STATUS cddaPEEventCallback(PVOID pContext, PE_EVENT_CODE event, PVOID pEventInfo)
{
if (event >= PE_EVENT_CODE_INVALID)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: Invalid event code.\n", __FUNCTION__));
return (PE_FAILURE);
}
if (CddaAppEventHandler(CDDAAPP_EVENTSOURCE_PE, (ULONG)event, pEventInfo) != OS_OK)
{
return (PE_FAILURE);
}
return (PE_SUCCESS);
}
/**
* Receives event callbacks from the DR.
*
* @param pContext - context pointer registered with the dr when the event handler is attached.
* @param event - enumerated event code (see dr_app.h)
* @param pEventInfo - pointer to buffer that can contain additional info depending on the event received.
*
* @return DR_ERROR
*/
static DR_ERROR cddaDrEventCallback(PVOID pContext, DR_EVENT_CODE event, PVOID pEventInfo)
{
if (event >= DR_EVENT_CODE_INVALID)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: Invalid event code.\n", __FUNCTION__));
return (DR_FAILURE);
}
if (CddaAppEventHandler(CDDAAPP_EVENTSOURCE_DR, (ULONG)event, pEventInfo) != OS_OK)
{
return (DR_FAILURE);
}
return (DR_SUCCESS);
}
static ULONG CddaCreatRandomTrackList(void)
{
BYTE bFirstTrack, bLastTrack;
UBYTE i,t;
srand(OS_GetTicks() );
bFirstTrack = CddaAppControl.TOC.bFirstTrackNumber;
bLastTrack = CddaAppControl.TOC.bLastTrackNumber;
g_RandomCur=bFirstTrack;
for(i=bFirstTrack ; i<=bLastTrack ; i++ )
{
while(1 )
{
g_RandomList[i] = ( (UBYTE) ( rand( ) % bLastTrack) + 1 );
if(i==0)
{
break;
}
for(t =bFirstTrack ; t<i ;++t)
{
if(g_RandomList[t] ==g_RandomList[i])
break;
}
if(t ==i)
{
break;
}
}
}
return (0);
}
/**
* This is the cdda task which processes cdda commands.
*
* @param argv - not used
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -