/*****************************/ /*** PSX CDXA Player Stuff ***/ /*** Another one by Dave ***/ /*****************************/ // Note, need to add blanks in between tracks #include "system\global.h" #include "fileio/fileio.h" #include "fileio/filetab.h" #include "sound\cdxa.h" #include #include //#ifndef __SOUND_SNDBANK_H__ //#include "sound\sndbank.h" //#endif // Add this to have CDXA on PC build!! // You will need a CD with Track1 synced to something, oh, and a CD drive #if 0//|| defined(__USER_daveo__) #define FORCE_XA 1 #endif #if __FILE_SYSTEM__==CD | FORCE_XA #define ENABLE_XA #endif #if defined(__USER_CDBUILD__) #undef FORCE_XA #endif /*****************************************************************************/ CXAStream::XA_MODE CXAStream::Mode=XA_MODE_NOTINIT; int CXAStream::Status; int CXAStream::StartSector; CXAStream::sXAStream CXAStream::Stream[XA_STREAM_MAX]; int CXAStream::CurrentStream; int CXAStream::PauseFlag; // Speech SpeechEquate CXAStream::Queue[XA_QUEUE_MAX]; u16 CXAStream::QueueCount; // Volume int CXAStream::s_masterVolumeL=XA_DEFAULT_VOL; int CXAStream::s_masterVolumeR=XA_DEFAULT_VOL; /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CXAStream::XACDReadyCallback(int Intr, u8 *Result) { static int ErrorRetry; u32 XABuffer[8]; u16 ID,Track; sXAStream &ThisStream=CXAStream::Stream[CXAStream::CurrentStream]; CXAStream::Status=Intr; if (CXAStream::Mode==XA_MODE_IDLE) return; switch (Intr) { case CdlNoIntr: break; case CdlDataReady: // Check end of XA using video termination ErrorRetry=0; CdGetSector((u_long *)XABuffer,8); ID = *(unsigned short *)(XABuffer+3); Track = *((unsigned short *)(XABuffer+3)+1); Track = (Track&31744)>>10; if (Track==0) { ThisStream.Entry.CurrentSector++; // track position } else { if (ID==352) { if (Track==ThisStream.Entry.Channel) { // DbgMsg0("TrackEnd\n"); CXAStream::SetVolumeOff(); CdControlF(CdlPause,0); CXAStream::Mode=XA_MODE_END; } } } break; case CdlComplete: break; case CdlAcknowledge: break; case CdlDataEnd: break; case CdlDiskError: if (!ErrorRetry) { ErrorRetry=25; // CXAStream::Mode=XA_MODE_RESUME; } else ErrorRetry--; break; default: break; } } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CXAStream::Init() { #ifdef FORCE_XA SYSTEM_DBGMSG("FORCE XA\n"); while (!CdInit()); CFileIO::FindAllFilePos(); CXAStream::SetSector(CFileIO::GetFilePos(FILEPOS_TRACK1)); #endif SYSTEM_DBGMSG("XA INITIALISED"); // Set defaults CurrentStream=XA_STREAM_MUSIC; Stream[XA_STREAM_MUSIC].BaseChannel =XA_MUSIC_TRACK; Stream[XA_STREAM_SPEECH].BaseChannel=XA_SPEECH_TRACK; Reset(); } /*****************************************************************************/ void CXAStream::Start(int Str,u32 Sector,u32 Channel,s32 LVol,s32 RVol) { #ifdef ENABLE_XA if (Mode==XA_MODE_NOTINIT) Init(); sXAStream &ThisStream=Stream[Str]; SetVolumeOff(); CdControlF(CdlPause,0); CurrentStream=Str; ThisStream.Entry.StartSector=Sector; ThisStream.Entry.CurrentSector=Sector; ThisStream.Entry.Channel=Channel+ThisStream.BaseChannel; ThisStream.Entry.LVol=LVol; ThisStream.Entry.RVol=RVol; Mode=XA_MODE_START; CdReadyCallback((CdlCB)XACDReadyCallback); #endif } /*****************************************************************************/ void CXAStream::Stop() { Reset(); Mode=XA_MODE_STOP; } /*****************************************************************************/ void CXAStream::PlayMusic(u32 TrackNo) { Start(XA_STREAM_MUSIC,0,0,XA_DEFAULT_VOL,XA_DEFAULT_VOL); } /*****************************************************************************/ void CXAStream::PlaySpeech(SpeechEquate SpeechNo,int ForcePlay) { u32 Channel=SpeechNo>>XA_CHANNEL_SHIFT; u32 Speech=SpeechNo & XA_SPEECH_MASK; u32 Sector=Speech*XA_TRACK_MAX; if (CurrentStream==XA_STREAM_SPEECH && Mode==XA_MODE_PLAY && !ForcePlay) { // Check Current if (Stream[CurrentStream].Entry.Channel==Channel && Stream[CurrentStream].Entry.StartSector==Sector) return; // Check Queue if (QueueCount>=(int)XA_QUEUE_MAX) return; for (int Loop=0;Loop SpuL CDVol.val1 = 127; // CdL -> SpuR CDVol.val2 = 127; // CdR -> SpuR CDVol.val3 = 127; // CdR -> SpuL CdMix(&CDVol); } /*****************************************************************************/ void CXAStream::SetVolumeOff() { CdlATV CDVol; SpuCommonAttr Attr; SpuSetCommonCDVolume(0,0); SpuSetCommonCDMix(SPU_ON); CDVol.val0 = 0; // CdL -> SpuL CDVol.val1 = 0; // CdL -> SpuR CDVol.val2 = 0; // CdR -> SpuR CDVol.val3 = 0; // CdR -> SpuL CdMix(&CDVol); } /*****************************************************************************/ void CXAStream::setMasterVolume(int _volumeL,int _volumeR) { ASSERT(_volumeL>=MIN_VOLUME) ASSERT(_volumeL<=MAX_VOLUME); ASSERT(_volumeR>=MIN_VOLUME) ASSERT(_volumeR<=MAX_VOLUME); s_masterVolumeL=_volumeL; s_masterVolumeR=_volumeR; }