summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/modplug/load_wav.cpp
Unidiff
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.cpp223
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
20BOOL 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
151typedef struct IMAADPCMBLOCK
152{
153 WORD sample;
154 BYTE index;
155 BYTE Reserved;
156} Q_PACKED DVI_ADPCMBLOCKHEADER;
157
158#pragma pack()
159
160static 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
177BOOL 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