⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdda_app.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    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 + -