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

📄 cdplayer.c

📁 SDL库 在进行视频显示程序spcaview安装时必须的库文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    SDL - Simple DirectMedia Layer    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*/#include "SDL_config.h"#include "CDPlayer.h"#include "AudioFilePlayer.h"#include "SDLOSXCAGuard.h"/* we're exporting these functions into C land for SDL_syscdrom.c *//*extern "C" {*//*///////////////////////////////////////////////////////////////////////////    Constants  //////////////////////////////////////////////////////////////////////////*/#define kAudioCDFilesystemID   (UInt16)(('J' << 8) | 'H') /* 'JH'; this avoids compiler warning *//* XML PList keys */#define kRawTOCDataString           "Format 0x02 TOC Data"#define kSessionsString             "Sessions"#define kSessionTypeString          "Session Type"#define kTrackArrayString           "Track Array"#define kFirstTrackInSessionString      "First Track"#define kLastTrackInSessionString       "Last Track"#define kLeadoutBlockString         "Leadout Block"#define kDataKeyString              "Data"#define kPointKeyString             "Point"#define kSessionNumberKeyString         "Session Number"#define kStartBlockKeyString            "Start Block"       /*///////////////////////////////////////////////////////////////////////////    Globals  //////////////////////////////////////////////////////////////////////////*/#pragma mark -- Globals --static int             playBackWasInit = 0;static AudioUnit        theUnit;static AudioFilePlayer* thePlayer = NULL;static CDPlayerCompletionProc   completionProc = NULL;static SDL_mutex       *apiMutex = NULL;static SDL_sem         *callbackSem;static SDL_CD*          theCDROM;/*///////////////////////////////////////////////////////////////////////////    Prototypes  //////////////////////////////////////////////////////////////////////////*/#pragma mark -- Prototypes --static OSStatus CheckInit ();static void     FilePlayNotificationHandler (void* inRefCon, OSStatus inStatus);static int      RunCallBackThread (void* inRefCon);#pragma mark -- Public Functions --void     Lock (){    if (!apiMutex) {        apiMutex = SDL_CreateMutex();    }    SDL_mutexP(apiMutex);}void     Unlock (){    SDL_mutexV(apiMutex);}int DetectAudioCDVolumes(FSVolumeRefNum *volumes, int numVolumes){    int volumeIndex;    int cdVolumeCount = 0;    OSStatus result = noErr;        for (volumeIndex = 1; result == noErr || result != nsvErr; volumeIndex++)    {        FSVolumeRefNum  actualVolume;        FSVolumeInfo    volumeInfo;                memset (&volumeInfo, 0, sizeof(volumeInfo));                result = FSGetVolumeInfo (kFSInvalidVolumeRefNum,                                  volumeIndex,                                  &actualVolume,                                  kFSVolInfoFSInfo,                                  &volumeInfo,                                  NULL,                                  NULL);                  if (result == noErr)        {            if (volumeInfo.filesystemID == kAudioCDFilesystemID) /* It's an audio CD */            {                if (volumes != NULL && cdVolumeCount < numVolumes)                    volumes[cdVolumeCount] = actualVolume;                            cdVolumeCount++;            }        }        else         {            /* I'm commenting this out because it seems to be harmless */            /*SDL_SetError ("DetectAudioCDVolumes: FSGetVolumeInfo returned %d", result);*/        }    }            return cdVolumeCount;}int ReadTOCData (FSVolumeRefNum theVolume, SDL_CD *theCD){    HFSUniStr255      dataForkName;    OSStatus          theErr;    SInt16            forkRefNum;    SInt64            forkSize;    Ptr               forkData = 0;    ByteCount         actualRead;    CFDataRef         dataRef = 0;    CFPropertyListRef propertyListRef = 0;    FSRefParam      fsRefPB;    FSRef           tocPlistFSRef;        const char* error = "Unspecified Error";        /* get stuff from .TOC.plist */    fsRefPB.ioCompletion = NULL;    fsRefPB.ioNamePtr = "\p.TOC.plist";    fsRefPB.ioVRefNum = theVolume;    fsRefPB.ioDirID = 0;    fsRefPB.newRef = &tocPlistFSRef;        theErr = PBMakeFSRefSync (&fsRefPB);    if(theErr != noErr) {        error = "PBMakeFSRefSync";        goto bail;    }        /* Load and parse the TOC XML data */    theErr = FSGetDataForkName (&dataForkName);    if (theErr != noErr) {        error = "FSGetDataForkName";        goto bail;    }        theErr = FSOpenFork (&tocPlistFSRef, dataForkName.length, dataForkName.unicode, fsRdPerm, &forkRefNum);    if (theErr != noErr) {        error = "FSOpenFork";        goto bail;    }        theErr = FSGetForkSize (forkRefNum, &forkSize);    if (theErr != noErr) {        error = "FSGetForkSize";        goto bail;    }        /* Allocate some memory for the XML data */    forkData = NewPtr (forkSize);    if(forkData == NULL) {        error = "NewPtr";        goto bail;    }        theErr = FSReadFork (forkRefNum, fsFromStart, 0 /* offset location */, forkSize, forkData, &actualRead);    if(theErr != noErr) {        error = "FSReadFork";        goto bail;    }        dataRef = CFDataCreate (kCFAllocatorDefault, (UInt8 *)forkData, forkSize);    if(dataRef == 0) {        error = "CFDataCreate";        goto bail;    }    propertyListRef = CFPropertyListCreateFromXMLData (kCFAllocatorDefault,                                                       dataRef,                                                       kCFPropertyListImmutable,                                                       NULL);    if (propertyListRef == NULL) {        error = "CFPropertyListCreateFromXMLData";        goto bail;    }    /* Now we got the Property List in memory. Parse it. */        /* First, make sure the root item is a CFDictionary. If not, release and bail. */    if(CFGetTypeID(propertyListRef)== CFDictionaryGetTypeID())    {        CFDictionaryRef dictRef = (CFDictionaryRef)propertyListRef;                CFDataRef   theRawTOCDataRef;        CFArrayRef  theSessionArrayRef;        CFIndex     numSessions;        CFIndex     index;                /* This is how we get the Raw TOC Data */        theRawTOCDataRef = (CFDataRef)CFDictionaryGetValue (dictRef, CFSTR(kRawTOCDataString));                /* Get the session array info. */        theSessionArrayRef = (CFArrayRef)CFDictionaryGetValue (dictRef, CFSTR(kSessionsString));                /* Find out how many sessions there are. */        numSessions = CFArrayGetCount (theSessionArrayRef);                /* Initialize the total number of tracks to 0 */        theCD->numtracks = 0;                /* Iterate over all sessions, collecting the track data */        for(index = 0; index < numSessions; index++)        {            CFDictionaryRef theSessionDict;            CFNumberRef     leadoutBlock;            CFArrayRef      trackArray;            CFIndex         numTracks;            CFIndex         trackIndex;            UInt32          value = 0;                        theSessionDict      = (CFDictionaryRef) CFArrayGetValueAtIndex (theSessionArrayRef, index);            leadoutBlock        = (CFNumberRef) CFDictionaryGetValue (theSessionDict, CFSTR(kLeadoutBlockString));                        trackArray = (CFArrayRef)CFDictionaryGetValue (theSessionDict, CFSTR(kTrackArrayString));                        numTracks = CFArrayGetCount (trackArray);            for(trackIndex = 0; trackIndex < numTracks; trackIndex++) {                                    CFDictionaryRef theTrackDict;                CFNumberRef     trackNumber;                CFNumberRef     sessionNumber;                CFNumberRef     startBlock;                CFBooleanRef    isDataTrack;                UInt32          value;                                theTrackDict  = (CFDictionaryRef) CFArrayGetValueAtIndex (trackArray, trackIndex);                                trackNumber   = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kPointKeyString));                sessionNumber = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kSessionNumberKeyString));                startBlock    = (CFNumberRef)  CFDictionaryGetValue (theTrackDict, CFSTR(kStartBlockKeyString));                isDataTrack   = (CFBooleanRef) CFDictionaryGetValue (theTrackDict, CFSTR(kDataKeyString));                                                                        /* Fill in the SDL_CD struct */                int idx = theCD->numtracks++;                CFNumberGetValue (trackNumber, kCFNumberSInt32Type, &value);                theCD->track[idx].id = value;                                CFNumberGetValue (startBlock, kCFNumberSInt32Type, &value);                theCD->track[idx].offset = value;                theCD->track[idx].type = (isDataTrack == kCFBooleanTrue) ? SDL_DATA_TRACK : SDL_AUDIO_TRACK;                /* Since the track lengths are not stored in .TOC.plist we compute them. */                if (trackIndex > 0) {                    theCD->track[idx-1].length = theCD->track[idx].offset - theCD->track[idx-1].offset;                }            }                        /* Compute the length of the last track */            CFNumberGetValue (leadoutBlock, kCFNumberSInt32Type, &value);                        theCD->track[theCD->numtracks-1].length =                 value - theCD->track[theCD->numtracks-1].offset;            /* Set offset to leadout track */            theCD->track[theCD->numtracks].offset = value;        }        }    theErr = 0;    goto cleanup;bail:    SDL_SetError ("ReadTOCData: %s returned %d", error, theErr);    theErr = -1;cleanup:    if (propertyListRef != NULL)        CFRelease(propertyListRef);    if (dataRef != NULL)        CFRelease(dataRef);    if (forkData != NULL)        DisposePtr(forkData);            FSCloseFork (forkRefNum);    return theErr;}int ListTrackFiles (FSVolumeRefNum theVolume, FSRef *trackFiles, int numTracks)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -