author | llornkcor <llornkcor> | 2002-07-20 22:07:31 (UTC) |
---|---|---|
committer | llornkcor <llornkcor> | 2002-07-20 22:07:31 (UTC) |
commit | 2342d48be31847e7ead9d1cc682452e8f0122351 (patch) (unidiff) | |
tree | 8329bb94e9d429c905a0ef6b881cf1c0f775bf14 /core/multimedia/opieplayer/modplug/load_wav.cpp | |
parent | 0f24c1fb86d3bb58d8696358b824c0e01752b10d (diff) | |
download | opie-2342d48be31847e7ead9d1cc682452e8f0122351.zip opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.gz opie-2342d48be31847e7ead9d1cc682452e8f0122351.tar.bz2 |
initial commit of modplugin
Diffstat (limited to 'core/multimedia/opieplayer/modplug/load_wav.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/modplug/load_wav.cpp | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/modplug/load_wav.cpp b/core/multimedia/opieplayer/modplug/load_wav.cpp new file mode 100644 index 0000000..f445273 --- a/dev/null +++ b/core/multimedia/opieplayer/modplug/load_wav.cpp | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and modify it | ||
3 | * under the terms of the GNU General Public License as published by the | ||
4 | * Free Software Foundation; either version 2 of the license or (at your | ||
5 | * option) any later version. | ||
6 | * | ||
7 | * Authors: Olivier Lapicque <olivierl@jps.net> | ||
8 | */ | ||
9 | |||
10 | #include "stdafx.h" | ||
11 | #include "sndfile.h" | ||
12 | |||
13 | #ifndef WAVE_FORMAT_EXTENSIBLE | ||
14 | #define WAVE_FORMAT_EXTENSIBLE0xFFFE | ||
15 | #endif | ||
16 | |||
17 | ///////////////////////////////////////////////////////////// | ||
18 | // WAV file support | ||
19 | |||
20 | BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength) | ||
21 | //--------------------------------------------------------------- | ||
22 | { | ||
23 | DWORD dwMemPos = 0; | ||
24 | WAVEFILEHEADER *phdr = (WAVEFILEHEADER *)lpStream; | ||
25 | WAVEFORMATHEADER *pfmt = (WAVEFORMATHEADER *)(lpStream + sizeof(WAVEFILEHEADER)); | ||
26 | if ((!lpStream) || (dwMemLength < (DWORD)sizeof(WAVEFILEHEADER))) return FALSE; | ||
27 | if ((phdr->id_RIFF != IFFID_RIFF) || (phdr->id_WAVE != IFFID_WAVE) | ||
28 | || (pfmt->id_fmt != IFFID_fmt)) return FALSE; | ||
29 | dwMemPos = sizeof(WAVEFILEHEADER) + 8 + pfmt->hdrlen; | ||
30 | if ((dwMemPos + 8 >= dwMemLength) | ||
31 | || ((pfmt->format != WAVE_FORMAT_PCM) && (pfmt->format != WAVE_FORMAT_EXTENSIBLE)) | ||
32 | || (pfmt->channels > 4) | ||
33 | || (!pfmt->channels) | ||
34 | || (!pfmt->freqHz) | ||
35 | || (pfmt->bitspersample & 7) | ||
36 | || (pfmt->bitspersample < 8) | ||
37 | || (pfmt->bitspersample > 32)) return FALSE; | ||
38 | WAVEDATAHEADER *pdata; | ||
39 | for (;;) | ||
40 | { | ||
41 | pdata = (WAVEDATAHEADER *)(lpStream + dwMemPos); | ||
42 | if (pdata->id_data == IFFID_data) break; | ||
43 | dwMemPos += pdata->length + 8; | ||
44 | if (dwMemPos + 8 >= dwMemLength) return FALSE; | ||
45 | } | ||
46 | m_nType = MOD_TYPE_WAV; | ||
47 | m_nSamples = 0; | ||
48 | m_nInstruments = 0; | ||
49 | m_nChannels = 4; | ||
50 | m_nDefaultSpeed = 8; | ||
51 | m_nDefaultTempo = 125; | ||
52 | m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling | ||
53 | Order[0] = 0; | ||
54 | Order[1] = 0xFF; | ||
55 | PatternSize[0] = PatternSize[1] = 64; | ||
56 | if ((Patterns[0] = AllocatePattern(64, 4)) == NULL) return TRUE; | ||
57 | if ((Patterns[1] = AllocatePattern(64, 4)) == NULL) return TRUE; | ||
58 | UINT samplesize = (pfmt->channels * pfmt->bitspersample) >> 3; | ||
59 | UINT len = pdata->length, bytelen; | ||
60 | if (dwMemPos + len > dwMemLength - 8) len = dwMemLength - dwMemPos - 8; | ||
61 | len /= samplesize; | ||
62 | bytelen = len; | ||
63 | if (pfmt->bitspersample >= 16) bytelen *= 2; | ||
64 | if (len > MAX_SAMPLE_LENGTH) len = MAX_SAMPLE_LENGTH; | ||
65 | if (!len) return TRUE; | ||
66 | // Setting up module length | ||
67 | DWORD dwTime = ((len * 50) / pfmt->freqHz) + 1; | ||
68 | DWORD framesperrow = (dwTime + 63) / 63; | ||
69 | if (framesperrow < 4) framesperrow = 4; | ||
70 | UINT norders = 1; | ||
71 | while (framesperrow >= 0x20) | ||
72 | { | ||
73 | Order[norders++] = 1; | ||
74 | Order[norders] = 0xFF; | ||
75 | framesperrow = (dwTime + (64 * norders - 1)) / (64 * norders); | ||
76 | if (norders >= MAX_ORDERS-1) break; | ||
77 | } | ||
78 | m_nDefaultSpeed = framesperrow; | ||
79 | for (UINT iChn=0; iChn<4; iChn++) | ||
80 | { | ||
81 | ChnSettings[iChn].nPan = (iChn & 1) ? 256 : 0; | ||
82 | ChnSettings[iChn].nVolume = 64; | ||
83 | ChnSettings[iChn].dwFlags = 0; | ||
84 | } | ||
85 | // Setting up speed command | ||
86 | MODCOMMAND *pcmd = Patterns[0]; | ||
87 | pcmd[0].command = CMD_SPEED; | ||
88 | pcmd[0].param = (BYTE)m_nDefaultSpeed; | ||
89 | pcmd[0].note = 5*12+1; | ||
90 | pcmd[0].instr = 1; | ||
91 | pcmd[1].note = pcmd[0].note; | ||
92 | pcmd[1].instr = pcmd[0].instr; | ||
93 | m_nSamples = pfmt->channels; | ||
94 | // Support for Multichannel Wave | ||
95 | for (UINT nChn=0; nChn<m_nSamples; nChn++) | ||
96 | { | ||
97 | MODINSTRUMENT *pins = &Ins[nChn+1]; | ||
98 | pcmd[nChn].note = pcmd[0].note; | ||
99 | pcmd[nChn].instr = (BYTE)(nChn+1); | ||
100 | pins->nLength = len; | ||
101 | pins->nC4Speed = pfmt->freqHz; | ||
102 | pins->nVolume = 256; | ||
103 | pins->nPan = 128; | ||
104 | pins->nGlobalVol = 64; | ||
105 | pins->uFlags = (WORD)((pfmt->bitspersample >= 16) ? CHN_16BIT : 0); | ||
106 | pins->uFlags |= CHN_PANNING; | ||
107 | if (m_nSamples > 1) | ||
108 | { | ||
109 | switch(nChn) | ||
110 | { | ||
111 | case 0:pins->nPan = 0; break; | ||
112 | case 1:pins->nPan = 256; break; | ||
113 | case 2: pins->nPan = (WORD)((m_nSamples == 3) ? 128 : 64); pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break; | ||
114 | case 3: pins->nPan = 192; pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break; | ||
115 | default: pins->nPan = 128; break; | ||
116 | } | ||
117 | } | ||
118 | if ((pins->pSample = AllocateSample(bytelen+8)) == NULL) return TRUE; | ||
119 | if (pfmt->bitspersample >= 16) | ||
120 | { | ||
121 | int slsize = pfmt->bitspersample >> 3; | ||
122 | signed short *p = (signed short *)pins->pSample; | ||
123 | signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn*slsize+slsize-2); | ||
124 | for (UINT i=0; i<len; i++) | ||
125 | { | ||
126 | p[i] = *((signed short *)psrc); | ||
127 | psrc += samplesize; | ||
128 | } | ||
129 | p[len+1] = p[len] = p[len-1]; | ||
130 | } else | ||
131 | { | ||
132 | signed char *p = (signed char *)pins->pSample; | ||
133 | signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn); | ||
134 | for (UINT i=0; i<len; i++) | ||
135 | { | ||
136 | p[i] = (signed char)((*psrc) + 0x80); | ||
137 | psrc += samplesize; | ||
138 | } | ||
139 | p[len+1] = p[len] = p[len-1]; | ||
140 | } | ||
141 | } | ||
142 | return TRUE; | ||
143 | } | ||
144 | |||
145 | |||
146 | //////////////////////////////////////////////////////////////////////// | ||
147 | // IMA ADPCM Support | ||
148 | |||
149 | #pragma pack(1) | ||
150 | |||
151 | typedef struct IMAADPCMBLOCK | ||
152 | { | ||
153 | WORD sample; | ||
154 | BYTE index; | ||
155 | BYTE Reserved; | ||
156 | } Q_PACKED DVI_ADPCMBLOCKHEADER; | ||
157 | |||
158 | #pragma pack() | ||
159 | |||
160 | static const int gIMAUnpackTable[90] = | ||
161 | { | ||
162 | 7, 8, 9, 10, 11, 12, 13, 14, | ||
163 | 16, 17, 19, 21, 23, 25, 28, 31, | ||
164 | 34, 37, 41, 45, 50, 55, 60, 66, | ||
165 | 73, 80, 88, 97, 107, 118, 130, 143, | ||
166 | 157, 173, 190, 209, 230, 253, 279, 307, | ||
167 | 337, 371, 408, 449, 494, 544, 598, 658, | ||
168 | 724, 796, 876, 963, 1060, 1166, 1282, 1411, | ||
169 | 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, | ||
170 | 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, | ||
171 | 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, | ||
172 | 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, | ||
173 | 32767, 0 | ||
174 | }; | ||
175 | |||
176 | |||
177 | BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign) | ||
178 | //------------------------------------------------------------------------------------------------ | ||
179 | { | ||
180 | static const int gIMAIndexTab[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; | ||
181 | UINT nPos; | ||
182 | int value; | ||
183 | |||
184 | if ((nLen < 4) || (!pdest) || (!psrc) | ||
185 | || (pkBlkAlign < 5) || (pkBlkAlign > dwBytes)) return FALSE; | ||
186 | nPos = 0; | ||
187 | while ((nPos < nLen) && (dwBytes > 4)) | ||
188 | { | ||
189 | int nIndex; | ||
190 | value = *((short int *)psrc); | ||
191 | nIndex = psrc[2]; | ||
192 | psrc += 4; | ||
193 | dwBytes -= 4; | ||
194 | pdest[nPos++] = (short int)value; | ||
195 | for (UINT i=0; ((i<(pkBlkAlign-4)*2) && (nPos < nLen) && (dwBytes)); i++) | ||
196 | { | ||
197 | BYTE delta; | ||
198 | if (i & 1) | ||
199 | { | ||
200 | delta = (BYTE)(((*(psrc++)) >> 4) & 0x0F); | ||
201 | dwBytes--; | ||
202 | } else | ||
203 | { | ||
204 | delta = (BYTE)((*psrc) & 0x0F); | ||
205 | } | ||
206 | int v = gIMAUnpackTable[nIndex] >> 3; | ||
207 | if (delta & 1) v += gIMAUnpackTable[nIndex] >> 2; | ||
208 | if (delta & 2) v += gIMAUnpackTable[nIndex] >> 1; | ||
209 | if (delta & 4) v += gIMAUnpackTable[nIndex]; | ||
210 | if (delta & 8) value -= v; else value += v; | ||
211 | nIndex += gIMAIndexTab[delta & 7]; | ||
212 | if (nIndex < 0) nIndex = 0; else | ||
213 | if (nIndex > 88) nIndex = 88; | ||
214 | if (value > 32767) value = 32767; else | ||
215 | if (value < -32768) value = -32768; | ||
216 | pdest[nPos++] = (short int)value; | ||
217 | } | ||
218 | } | ||
219 | return TRUE; | ||
220 | } | ||
221 | |||
222 | |||
223 | |||