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