1 #include "All.h" 2 #include "MACLib.h" 3 4 //#include "APECompress.h" 5 //#include "APECompressCreate.h" 6 //#include "APECompressCore.h" 7 #include "APECompress.h" 8 #include "APEDecompress.h" 9 #include "APEInfo.h" 10 #include "APELink.h" 11 12 #undef BACKWARDS_COMPATIBILITY 13 14 #ifdef BACKWARDS_COMPATIBILITY 15 #include "Old/APEDecompressOld.h" 16 #endif 17 18 IAPEDecompress * CreateIAPEDecompressCore(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode) 19 { 20 IAPEDecompress * pAPEDecompress = NULL; 21 if (pAPEInfo != NULL && *pErrorCode == ERROR_SUCCESS) 22 { 23 try 24 { 25 if (pAPEInfo->GetInfo(APE_INFO_FILE_VERSION) >= 3930) 26 pAPEDecompress = new CAPEDecompress(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock); 27 #ifdef BACKWARDS_COMPATIBILITY 28 else 29 pAPEDecompress = new CAPEDecompressOld(pErrorCode, pAPEInfo, nStartBlock, nFinishBlock); 30 #endif 31 32 if (pAPEDecompress == NULL || *pErrorCode != ERROR_SUCCESS) 33 { 34 SAFE_DELETE(pAPEDecompress) 35 } 36 } 37 catch(...) 38 { 39 SAFE_DELETE(pAPEDecompress) 40 *pErrorCode = ERROR_UNDEFINED; 41 } 42 } 43 44 return pAPEDecompress; 45 } 46 47 IAPEDecompress * __stdcall CreateIAPEDecompress(const str_utf16 * pFilename, int * pErrorCode) 48 { 49 // error check the parameters 50 if ((pFilename == NULL) || (wcslen(pFilename) == 0)) 51 { 52 if (pErrorCode) *pErrorCode = ERROR_BAD_PARAMETER; 53 return NULL; 54 } 55 56 // variables 57 int nErrorCode = ERROR_UNDEFINED; 58 CAPEInfo * pAPEInfo = NULL; 59 int nStartBlock = -1; int nFinishBlock = -1; 60 61 // get the extension 62 const str_utf16 * pExtension = &pFilename[wcslen(pFilename)]; 63 while ((pExtension > pFilename) && (*pExtension != '.')) 64 pExtension--; 65 66 // take the appropriate action (based on the extension) 67 if (wcsicmp(pExtension, ".apl") == 0) 68 { 69 // "link" file (.apl linked large APE file) 70 CAPELink APELink(pFilename); 71 if (APELink.GetIsLinkFile()) 72 { 73 pAPEInfo = new CAPEInfo(&nErrorCode, APELink.GetImageFilename(), new CAPETag(pFilename, TRUE)); 74 nStartBlock = APELink.GetStartBlock(); nFinishBlock = APELink.GetFinishBlock(); 75 } 76 } 77 else /*if ((wcsicmp(pExtension, L".mac") == 0) || (wcsicmp(pExtension, L".ape") == 0))*/ // SHINTA: To play regardless of the extension. 78 { 79 // plain .ape file 80 pAPEInfo = new CAPEInfo(&nErrorCode, pFilename); 81 } 82 83 // fail if we couldn't get the file information 84 if (pAPEInfo == NULL) 85 { 86 if (pErrorCode) *pErrorCode = ERROR_INVALID_INPUT_FILE; 87 return NULL; 88 } 89 90 // create and return 91 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode); 92 if (pErrorCode) *pErrorCode = nErrorCode; 93 return pAPEDecompress; 94 } 95 96 IAPEDecompress * __stdcall CreateIAPEDecompressEx(CIO * pIO, int * pErrorCode) 97 { 98 int nErrorCode = ERROR_UNDEFINED; 99 CAPEInfo * pAPEInfo = new CAPEInfo(&nErrorCode, pIO); 100 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, -1, -1, &nErrorCode); 101 if (pErrorCode) *pErrorCode = nErrorCode; 102 return pAPEDecompress; 103 } 104 105 106 IAPEDecompress * __stdcall CreateIAPEDecompressEx2(CAPEInfo * pAPEInfo, int nStartBlock, int nFinishBlock, int * pErrorCode) 107 { 108 int nErrorCode = ERROR_SUCCESS; 109 IAPEDecompress * pAPEDecompress = CreateIAPEDecompressCore(pAPEInfo, nStartBlock, nFinishBlock, &nErrorCode); 110 if (pErrorCode) *pErrorCode = nErrorCode; 111 return pAPEDecompress; 112 } 113 114 IAPECompress * __stdcall CreateIAPECompress(int * pErrorCode) 115 { 116 if (pErrorCode) 117 *pErrorCode = ERROR_SUCCESS; 118 119 return new CAPECompress(); 120 } 121 122 int __stdcall FillWaveFormatEx(WAVEFORMATEX * pWaveFormatEx, int nSampleRate, int nBitsPerSample, int nChannels) 123 { 124 pWaveFormatEx->cbSize = 0; 125 pWaveFormatEx->nSamplesPerSec = nSampleRate; 126 pWaveFormatEx->wBitsPerSample = nBitsPerSample; 127 pWaveFormatEx->nChannels = nChannels; 128 pWaveFormatEx->wFormatTag = 1; 129 130 pWaveFormatEx->nBlockAlign = (pWaveFormatEx->wBitsPerSample / 8) * pWaveFormatEx->nChannels; 131 pWaveFormatEx->nAvgBytesPerSec = pWaveFormatEx->nBlockAlign * pWaveFormatEx->nSamplesPerSec; 132 133 return ERROR_SUCCESS; 134 } 135 136 int __stdcall FillWaveHeader(WAVE_HEADER * pWAVHeader, int nAudioBytes, WAVEFORMATEX * pWaveFormatEx, int nTerminatingBytes) 137 { 138 try 139 { 140 // RIFF header 141 memcpy(pWAVHeader->cRIFFHeader, "RIFF", 4); 142 pWAVHeader->nRIFFBytes = (nAudioBytes + 44) - 8 + nTerminatingBytes; 143 144 // format header 145 memcpy(pWAVHeader->cDataTypeID, "WAVE", 4); 146 memcpy(pWAVHeader->cFormatHeader, "fmt ", 4); 147 148 // the format chunk is the first 16 bytes of a waveformatex 149 pWAVHeader->nFormatBytes = 16; 150 memcpy(&pWAVHeader->nFormatTag, pWaveFormatEx, 16); 151 152 // the data header 153 memcpy(pWAVHeader->cDataHeader, "data", 4); 154 pWAVHeader->nDataBytes = nAudioBytes; 155 156 return ERROR_SUCCESS; 157 } 158 catch(...) { return ERROR_UNDEFINED; } 159 }