2 * This source code is public domain.
4 * Authors: Olivier Lapicque <olivierl@jps.net>
14 #ifndef WAVE_FORMAT_EXTENSIBLE
15 #define WAVE_FORMAT_EXTENSIBLE 0xFFFE
18 /////////////////////////////////////////////////////////////
21 BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength)
22 //---------------------------------------------------------------
25 WAVEFILEHEADER *phdr = (WAVEFILEHEADER *)lpStream;
26 WAVEFORMATHEADER *pfmt = (WAVEFORMATHEADER *)(lpStream + sizeof(WAVEFILEHEADER));
27 if ((!lpStream) || (dwMemLength < (DWORD)sizeof(WAVEFILEHEADER))) return FALSE;
28 if ((phdr->id_RIFF != IFFID_RIFF) || (phdr->id_WAVE != IFFID_WAVE)
29 || (pfmt->id_fmt != IFFID_fmt)) return FALSE;
30 dwMemPos = sizeof(WAVEFILEHEADER) + 8 + pfmt->hdrlen;
31 if ((dwMemPos + 8 >= dwMemLength)
32 || ((pfmt->format != WAVE_FORMAT_PCM) && (pfmt->format != WAVE_FORMAT_EXTENSIBLE))
33 || (pfmt->channels > 4)
36 || (pfmt->bitspersample & 7)
37 || (pfmt->bitspersample < 8)
38 || (pfmt->bitspersample > 32)) return FALSE;
39 WAVEDATAHEADER *pdata;
42 pdata = (WAVEDATAHEADER *)(lpStream + dwMemPos);
43 if (pdata->id_data == IFFID_data) break;
44 dwMemPos += pdata->length + 8;
45 if (dwMemPos + 8 >= dwMemLength) return FALSE;
47 m_nType = MOD_TYPE_WAV;
52 m_nDefaultTempo = 125;
53 m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
56 PatternSize[0] = PatternSize[1] = 64;
57 if ((Patterns[0] = AllocatePattern(64, 4)) == NULL) return TRUE;
58 if ((Patterns[1] = AllocatePattern(64, 4)) == NULL) return TRUE;
59 UINT samplesize = (pfmt->channels * pfmt->bitspersample) >> 3;
60 UINT len = pdata->length, bytelen;
61 if (dwMemPos + len > dwMemLength - 8) len = dwMemLength - dwMemPos - 8;
64 if (pfmt->bitspersample >= 16) bytelen *= 2;
65 if (len > MAX_SAMPLE_LENGTH) len = MAX_SAMPLE_LENGTH;
66 if (!len) return TRUE;
67 // Setting up module length
68 DWORD dwTime = ((len * 50) / pfmt->freqHz) + 1;
69 DWORD framesperrow = (dwTime + 63) / 63;
70 if (framesperrow < 4) framesperrow = 4;
72 while (framesperrow >= 0x20)
75 Order[norders] = 0xFF;
76 framesperrow = (dwTime + (64 * norders - 1)) / (64 * norders);
77 if (norders >= MAX_ORDERS-1) break;
79 m_nDefaultSpeed = framesperrow;
80 for (UINT iChn=0; iChn<4; iChn++)
82 ChnSettings[iChn].nPan = (iChn & 1) ? 256 : 0;
83 ChnSettings[iChn].nVolume = 64;
84 ChnSettings[iChn].dwFlags = 0;
86 // Setting up speed command
87 MODCOMMAND *pcmd = Patterns[0];
88 pcmd[0].command = CMD_SPEED;
89 pcmd[0].param = (BYTE)m_nDefaultSpeed;
90 pcmd[0].note = 5*12+1;
92 pcmd[1].note = pcmd[0].note;
93 pcmd[1].instr = pcmd[0].instr;
94 m_nSamples = pfmt->channels;
95 // Support for Multichannel Wave
96 for (UINT nChn=0; nChn<m_nSamples; nChn++)
98 MODINSTRUMENT *pins = &Ins[nChn+1];
99 pcmd[nChn].note = pcmd[0].note;
100 pcmd[nChn].instr = (BYTE)(nChn+1);
102 pins->nC4Speed = pfmt->freqHz;
105 pins->nGlobalVol = 64;
106 pins->uFlags = (WORD)((pfmt->bitspersample >= 16) ? CHN_16BIT : 0);
107 pins->uFlags |= CHN_PANNING;
112 case 0: pins->nPan = 0; break;
113 case 1: pins->nPan = 256; break;
114 case 2: pins->nPan = (WORD)((m_nSamples == 3) ? 128 : 64); pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
115 case 3: pins->nPan = 192; pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
116 default: pins->nPan = 128; break;
119 if ((pins->pSample = AllocateSample(bytelen+8)) == NULL) return TRUE;
120 if (pfmt->bitspersample >= 16)
122 int slsize = pfmt->bitspersample >> 3;
123 signed short *p = (signed short *)pins->pSample;
124 signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn*slsize+slsize-2);
125 for (UINT i=0; i<len; i++)
127 p[i] = *((signed short *)psrc);
130 p[len+1] = p[len] = p[len-1];
133 signed char *p = (signed char *)pins->pSample;
134 signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn);
135 for (UINT i=0; i<len; i++)
137 p[i] = (signed char)((*psrc) + 0x80);
140 p[len+1] = p[len] = p[len-1];
147 ////////////////////////////////////////////////////////////////////////
152 typedef struct IMAADPCMBLOCK
157 } DVI_ADPCMBLOCKHEADER;
161 static const int gIMAUnpackTable[90] =
163 7, 8, 9, 10, 11, 12, 13, 14,
164 16, 17, 19, 21, 23, 25, 28, 31,
165 34, 37, 41, 45, 50, 55, 60, 66,
166 73, 80, 88, 97, 107, 118, 130, 143,
167 157, 173, 190, 209, 230, 253, 279, 307,
168 337, 371, 408, 449, 494, 544, 598, 658,
169 724, 796, 876, 963, 1060, 1166, 1282, 1411,
170 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
171 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
172 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
173 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
178 BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign)
179 //------------------------------------------------------------------------------------------------
181 static const int gIMAIndexTab[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
185 if ((nLen < 4) || (!pdest) || (!psrc)
186 || (pkBlkAlign < 5) || (pkBlkAlign > dwBytes)) return FALSE;
188 while ((nPos < nLen) && (dwBytes > 4))
191 value = *((short int *)psrc);
195 pdest[nPos++] = (short int)value;
196 for (UINT i=0; ((i<(pkBlkAlign-4)*2) && (nPos < nLen) && (dwBytes)); i++)
201 delta = (BYTE)(((*(psrc++)) >> 4) & 0x0F);
205 delta = (BYTE)((*psrc) & 0x0F);
207 int v = gIMAUnpackTable[nIndex] >> 3;
208 if (delta & 1) v += gIMAUnpackTable[nIndex] >> 2;
209 if (delta & 2) v += gIMAUnpackTable[nIndex] >> 1;
210 if (delta & 4) v += gIMAUnpackTable[nIndex];
211 if (delta & 8) value -= v; else value += v;
212 nIndex += gIMAIndexTab[delta & 7];
213 if (nIndex < 0) nIndex = 0; else
214 if (nIndex > 88) nIndex = 88;
215 if (value > 32767) value = 32767; else
216 if (value < -32768) value = -32768;
217 pdest[nPos++] = (short int)value;