📄 cdda_app.cpp
字号:
/* vim:set ts=4 sw=4 et: */
/*****************************************************************************
******************************************************************************
** **
** Copyright (c) 2006 Videon Central, Inc. **
** All rights reserved. **
** **
** The computer program contained herein contains proprietary information **
** which is the property of Videon Central, Inc. The program may be used **
** and/or copied only with the written permission of Videon Central, Inc. **
** or in accordance with the terms and conditions stipulated in the **
** agreement/contract under which the programs have been supplied. **
** **
******************************************************************************
*****************************************************************************/
/**
* @file cdda_app.cpp
*
* Application for playing CDDAs
*
* $Id: cdda_app.cpp,v 1.55 2007/01/26 21:14:54 rbehe Exp $
*/
#include <stdlib.h>
#include <string.h>
#include "vdvd_types.h"
#include "osapi.h"
#include "loader_app.h"
#include "dr_app.h"
#include "pe_app.h"
#include "usrapi.h"
#include "dbgprint.h"
#include "cdda_app.h"
#include "utility.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Macros */
/* Debug Print Control */
#define CDDAAPP_DEBUG (DBG_ERROR)
#define CDDAAPP_TRACE_TOC (DBG_ERROR)
#define CDDAAPP_TRACE_DR_EVENT_MSF (DBG_ERROR)
#define DBG_ON(x) (CDDAAPP_DEBUG >= x)
/* General */
#define CDDA_MSG_QUEUE_DEPTH (2) /* Max number of command messages allowed in queue */
#define CDDA_TASK_STACKSIZE (8 * 1024) /* CDDA task stack size */
/* Version information for the CDDA player */
#define CDDA_VERSION_STRING "cdda_app_00_00_06"
#define CDDA_VERSION_DATE_STRING "April 6, 2006"
#define CDDA_VERSION_YEAR 0x2006
#define CDDA_VERSION_MONTH 0x04
#define CDDA_VERSION_DAY 0x06
#define CDDA_SECTOR_SIZE 2352
#define CD_FRAMES 75
#define MAX_SYNC_LOOP 64
/* Globals */
static CDDA_AppInfo CddaAppControl; /* CDDA application control */
static BYTE bCddaLocalBuf[CDDA_SECTOR_SIZE];
static USHORT g_RandomList[99];
static USHORT g_RandomCur;
/* Function Prototypes */
static OS_STATUS cddaAppStartNav(void);
static void cddaAppStopNav(void);
static ULONG cddaRetrieveCddaTOC(void);
static void cddaParseCddaTOC(void);
static void cddaGetTrackLBAs(BYTE bRequestedTrack, CDDA_TrackInfo *pRequestedTrackInfo);
static PE_STATUS cddaPEEventCallback(PVOID pContext, PE_EVENT_CODE event, PVOID pEventInfo);
static DR_ERROR cddaDrEventCallback(PVOID pContext, DR_EVENT_CODE event, PVOID pEventInfo);
static ULONG cddaAppTask(PVOID argv);
static BOOLEAN cddaAppCheckForDts(LOADER_HANDLE loader, ULONG lba, BYTE *buffPtr);
ULONG CddaAppGetChapterTotalTime(ULONG ulChapterNumber)
{
ULONG ulCurrenrTrackTime, ulNextTrackTime;
BYTE bFirstTrack, bLastTrack, bEntry;
CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
CDDA_TrackDescriptorInfo *pTDIEntry;
bFirstTrack = CddaAppControl.TOC.bFirstTrackNumber;
bLastTrack = CddaAppControl.TOC.bLastTrackNumber;
pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData +CDDA_TOC_HEADER_SIZE_BYTES );
if ( (ulChapterNumber < (ULONG)bFirstTrack) || (ulChapterNumber > (ULONG)bLastTrack) )
return 0;
bEntry =CddaAppControl.TOC.bTrackToEntry[(BYTE)ulChapterNumber ];
pTDIEntry =&(pTrackDescriptorInfo[bEntry]);
ulCurrenrTrackTime =(60 * pTDIEntry->bPMinute);
ulCurrenrTrackTime +=pTDIEntry->bPSecond;
ulCurrenrTrackTime+=(pTDIEntry->bPFrame /CD_FRAMES );
if (ulChapterNumber== CddaAppControl.TOC.bLastTrackNumber)
{
/* Use lead-out */
ulNextTrackTime = (60 * CddaAppControl.TOC.LeadOut.bPMinute);
ulNextTrackTime += CddaAppControl.TOC.LeadOut.bPSecond;
ulNextTrackTime += (CddaAppControl.TOC.LeadOut.bPFrame / CD_FRAMES);
}
else
{
/* Use next track */
/* Translate track to TOC entry number, then set pointer */
bEntry = CddaAppControl.TOC.bTrackToEntry[((BYTE)ulChapterNumber + 1)];
pTDIEntry = &(pTrackDescriptorInfo[bEntry]);
/* Determine time (in seconds) */
ulNextTrackTime = (60 * pTDIEntry->bPMinute);
ulNextTrackTime += pTDIEntry->bPSecond;
ulNextTrackTime += (pTDIEntry->bPFrame / CD_FRAMES);
}
return ( ulNextTrackTime - ulCurrenrTrackTime );
}
void PrintfAllTrackTimes()
{
int i=0;
ULONG ulCurrenrTrackTime, ulNextTrackTime;
BYTE bFirstTrack, bLastTrack, bEntry;
CDDA_TrackDescriptorInfo *pTrackDescriptorInfo;
CDDA_TrackDescriptorInfo *pTDIEntry;
ULONG TrackTime[CDDA_TOC_TRACK_MAXIMUM];
bFirstTrack = CddaAppControl.TOC.bFirstTrackNumber;
bLastTrack = CddaAppControl.TOC.bLastTrackNumber;
DbgPrint(("\nbFirstTrack %d \n", (int)bFirstTrack));
DbgPrint(("\bLastTrack %d \n", (int)bLastTrack));
pTrackDescriptorInfo = (CDDA_TrackDescriptorInfo *) (CddaAppControl.TOC.bData +CDDA_TOC_HEADER_SIZE_BYTES );
for(i=(int)bFirstTrack; i<=(int)bLastTrack ; i++)
{
bEntry =CddaAppControl.TOC.bTrackToEntry[(BYTE)i ];
pTDIEntry =&(pTrackDescriptorInfo[bEntry]);
ulCurrenrTrackTime =(60 * pTDIEntry->bPMinute);
ulCurrenrTrackTime +=pTDIEntry->bPSecond;
ulCurrenrTrackTime+=(pTDIEntry->bPFrame /CD_FRAMES );
if (i == CddaAppControl.TOC.bLastTrackNumber)
{
/* Use lead-out */
ulNextTrackTime = (60 * CddaAppControl.TOC.LeadOut.bPMinute);
ulNextTrackTime += CddaAppControl.TOC.LeadOut.bPSecond;
ulNextTrackTime += (CddaAppControl.TOC.LeadOut.bPFrame / CD_FRAMES);
}
else
{
/* Use next track */
/* Translate track to TOC entry number, then set pointer */
bEntry = CddaAppControl.TOC.bTrackToEntry[((BYTE)i + 1)];
pTDIEntry = &(pTrackDescriptorInfo[bEntry]);
/* Determine time (in seconds) */
ulNextTrackTime = (60 * pTDIEntry->bPMinute);
ulNextTrackTime += pTDIEntry->bPSecond;
ulNextTrackTime += (pTDIEntry->bPFrame / CD_FRAMES);
}
TrackTime[i] = ulNextTrackTime - ulCurrenrTrackTime;
DbgPrint(("Track %d: Time (in seconds): %d~%d (%d ) \n", i, ulCurrenrTrackTime, ulNextTrackTime, TrackTime[i] ));
}
}
/**
* Initialize the CDDA application.
*
* @param loader - Handle to loader module.
* @param dr - Handle to DR module.
* @param pe - Handle to PE module.
*
* @return OS_STATUS - Status / error code.
*/
OS_STATUS CddaAppInitialize(LOADER_HANDLE loader, DR_HANDLE dr, PE_HANDLE pe)
{
ULONG ulEvents;
/* Announce version information */
DbgPrint(("%s(): %s, %s\n", __FUNCTION__, CDDA_VERSION_STRING, CDDA_VERSION_DATE_STRING));
if ((loader == NULL) || (dr == NULL) || (pe == NULL))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: NULL HANDLE.\n", __FUNCTION__));
return (OS_NULL_POINTER);
}
/* Initialize variables */
CddaAppControl.tLoader = loader;
CddaAppControl.tDR = dr;
CddaAppControl.tPE = pe;
CddaAppControl.State = CDDA_STATE_UNITIALIZED;
CddaAppControl.RepeatMode = CDDA_REPEAT_NONE;
CddaAppControl.bABRepeatCount = 0;
CddaAppControl.sSpeed = 1;
CddaAppControl.ulCurrentPETime = 0; /* Held in LBA units */
CddaAppControl.ulRepeatATime = 0; /* Held in LBA units */
CddaAppControl.ulRepeatBTime = 0; /* Held in LBA units */
/* Retrieve the Table of Contents */
if (CDDA_SUCCESS != cddaRetrieveCddaTOC())
{
DbgPrint(("CddaAppInitialize() - cddaRetrieveCddaTOC FAILED\n"));
return (OS_FAILURE);
}
/* Parse the Table of Contents */
cddaParseCddaTOC();
/* Retrieve LBAs, which also sets current track info */
cddaGetTrackLBAs(CddaAppControl.TOC.bFirstTrackNumber, &CddaAppControl.CurrentTrack);
/* attach DR event handler */
if (DRAttachEvent(CddaAppControl.tDR, cddaDrEventCallback, CddaAppControl.tDR) != DR_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: DRAttachEvent Failed.\n", __FUNCTION__));
goto error_out;
}
ulEvents = (PE_EVENT_BEG_OF_STREAM | PE_EVENT_END_OF_STREAM | PE_EVENT_DISCONTINUITY | PE_EVENT_ASYNC_PREFILL | PE_EVENT_POSITION);
/* attach PE event handler */
if (PERegisterForEvents(CddaAppControl.tPE, cddaPEEventCallback, ulEvents, CddaAppControl.tPE) != PE_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlRegisterForEvents Failed.\n", __FUNCTION__));
goto error_out;
}
/* Check for DTS audio on a CDDA disc */
if (cddaAppCheckForDts(loader, CddaAppControl.CurrentTrack.ulStartLBA, bCddaLocalBuf) == TRUE)
{
/* TODO: configure for dts */
// if (PEiStreamCtrlDemuxAddAudioPS(CddaAppControl.tPE, 0, 0, INPUT_MAIN, AUDIO_TYPE_DTS) == PE_NOT_SUPPORTED)
// {
// ULONG out_msg[4];
// out_msg[0] = VDVD_STATUS_AUDIO_NOT_SUPPORTED;
// out_msg[1] = VDVD_INFO_AUDIOTYPE_DTS;
// UsrEventHandler(out_msg);
// goto error_out;
// }
}
else
{
PE_ISTREAMCTRL_AUDIO_ATTRIBUTES audio_attributes;
/* Set audio type: 16-bit, stereo PCM, 44.1 kHz */
audio_attributes.sampling_frequency = AUDIO_SAMPLING_FREQUENCY_44_1_KHz;
audio_attributes.n_channels = AUDIO_STEREO;
if (PEiStreamCtrlDemuxAddAudioPS(CddaAppControl.tPE, 0, 0, INPUT_MAIN, AUDIO_TYPE_PCM, &audio_attributes) == PE_NOT_SUPPORTED)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlSetAudioType Failed.\n", __FUNCTION__));
goto error_out;
}
}
/* create RTOS tasks */
if (cddaAppStartNav() != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: cddaAppStartNav Failed.\n", __FUNCTION__));
goto error_out;
}
/* prefill the PE */
if (PEiStreamCtrlPrefill(CddaAppControl.tPE, INPUT_MAIN, PE_ASYNC) != PE_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: PEiStreamCtrlPrefill Failed.\n", __FUNCTION__));
}
CddaAppControl.State = CDDA_STATE_STOPPED;
return (OS_OK);
error_out:
CddaAppUnInitialize();
return (OS_FAILURE);
}
/**
* Uninitialize / tear-down the CDDA application.
*
* @param none.
*
* @return OS_STATUS - Status / error code.
*/
OS_STATUS CddaAppUnInitialize(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -