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
CreateIAPEDecompressCore(CAPEInfo * pAPEInfo,int nStartBlock,int nFinishBlock,int * pErrorCode)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
CreateIAPEDecompress(const str_utf16 * pFilename,int * pErrorCode)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
CreateIAPEDecompressEx(CIO * pIO,int * pErrorCode)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
CreateIAPEDecompressEx2(CAPEInfo * pAPEInfo,int nStartBlock,int nFinishBlock,int * pErrorCode)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
CreateIAPECompress(int * pErrorCode)114 IAPECompress * __stdcall CreateIAPECompress(int * pErrorCode)
115 {
116 if (pErrorCode)
117 *pErrorCode = ERROR_SUCCESS;
118
119 return new CAPECompress();
120 }
121
FillWaveFormatEx(WAVEFORMATEX * pWaveFormatEx,int nSampleRate,int nBitsPerSample,int nChannels)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
FillWaveHeader(WAVE_HEADER * pWAVHeader,int nAudioBytes,WAVEFORMATEX * pWaveFormatEx,int nTerminatingBytes)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 }