Mercurial > audlegacy-plugins
diff src/modplug/sndfile.cxx @ 2337:107c1fed3d92
Port Schism modplug core.
author | "Tony Vroon <chainsaw@gentoo.org>" |
---|---|
date | Thu, 24 Jan 2008 12:05:59 +0000 |
parents | 6907fc39b53f |
children | 585f2fc4134e |
line wrap: on
line diff
--- a/src/modplug/sndfile.cxx Wed Jan 23 19:37:05 2008 +0100 +++ b/src/modplug/sndfile.cxx Thu Jan 24 12:05:59 2008 +0000 @@ -15,6 +15,7 @@ extern BOOL MMCMP_Unpack(LPCBYTE *ppMemFile, LPDWORD pdwMemLength); #endif + // External decompressors extern void AMSUnpack(const char *psrc, UINT inputlen, char *pdest, UINT dmax, char packcharacter); extern WORD MDLReadBits(DWORD &bitbuf, UINT &bitnum, LPBYTE &ibuf, CHAR n); @@ -50,6 +51,7 @@ { m_nType = MOD_TYPE_NONE; m_dwSongFlags = 0; + m_nStereoSeparation = 128; m_nChannels = 0; m_nMixChannels = 0; m_nSamples = 0; @@ -62,6 +64,8 @@ m_nMinPeriod = 0x20; m_nMaxPeriod = 0x7FFF; m_nRepeatCount = 0; + m_rowHighlightMajor = 16; + m_rowHighlightMinor = 4; memset(Chn, 0, sizeof(Chn)); memset(ChnMix, 0, sizeof(ChnMix)); memset(Ins, 0, sizeof(Ins)); @@ -86,8 +90,10 @@ { int i; + // deja vu... m_nType = MOD_TYPE_NONE; m_dwSongFlags = 0; + m_nStereoSeparation = 128; m_nChannels = 0; m_nMixChannels = 0; m_nSamples = 0; @@ -111,7 +117,6 @@ m_nMaxPeriod = 32767; m_nSongPreAmp = 0x30; m_nPatternNames = 0; - m_nMaxOrderPosition = 0; m_lpszPatternNames = NULL; m_lpszSongComments = NULL; memset(Ins, 0, sizeof(Ins)); @@ -123,7 +128,10 @@ memset(m_szNames, 0, sizeof(m_szNames)); memset(m_MixPlugins, 0, sizeof(m_MixPlugins)); ResetMidiCfg(); - for (UINT npt=0; npt<MAX_PATTERNS; npt++) PatternSize[npt] = 64; + for (UINT npt=0; npt<MAX_PATTERNS; npt++) { + PatternSize[npt] = 64; + PatternAllocSize[npt] = 64; + } for (UINT nch=0; nch<MAX_BASECHANNELS; nch++) { ChnSettings[nch].nPan = 128; @@ -137,16 +145,15 @@ BOOL bMMCmp = MMCMP_Unpack(&lpStream, &dwMemLength); #endif if ((!ReadXM(lpStream, dwMemLength)) + && (!Read669(lpStream, dwMemLength)) && (!ReadS3M(lpStream, dwMemLength)) && (!ReadIT(lpStream, dwMemLength)) && (!ReadWav(lpStream, dwMemLength)) -#ifndef MODPLUG_BASIC_SUPPORT && (!ReadSTM(lpStream, dwMemLength)) && (!ReadMed(lpStream, dwMemLength)) && (!ReadMTM(lpStream, dwMemLength)) && (!ReadMDL(lpStream, dwMemLength)) && (!ReadDBM(lpStream, dwMemLength)) - && (!Read669(lpStream, dwMemLength)) && (!ReadFAR(lpStream, dwMemLength)) && (!ReadAMS(lpStream, dwMemLength)) && (!ReadOKT(lpStream, dwMemLength)) @@ -158,7 +165,7 @@ && (!ReadAMF(lpStream, dwMemLength)) && (!ReadPSM(lpStream, dwMemLength)) && (!ReadMT2(lpStream, dwMemLength)) -#endif // MODPLUG_BASIC_SUPPORT + && (!ReadMID(lpStream, dwMemLength)) && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; #ifdef MMCMP_SUPPORT if (bMMCmp) @@ -168,14 +175,6 @@ } #endif } - // Adjust song names - for (i=0; i<MAX_SAMPLES; i++) - { - LPSTR p = m_szNames[i]; - int j = 31; - p[j] = 0; - while ((j >= 0) && (p[j] == ' ')) p[j--] = 0; - } // Adjust channels for (i=0; i<MAX_BASECHANNELS; i++) { @@ -195,19 +194,8 @@ if (pins->pSample) { if (pins->nLoopEnd > pins->nLength) pins->nLoopEnd = pins->nLength; - if (pins->nLoopStart + 3 >= pins->nLoopEnd) - { - pins->nLoopStart = 0; - pins->nLoopEnd = 0; - } if (pins->nSustainEnd > pins->nLength) pins->nSustainEnd = pins->nLength; - if (pins->nSustainStart + 3 >= pins->nSustainEnd) - { - pins->nSustainStart = 0; - pins->nSustainEnd = 0; - } - } else - { + } else { pins->nLength = 0; pins->nLoopStart = 0; pins->nLoopEnd = 0; @@ -221,8 +209,7 @@ // Check invalid instruments while ((m_nInstruments > 0) && (!Headers[m_nInstruments])) m_nInstruments--; // Set default values - if (m_nSongPreAmp < 0x20) m_nSongPreAmp = 0x20; - if (m_nDefaultTempo < 32) m_nDefaultTempo = 125; + if (m_nDefaultTempo < 31) m_nDefaultTempo = 31; if (!m_nDefaultSpeed) m_nDefaultSpeed = 6; m_nMusicSpeed = m_nDefaultSpeed; m_nMusicTempo = m_nDefaultTempo; @@ -251,14 +238,7 @@ } } } - if (m_nType) - { - UINT maxpreamp = 0x10+(m_nChannels*8); - if (maxpreamp > 100) maxpreamp = 100; - if (m_nSongPreAmp > maxpreamp) m_nSongPreAmp = maxpreamp; - return TRUE; - } - return FALSE; + return m_nType ? TRUE : FALSE; } @@ -467,6 +447,7 @@ gdwMixingFreq = nRate; gnBitsPerSample = nBits; InitPlayer(bReset); +//printf("Rate=%u Bits=%u Channels=%u MMX=%u\n",gdwMixingFreq,gnBitsPerSample,gnChannels,bMMX); return TRUE; } @@ -494,7 +475,7 @@ { if (nVol < 1) nVol = 1; if (nVol > 0x200) nVol = 0x200; // x4 maximum - if ((nVol < m_nMasterVolume) && (nVol) && (gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) + if ((gdwSoundSetup & SNDMIX_AGC) && (bAdjustAGC)) { gnAGC = gnAGC * m_nMasterVolume / nVol; if (gnAGC > AGC_UNITY) gnAGC = AGC_UNITY; @@ -697,7 +678,6 @@ m_dwSongFlags &= ~(SONG_PATTERNLOOP|SONG_CPUVERYHIGH|SONG_FADINGSONG|SONG_ENDREACHED|SONG_GLOBALFADE); } - void CSoundFile::ResetChannels() //------------------------------ { @@ -710,6 +690,21 @@ } +void CSoundFile::ResetTimestamps() +//-------------------------------- +{ + int n; + + for (n = 1; n < MAX_SAMPLES; n++) { + Ins[n].played = 0; + } + for (n = 1; n < MAX_INSTRUMENTS; n++) { + if (Headers[n]) + Headers[n]->played = 0; + } +} + + void CSoundFile::LoopPattern(int nPat, int nRow) //---------------------------------------------- { @@ -756,7 +751,7 @@ case MOD_TYPE_S3M: n = MOD_TYPE_S3M; } n |= MOD_TYPE_XM | MOD_TYPE_IT; - if (!m_nInstruments) + if (!(m_dwSongFlags & SONG_INSTRUMENTMODE)) { if (m_nSamples < 32) n |= MOD_TYPE_MOD; n |= MOD_TYPE_S3M; @@ -853,212 +848,6 @@ } #endif // NO_PACKING -#ifndef MODPLUG_NO_FILESAVE - -UINT CSoundFile::WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen) -//----------------------------------------------------------------------------------- -{ - UINT len = 0, bufcount; - signed char buffer[4096]; - signed char *pSample = (signed char *)pins->pSample; - UINT nLen = pins->nLength; - - if ((nMaxLen) && (nLen > nMaxLen)) nLen = nMaxLen; - if ((!pSample) || (f == NULL) || (!nLen)) return 0; - switch(nFlags) - { -#ifndef NO_PACKING - // 3: 4-bit ADPCM data - case RS_ADPCM4: - { - int pos; - len = (nLen + 1) / 2; - fwrite(CompressionTable, 16, 1, f); - bufcount = 0; - pos = 0; - for (UINT j=0; j<len; j++) - { - BYTE b; - // Sample #1 - b = PackSample(pos, (int)pSample[j*2]); - // Sample #2 - b |= PackSample(pos, (int)pSample[j*2+1]) << 4; - buffer[bufcount++] = (signed char)b; - if (bufcount >= sizeof(buffer)) - { - fwrite(buffer, 1, bufcount, f); - bufcount = 0; - } - } - if (bufcount) fwrite(buffer, 1, bufcount, f); - len += 16; - } - break; -#endif // NO_PACKING - - // 16-bit samples - case RS_PCM16U: - case RS_PCM16D: - case RS_PCM16S: - { - short int *p = (short int *)pSample; - int s_old = 0, s_ofs; - len = nLen * 2; - bufcount = 0; - s_ofs = (nFlags == RS_PCM16U) ? 0x8000 : 0; - for (UINT j=0; j<nLen; j++) - { - int s_new = *p; - p++; - if (pins->uFlags & CHN_STEREO) - { - s_new = (s_new + (*p) + 1) >> 1; - p++; - } - if (nFlags == RS_PCM16D) - { - short temp = bswapLE16((short)(s_new - s_old)); - *((short *)(&buffer[bufcount])) = temp; - s_old = s_new; - } else - { - short temp = bswapLE16((short)(s_new + s_ofs)); - *((short *)(&buffer[bufcount])) = temp; - } - bufcount += 2; - if (bufcount >= sizeof(buffer) - 1) - { - fwrite(buffer, 1, bufcount, f); - bufcount = 0; - } - } - if (bufcount) fwrite(buffer, 1, bufcount, f); - } - break; - - - // 8-bit Stereo samples (not interleaved) - case RS_STPCM8S: - case RS_STPCM8U: - case RS_STPCM8D: - { - int s_ofs = (nFlags == RS_STPCM8U) ? 0x80 : 0; - for (UINT iCh=0; iCh<2; iCh++) - { - signed char *p = pSample + iCh; - int s_old = 0; - - bufcount = 0; - for (UINT j=0; j<nLen; j++) - { - int s_new = *p; - p += 2; - if (nFlags == RS_STPCM8D) - { - buffer[bufcount++] = (signed char)(s_new - s_old); - s_old = s_new; - } else - { - buffer[bufcount++] = (signed char)(s_new + s_ofs); - } - if (bufcount >= sizeof(buffer)) - { - fwrite(buffer, 1, bufcount, f); - bufcount = 0; - } - } - if (bufcount) fwrite(buffer, 1, bufcount, f); - } - } - len = nLen * 2; - break; - - // 16-bit Stereo samples (not interleaved) - case RS_STPCM16S: - case RS_STPCM16U: - case RS_STPCM16D: - { - int s_ofs = (nFlags == RS_STPCM16U) ? 0x8000 : 0; - for (UINT iCh=0; iCh<2; iCh++) - { - signed short *p = ((signed short *)pSample) + iCh; - int s_old = 0; - - bufcount = 0; - for (UINT j=0; j<nLen; j++) - { - int s_new = *p; - p += 2; - if (nFlags == RS_STPCM16D) - { - short temp = bswapLE16((short)(s_new - s_old)); - *((short *)(&buffer[bufcount])) = temp; - s_old = s_new; - } else - { - short temp = bswapLE16((short)(s_new - s_ofs)); - *((short *)(&buffer[bufcount])) = temp; - } - bufcount += 2; - if (bufcount >= sizeof(buffer)) - { - fwrite(buffer, 1, bufcount, f); - bufcount = 0; - } - } - if (bufcount) fwrite(buffer, 1, bufcount, f); - } - } - len = nLen*4; - break; - - // Stereo signed interleaved - case RS_STIPCM8S: - case RS_STIPCM16S: - len = nLen * 2; - if (nFlags == RS_STIPCM16S) len *= 2; - fwrite(pSample, 1, len, f); - break; - - // Default: assume 8-bit PCM data - default: - len = nLen; - bufcount = 0; - { - signed char *p = pSample; - int sinc = (pins->uFlags & CHN_16BIT) ? 2 : 1; - int s_old = 0, s_ofs = (nFlags == RS_PCM8U) ? 0x80 : 0; - if (pins->uFlags & CHN_16BIT) p++; - for (UINT j=0; j<len; j++) - { - int s_new = (signed char)(*p); - p += sinc; - if (pins->uFlags & CHN_STEREO) - { - s_new = (s_new + ((int)*p) + 1) >> 1; - p += sinc; - } - if (nFlags == RS_PCM8D) - { - buffer[bufcount++] = (signed char)(s_new - s_old); - s_old = s_new; - } else - { - buffer[bufcount++] = (signed char)(s_new + s_ofs); - } - if (bufcount >= sizeof(buffer)) - { - fwrite(buffer, 1, bufcount, f); - bufcount = 0; - } - } - if (bufcount) fwrite(buffer, 1, bufcount, f); - } - } - return len; -} - -#endif // MODPLUG_NO_FILESAVE // Flags: @@ -1074,11 +863,10 @@ UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength) //------------------------------------------------------------------------------------------------ { - UINT len = 0, mem; + UINT len = 0, mem = pIns->nLength+6; - if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; + if ((!pIns) || (pIns->nLength < 1) || (!lpMemFile)) return 0; if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; - mem = pIns->nLength+6; pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); if (nFlags & RSF_16BIT) { @@ -1152,13 +940,15 @@ { len = pIns->nLength * 2; if (len > dwMemLength) break; - short int *pSample = (short int *)pIns->pSample; - short int *p = (short int *)lpMemFile; + short *pSample = (short *)pIns->pSample; + short *p = (short *)lpMemFile; + unsigned short tmp; int delta16 = 0; for (UINT j=0; j<len; j+=2) { - delta16 += bswapLE16(*p++); - *pSample++ = (short int)delta16; + tmp = *((unsigned short *)p++); + delta16 += bswapLE16(tmp); + *pSample++ = (short) delta16; } } break; @@ -1172,7 +962,7 @@ for (UINT j=0; j<len; j+=2) { *pSample = bswapLE16(*pSample); - ++pSample; + pSample++; } } break; @@ -1196,12 +986,15 @@ // 6: 16-bit unsigned PCM data case RS_PCM16U: - { + { len = pIns->nLength * 2; - if (len > dwMemLength) break; + if (len <= dwMemLength) memcpy(pIns->pSample, lpMemFile, len); short int *pSample = (short int *)pIns->pSample; - short int *pSrc = (short int *)lpMemFile; - for (UINT j=0; j<len; j+=2) *pSample++ = bswapLE16(*(pSrc++)) - 0x8000; + for (UINT j=0; j<len; j+=2) + { + *pSample = bswapLE16(*pSample) - 0x8000; + pSample++; + } } break; @@ -1283,14 +1076,13 @@ case RS_IT2158: case RS_IT21516: len = dwMemLength; - if (len < 4) break; + if (len < 2) break; if ((nFlags == RS_IT2148) || (nFlags == RS_IT2158)) ITUnpack8Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT2158)); else ITUnpack16Bit(pIns->pSample, pIns->nLength, (LPBYTE)lpMemFile, dwMemLength, (nFlags == RS_IT21516)); break; -#ifndef MODPLUG_BASIC_SUPPORT #ifndef MODPLUG_FASTSOUNDLIB // 8-bit interleaved stereo samples case RS_STIPCM8S: @@ -1364,7 +1156,7 @@ for (UINT j=0; j<len; j+=2) // swaparoni! { *pSampleW = bswapLE16(*pSampleW); - ++pSampleW; + *pSampleW++; } } break; @@ -1503,7 +1295,6 @@ #endif // MODPLUG_TRACKER #endif // !MODPLUG_FASTSOUNDLIB -#endif // !MODPLUG_BASIC_SUPPORT // Default: 8-bit signed PCM data default: @@ -1543,11 +1334,11 @@ // Adjust end of sample if (pIns->uFlags & CHN_STEREO) { - pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = 0; - pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = 0; + pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; + pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; } else { - pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = 0; + pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; } if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) { @@ -1595,12 +1386,11 @@ // Adjust end of sample if (pIns->uFlags & CHN_STEREO) { - pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = 0; - pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = 0; - + pSample[len*2+6] = pSample[len*2+4] = pSample[len*2+2] = pSample[len*2] = pSample[len*2-2]; + pSample[len*2+7] = pSample[len*2+5] = pSample[len*2+3] = pSample[len*2+1] = pSample[len*2-1]; } else { - pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = 0; + pSample[len+4] = pSample[len+3] = pSample[len+2] = pSample[len+1] = pSample[len] = pSample[len-1]; } if ((pIns->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) { @@ -1625,8 +1415,6 @@ //----------------------------------------------------------- { //---GCCFIX: Removed assembly. - return (DWORD)(8363*pow(2, (transp*128+ftune)/(1536))); - #ifdef MSC_VER const float _fbase = 8363; const float _factor = 1.0f/(12.0f*128.0f); @@ -1656,6 +1444,8 @@ if (derr <= 5) freq -= derr; if (derr >= 995) freq += 1000-derr; return freq; +#else + return (DWORD) (8363.0 * pow(2, (transp * 128.0 + ftune) / 1536.0)); #endif } @@ -1665,8 +1455,6 @@ //---------------------------------------------- { //---GCCFIX: Removed assembly. - return int(1536*(log(freq/8363)/log(2))); - #ifdef MSC_VER const float _f1_8363 = 1.0f / 8363.0f; const float _factor = 128 * 12; @@ -1682,6 +1470,8 @@ fistp result } return result; +#else + return (int) (1536.0 * (log(freq / 8363.0) / log(2))); #endif } @@ -1778,6 +1568,32 @@ return FALSE; } +UINT CSoundFile::GetHighestUsedChannel() +//------------------------------ +{ + UINT highchan = 0; + + for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++) + { + MODCOMMAND *p = Patterns[ipat]; + if (p) + { + UINT jmax = PatternSize[ipat] * m_nChannels; + for (UINT j=0; j<jmax; j++, p++) + { + if ((p->note) && (p->note <= 120)) + { + if ((j % m_nChannels) > highchan) + highchan = j % m_nChannels; + } + } + } + } + + return highchan; +} + + #ifndef MODPLUG_FASTSOUNDLIB @@ -1787,7 +1603,7 @@ UINT nExt = 0; if (!pbIns) return 0; - if (m_nInstruments) + if (m_dwSongFlags & SONG_INSTRUMENTMODE) { memset(pbIns, 0, MAX_SAMPLES * sizeof(BOOL)); for (UINT ipat=0; ipat<MAX_PATTERNS; ipat++)