/* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus * Copyright (C) 2001-2006 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Header$ * */ #include #include "common/stdafx.h" #include "common/system.h" #include "cd_msa.h" #include "start.h" // for appFileCreat static void doErr(Err e, const Char *msg) { Char err[100]; StrPrintF(err, "%ld : " , e); StrCat(err,msg); FrmCustomAlert(1000,err,0,0); } MsaCDPlayer::MsaCDPlayer(OSystem *sys) { _sys = sys; _msaRefNum = sysInvalidRefNum; _msaLoops = 0; _msaStopTime = 0; _msaTrackEndSu = 0; } bool MsaCDPlayer::init() { SonySysFtrSysInfoP sonySysFtrSysInfoP; Err error = errNone; if (!(error = FtrGet(sonySysFtrCreator, sonySysFtrNumSysInfoP, (UInt32*)&sonySysFtrSysInfoP))) { // not found with audio adapter ?! //if (sonySysFtrSysInfoP->libr & sonySysFtrSysInfoLibrMsa) { if ((error = SysLibFind(sonySysLibNameMsa, &_msaRefNum))) if (error == sysErrLibNotFound) error = SysLibLoad(sonySysFileTMsaLib, sonySysFileCMsaLib, &_msaRefNum); // FIXME : still don't understand how this lib works, it seems to be very unstable // and with the very bad documentation provided by Sony it's difficult to find out why // this doesn't work the same way on build-in MP3 device and external MP3 devices if (!error) { //MsaLibClose(_msaRefNum, msaLibOpenModeAlbum); // close the lib if we previously let it open (?) Need to add Notify for sonySysNotifyMsaEnforceOpenEvent just in case ... error = MsaLibOpen(_msaRefNum, msaLibOpenModeAlbum); //if (error == msaErrAlreadyOpen) // error = MsaLibEnforceOpen(_msaRefNum, msaLibOpenModeAlbum, appFileCreator); //error = (error != msaErrStillOpen) ? error : errNone; } //} } // if (error) // _msaRefNum = sysInvalidRefNum; _isInitialized = (_msaRefNum != sysInvalidRefNum); initInternal(); return _isInitialized; } void MsaCDPlayer::initInternal() { if (!_isInitialized) return; Err e; Char nameP[256]; UInt32 dummy, albumIterater = albumIteratorStart; MemSet(&_msaAlbum, sizeof(_msaAlbum), 0); _msaAlbum.maskflag = msa_INF_ALBUM; _msaAlbum.code = msa_LANG_CODE_ASCII; _msaAlbum.nameP = nameP; _msaAlbum.fileNameLength = 256; e = MsaAlbumEnumerate(_msaRefNum, &albumIterater, &_msaAlbum); e = MsaSetAlbum(_msaRefNum, _msaAlbum.albumRefNum, &dummy); // TODO : use RMC to control volume MsaOutCapabilityType capability; MsaOutGetCapability(_msaRefNum, &capability); _volumeLLimit = capability.volumeLLimit; _volumeRLimit = capability.volumeRLimit; } void MsaCDPlayer::setVolume(int volume) { _volumeLevel = volume; MsaOutSetVolume(_msaRefNum, (_volumeLLimit * volume) / 100, (_volumeRLimit * volume) / 100); } void MsaCDPlayer::release() { if (_isInitialized) { if (_msaRefNum != sysInvalidRefNum) { // stop the current track if any (needed if we use enforce open to prevent the track to play after exit) MsaStop(_msaRefNum, true); MsaLibClose(_msaRefNum, msaLibOpenModeAlbum); } } // self delete delete this; } bool MsaCDPlayer::poll() { if (!_isInitialized) return false; MsaPBStatus pb; MsaGetPBStatus(_msaRefNum, &pb); return (_msaLoops != 0 && (pb.currentSU < _msaTrackEndSu || pb.status != msa_STOPSTATUS)); } void MsaCDPlayer::update() { if (!_isInitialized) return; // get playback status MsaPBStatus pb; MsaGetPBStatus(_msaRefNum, &pb); // stop replay upon request of stopCD() if (_msaStopTime != 0 && _sys->getMillis() >= _msaStopTime) { MsaStop(_msaRefNum, true); _msaLoops = 0; _msaStopTime = 0; _msaTrackEndSu = 0; return; } // not fully played nad still playing the correct track // (when playing a full track the return SU is not correct // and so we need to check if we are still playing the correct track) if (pb.currentSU < _msaTrackEndSu) { UInt16 trackNo; MsaPBListIndexToTrackNo(_msaRefNum, pb.currentpblistindex, &trackNo); if (trackNo == _msaTrack) return; } MsaStop(_msaRefNum, true); if (_msaLoops == 0) return; // track ends and last play, force stop if still playing /* if (_msaLoops != 1 && pb.status != msa_STOPSTATUS) { MsaStop(_msaRefNum, true); return; } */ // loop again ? if (_msaLoops > 0) _msaLoops--; // loop if needed if (_msaLoops != 0) { if (_msaStartFrame == 0 && _msaDuration == 0) MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); else MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP); } } void MsaCDPlayer::stop() { /* Stop CD Audio in 1/10th of a second */ if (!_isInitialized) return; _msaStopTime = _sys->getMillis() + 100; _msaLoops = 0; return; } void MsaCDPlayer::play(int track, int num_loops, int start_frame, int duration) { if (!_isInitialized) return; if (!num_loops && !start_frame) return; _msaTrack = track + gVars->CD.firstTrack - 1; // first track >= 1 ?, not 0 (0=album) _msaLoops = num_loops; _msaStartFrame = TO_MSECS(start_frame); _msaDuration = TO_MSECS(duration); Err e; MemHandle trackH; // stop current play if any MsaStop(_msaRefNum, true); _msaStopTime = 0; // retreive track infos e = MsaGetTrackInfo(_msaRefNum, _msaTrack, 0, msa_LANG_CODE_ASCII, &trackH); // track exists if (!e && trackH) { MsaTime msaTime; MsaTrackInfo *trackP; UInt32 SU, fullLength; // FIXME (?) : this enable MsaSuToTime to return the right value in some cases MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); MsaStop(_msaRefNum, true); // get the msa time trackP = (MsaTrackInfo *)MemHandleLock(trackH); MsaSuToTime(_msaRefNum, trackP->totalsu, &msaTime); SU = trackP->totalsu; MemPtrUnlock(trackP); MemHandleFree(trackH); // MSA frame in milli-seconds fullLength = FROM_MIN(msaTime.minute); fullLength += FROM_SEC(msaTime.second); fullLength += msaTime.frame; if (_msaDuration > 0) { _msaTrackLength = _msaDuration; } else if (_msaStartFrame > 0) { _msaTrackLength = fullLength; _msaTrackLength -= _msaStartFrame; } else { _msaTrackLength = fullLength; } // try to play the track if (start_frame == 0 && duration == 0) { MsaPlay(_msaRefNum, _msaTrack, 0, msa_PBRATE_SP); _msaTrackEndSu = SU; } else { // FIXME : MsaTimeToSu doesn't work ... (may work with previous FIXME) _msaTrackStartSu = (UInt32) ((float)(_msaStartFrame) / ((float)fullLength / (float)SU)); _msaTrackEndSu = (UInt32) ((float)(_msaTrackLength) / ((float)fullLength / (float)SU)); _msaTrackEndSu += _msaTrackStartSu; if (_msaTrackEndSu > SU) _msaTrackEndSu = SU; MsaPlay(_msaRefNum, _msaTrack, _msaTrackStartSu, msa_PBRATE_SP); } } // TODO : use default track length if track not found }