~oah-dev/oah/gst-plugins-bad

« back to all changes in this revision

Viewing changes to gst/modplug/libmodplug/load_wav.cpp

  • Committer: Haakon Sporsheim
  • Date: 2009-03-12 13:52:03 UTC
  • Revision ID: haakon.sporsheim@tandberg.com-20090312135203-i5k294hgkushb0mt
Initial import of git repository: git://anongit.freedesktop.org/gstreamer/gst-plugins-bad (tag: RELEASE-0_10_10)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This source code is public domain.
 
3
 *
 
4
 * Authors: Olivier Lapicque <olivierl@jps.net>
 
5
*/
 
6
 
 
7
#ifdef HAVE_CONFIG_H
 
8
#include "config.h"
 
9
#endif
 
10
 
 
11
#include "stdafx.h"
 
12
#include "sndfile.h"
 
13
 
 
14
#ifndef WAVE_FORMAT_EXTENSIBLE
 
15
#define WAVE_FORMAT_EXTENSIBLE  0xFFFE
 
16
#endif
 
17
 
 
18
/////////////////////////////////////////////////////////////
 
19
// WAV file support
 
20
 
 
21
BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength)
 
22
//---------------------------------------------------------------
 
23
{
 
24
        DWORD dwMemPos = 0;
 
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)
 
34
         || (!pfmt->channels)
 
35
         || (!pfmt->freqHz)
 
36
         || (pfmt->bitspersample & 7)
 
37
         || (pfmt->bitspersample < 8)
 
38
         || (pfmt->bitspersample > 32))  return FALSE;
 
39
        WAVEDATAHEADER *pdata;
 
40
        for (;;)
 
41
        {
 
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;
 
46
        }
 
47
        m_nType = MOD_TYPE_WAV;
 
48
        m_nSamples = 0;
 
49
        m_nInstruments = 0;
 
50
        m_nChannels = 4;
 
51
        m_nDefaultSpeed = 8;
 
52
        m_nDefaultTempo = 125;
 
53
        m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
 
54
        Order[0] = 0;
 
55
        Order[1] = 0xFF;
 
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;
 
62
        len /= samplesize;
 
63
        bytelen = len;
 
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;
 
71
        UINT norders = 1;
 
72
        while (framesperrow >= 0x20)
 
73
        {
 
74
                Order[norders++] = 1;
 
75
                Order[norders] = 0xFF;
 
76
                framesperrow = (dwTime + (64 * norders - 1)) / (64 * norders);
 
77
                if (norders >= MAX_ORDERS-1) break;
 
78
        }
 
79
        m_nDefaultSpeed = framesperrow;
 
80
        for (UINT iChn=0; iChn<4; iChn++)
 
81
        {
 
82
                ChnSettings[iChn].nPan = (iChn & 1) ? 256 : 0;
 
83
                ChnSettings[iChn].nVolume = 64;
 
84
                ChnSettings[iChn].dwFlags = 0;
 
85
        }
 
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;
 
91
        pcmd[0].instr = 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++)
 
97
        {
 
98
                MODINSTRUMENT *pins = &Ins[nChn+1];
 
99
                pcmd[nChn].note = pcmd[0].note;
 
100
                pcmd[nChn].instr = (BYTE)(nChn+1);
 
101
                pins->nLength = len;
 
102
                pins->nC4Speed = pfmt->freqHz;
 
103
                pins->nVolume = 256;
 
104
                pins->nPan = 128;
 
105
                pins->nGlobalVol = 64;
 
106
                pins->uFlags = (WORD)((pfmt->bitspersample >= 16) ? CHN_16BIT : 0);
 
107
                pins->uFlags |= CHN_PANNING;
 
108
                if (m_nSamples > 1)
 
109
                {
 
110
                        switch(nChn)
 
111
                        {
 
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;
 
117
                        }
 
118
                }
 
119
                if ((pins->pSample = AllocateSample(bytelen+8)) == NULL) return TRUE;
 
120
                if (pfmt->bitspersample >= 16)
 
121
                {
 
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++)
 
126
                        {
 
127
                                p[i] = *((signed short *)psrc);
 
128
                                psrc += samplesize;
 
129
                        }
 
130
                        p[len+1] = p[len] = p[len-1];
 
131
                } else
 
132
                {
 
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++)
 
136
                        {
 
137
                                p[i] = (signed char)((*psrc) + 0x80);
 
138
                                psrc += samplesize;
 
139
                        }
 
140
                        p[len+1] = p[len] = p[len-1];
 
141
                }
 
142
        }
 
143
        return TRUE;
 
144
}
 
145
 
 
146
 
 
147
////////////////////////////////////////////////////////////////////////
 
148
// IMA ADPCM Support
 
149
 
 
150
#pragma pack(1)
 
151
 
 
152
typedef struct IMAADPCMBLOCK
 
153
{
 
154
        WORD sample;
 
155
        BYTE index;
 
156
        BYTE Reserved;
 
157
} DVI_ADPCMBLOCKHEADER;
 
158
 
 
159
#pragma pack()
 
160
 
 
161
static const int gIMAUnpackTable[90] = 
 
162
{
 
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,
 
174
  32767, 0
 
175
};
 
176
 
 
177
 
 
178
BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign)
 
179
//------------------------------------------------------------------------------------------------
 
180
{
 
181
        static const int gIMAIndexTab[8] =  { -1, -1, -1, -1, 2, 4, 6, 8 };
 
182
        UINT nPos;
 
183
        int value;
 
184
 
 
185
        if ((nLen < 4) || (!pdest) || (!psrc)
 
186
         || (pkBlkAlign < 5) || (pkBlkAlign > dwBytes)) return FALSE;
 
187
        nPos = 0;
 
188
        while ((nPos < nLen) && (dwBytes > 4))
 
189
        {
 
190
                int nIndex;
 
191
                value = *((short int *)psrc);
 
192
                nIndex = psrc[2];
 
193
                psrc += 4;
 
194
                dwBytes -= 4;
 
195
                pdest[nPos++] = (short int)value;
 
196
                for (UINT i=0; ((i<(pkBlkAlign-4)*2) && (nPos < nLen) && (dwBytes)); i++)
 
197
                {
 
198
                        BYTE delta;
 
199
                        if (i & 1)
 
200
                        {
 
201
                                delta = (BYTE)(((*(psrc++)) >> 4) & 0x0F);
 
202
                                dwBytes--;
 
203
                        } else
 
204
                        {
 
205
                                delta = (BYTE)((*psrc) & 0x0F);
 
206
                        }
 
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;
 
218
                }
 
219
        }
 
220
        return TRUE;
 
221
}
 
222
 
 
223
 
 
224