Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

load_wav.cpp

Go to the documentation of this file.
00001 /*
00002  * This program is  free software; you can redistribute it  and modify it
00003  * under the terms of the GNU  General Public License as published by the
00004  * Free Software Foundation; either version 2  of the license or (at your
00005  * option) any later version.
00006  *
00007  * Authors: Olivier Lapicque <olivierl@jps.net>
00008 */
00009 
00010 #include "stdafx.h"
00011 #include "sndfile.h"
00012 
00013 #ifndef WAVE_FORMAT_EXTENSIBLE
00014 #define WAVE_FORMAT_EXTENSIBLE  0xFFFE
00015 #endif
00016 
00018 // WAV file support
00019 
00020 BOOL CSoundFile::ReadWav(const BYTE *lpStream, DWORD dwMemLength)
00021 //---------------------------------------------------------------
00022 {
00023         DWORD dwMemPos = 0;
00024         WAVEFILEHEADER *phdr = (WAVEFILEHEADER *)lpStream;
00025         WAVEFORMATHEADER *pfmt = (WAVEFORMATHEADER *)(lpStream + sizeof(WAVEFILEHEADER));
00026         if ((!lpStream) || (dwMemLength < (DWORD)sizeof(WAVEFILEHEADER))) return FALSE;
00027         if ((phdr->id_RIFF != IFFID_RIFF) || (phdr->id_WAVE != IFFID_WAVE)
00028          || (pfmt->id_fmt != IFFID_fmt)) return FALSE;
00029         dwMemPos = sizeof(WAVEFILEHEADER) + 8 + pfmt->hdrlen;
00030         if ((dwMemPos + 8 >= dwMemLength)
00031          || ((pfmt->format != WAVE_FORMAT_PCM) && (pfmt->format != WAVE_FORMAT_EXTENSIBLE))
00032          || (pfmt->channels > 4)
00033          || (!pfmt->channels)
00034          || (!pfmt->freqHz)
00035          || (pfmt->bitspersample & 7)
00036          || (pfmt->bitspersample < 8)
00037          || (pfmt->bitspersample > 32))  return FALSE;
00038         WAVEDATAHEADER *pdata;
00039         for (;;)
00040         {
00041                 pdata = (WAVEDATAHEADER *)(lpStream + dwMemPos);
00042                 if (pdata->id_data == IFFID_data) break;
00043                 dwMemPos += pdata->length + 8;
00044                 if (dwMemPos + 8 >= dwMemLength) return FALSE;
00045         }
00046         m_nType = MOD_TYPE_WAV;
00047         m_nSamples = 0;
00048         m_nInstruments = 0;
00049         m_nChannels = 4;
00050         m_nDefaultSpeed = 8;
00051         m_nDefaultTempo = 125;
00052         m_dwSongFlags |= SONG_LINEARSLIDES; // For no resampling
00053         Order[0] = 0;
00054         Order[1] = 0xFF;
00055         PatternSize[0] = PatternSize[1] = 64;
00056         if ((Patterns[0] = AllocatePattern(64, 4)) == NULL) return TRUE;
00057         if ((Patterns[1] = AllocatePattern(64, 4)) == NULL) return TRUE;
00058         UINT samplesize = (pfmt->channels * pfmt->bitspersample) >> 3;
00059         UINT len = pdata->length, bytelen;
00060         if (dwMemPos + len > dwMemLength - 8) len = dwMemLength - dwMemPos - 8;
00061         len /= samplesize;
00062         bytelen = len;
00063         if (pfmt->bitspersample >= 16) bytelen *= 2;
00064         if (len > MAX_SAMPLE_LENGTH) len = MAX_SAMPLE_LENGTH;
00065         if (!len) return TRUE;
00066         // Setting up module length
00067         DWORD dwTime = ((len * 50) / pfmt->freqHz) + 1;
00068         DWORD framesperrow = (dwTime + 63) / 63;
00069         if (framesperrow < 4) framesperrow = 4;
00070         UINT norders = 1;
00071         while (framesperrow >= 0x20)
00072         {
00073                 Order[norders++] = 1;
00074                 Order[norders] = 0xFF;
00075                 framesperrow = (dwTime + (64 * norders - 1)) / (64 * norders);
00076                 if (norders >= MAX_ORDERS-1) break;
00077         }
00078         m_nDefaultSpeed = framesperrow;
00079         for (UINT iChn=0; iChn<4; iChn++)
00080         {
00081                 ChnSettings[iChn].nPan = (iChn & 1) ? 256 : 0;
00082                 ChnSettings[iChn].nVolume = 64;
00083                 ChnSettings[iChn].dwFlags = 0;
00084         }
00085         // Setting up speed command
00086         MODCOMMAND *pcmd = Patterns[0];
00087         pcmd[0].command = CMD_SPEED;
00088         pcmd[0].param = (BYTE)m_nDefaultSpeed;
00089         pcmd[0].note = 5*12+1;
00090         pcmd[0].instr = 1;
00091         pcmd[1].note = pcmd[0].note;
00092         pcmd[1].instr = pcmd[0].instr;
00093         m_nSamples = pfmt->channels;
00094         // Support for Multichannel Wave
00095         for (UINT nChn=0; nChn<m_nSamples; nChn++)
00096         {
00097                 MODINSTRUMENT *pins = &Ins[nChn+1];
00098                 pcmd[nChn].note = pcmd[0].note;
00099                 pcmd[nChn].instr = (BYTE)(nChn+1);
00100                 pins->nLength = len;
00101                 pins->nC4Speed = pfmt->freqHz;
00102                 pins->nVolume = 256;
00103                 pins->nPan = 128;
00104                 pins->nGlobalVol = 64;
00105                 pins->uFlags = (WORD)((pfmt->bitspersample >= 16) ? CHN_16BIT : 0);
00106                 pins->uFlags |= CHN_PANNING;
00107                 if (m_nSamples > 1)
00108                 {
00109                         switch(nChn)
00110                         {
00111                         case 0: pins->nPan = 0; break;
00112                         case 1: pins->nPan = 256; break;
00113                         case 2: pins->nPan = (WORD)((m_nSamples == 3) ? 128 : 64); pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
00114                         case 3: pins->nPan = 192; pcmd[nChn].command = CMD_S3MCMDEX; pcmd[nChn].param = 0x91; break;
00115                         default: pins->nPan = 128; break;
00116                         }
00117                 }
00118                 if ((pins->pSample = AllocateSample(bytelen+8)) == NULL) return TRUE;
00119                 if (pfmt->bitspersample >= 16)
00120                 {
00121                         int slsize = pfmt->bitspersample >> 3;
00122                         signed short *p = (signed short *)pins->pSample;
00123                         signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn*slsize+slsize-2);
00124                         for (UINT i=0; i<len; i++)
00125                         {
00126                                 p[i] = *((signed short *)psrc);
00127                                 psrc += samplesize;
00128                         }
00129                         p[len+1] = p[len] = p[len-1];
00130                 } else
00131                 {
00132                         signed char *p = (signed char *)pins->pSample;
00133                         signed char *psrc = (signed char *)(lpStream+dwMemPos+8+nChn);
00134                         for (UINT i=0; i<len; i++)
00135                         {
00136                                 p[i] = (signed char)((*psrc) + 0x80);
00137                                 psrc += samplesize;
00138                         }
00139                         p[len+1] = p[len] = p[len-1];
00140                 }
00141         }
00142         return TRUE;
00143 }
00144 
00145 
00147 // IMA ADPCM Support
00148 
00149 #pragma pack(1)
00150 
00151 typedef struct IMAADPCMBLOCK
00152 {
00153         WORD sample;
00154         BYTE index;
00155         BYTE Reserved;
00156 } Q_PACKED DVI_ADPCMBLOCKHEADER;
00157 
00158 #pragma pack()
00159 
00160 static const int gIMAUnpackTable[90] = 
00161 {
00162   7,     8,     9,    10,    11,    12,    13,    14,
00163   16,    17,    19,    21,    23,    25,    28,    31,
00164   34,    37,    41,    45,    50,    55,    60,    66,
00165   73,    80,    88,    97,   107,   118,   130,   143,
00166   157,   173,   190,   209,   230,   253,   279,   307,
00167   337,   371,   408,   449,   494,   544,   598,   658,
00168   724,   796,   876,   963,  1060,  1166,  1282,  1411,
00169   1552,  1707,  1878,  2066,  2272,  2499,  2749,  3024,
00170   3327,  3660,  4026,  4428,  4871,  5358,  5894,  6484,
00171   7132,  7845,  8630,  9493, 10442, 11487, 12635, 13899,
00172   15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
00173   32767, 0
00174 };
00175 
00176 
00177 BOOL IMAADPCMUnpack16(signed short *pdest, UINT nLen, LPBYTE psrc, DWORD dwBytes, UINT pkBlkAlign)
00178 //------------------------------------------------------------------------------------------------
00179 {
00180         static const int gIMAIndexTab[8] =  { -1, -1, -1, -1, 2, 4, 6, 8 };
00181         UINT nPos;
00182         int value;
00183 
00184         if ((nLen < 4) || (!pdest) || (!psrc)
00185          || (pkBlkAlign < 5) || (pkBlkAlign > dwBytes)) return FALSE;
00186         nPos = 0;
00187         while ((nPos < nLen) && (dwBytes > 4))
00188         {
00189                 int nIndex;
00190                 value = *((short int *)psrc);
00191                 nIndex = psrc[2];
00192                 psrc += 4;
00193                 dwBytes -= 4;
00194                 pdest[nPos++] = (short int)value;
00195                 for (UINT i=0; ((i<(pkBlkAlign-4)*2) && (nPos < nLen) && (dwBytes)); i++)
00196                 {
00197                         BYTE delta;
00198                         if (i & 1)
00199                         {
00200                                 delta = (BYTE)(((*(psrc++)) >> 4) & 0x0F);
00201                                 dwBytes--;
00202                         } else
00203                         {
00204                                 delta = (BYTE)((*psrc) & 0x0F);
00205                         }
00206                         int v = gIMAUnpackTable[nIndex] >> 3;
00207                         if (delta & 1) v += gIMAUnpackTable[nIndex] >> 2;
00208                         if (delta & 2) v += gIMAUnpackTable[nIndex] >> 1;
00209                         if (delta & 4) v += gIMAUnpackTable[nIndex];
00210                         if (delta & 8) value -= v; else value += v;
00211                         nIndex += gIMAIndexTab[delta & 7];
00212                         if (nIndex < 0) nIndex = 0; else
00213                         if (nIndex > 88) nIndex = 88;
00214                         if (value > 32767) value = 32767; else
00215                         if (value < -32768) value = -32768;
00216                         pdest[nPos++] = (short int)value;
00217                 }
00218         }
00219         return TRUE;
00220 }
00221 
00222 
00223 

Generated on Sat Nov 5 16:15:40 2005 for OPIE by  doxygen 1.4.2