|
From: <sag...@us...> - 2013-10-22 13:39:52
|
Revision: 2980
http://sourceforge.net/p/modplug/code/2980
Author: saga-games
Date: 2013-10-22 13:39:42 +0000 (Tue, 22 Oct 2013)
Log Message:
-----------
[Ref] Rewrote DBM loader to use FileReader.
[Imp] DBM Loader: Support for panning envelopes, 32-bit samples, pattern names, multiple songs and various other small improvements.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_dbm.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/soundlib/Load_dbm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_dbm.cpp 2013-10-22 08:56:26 UTC (rev 2979)
+++ trunk/OpenMPT/soundlib/Load_dbm.cpp 2013-10-22 13:39:42 UTC (rev 2980)
@@ -2,109 +2,161 @@
* Load_dbm.cpp
* ------------
* Purpose: DigiBooster Pro module Loader (DBM)
- * Notes : This loader doesn't handle multiple songs.
- * Authors: Olivier Lapicque
- * Adam Goode (endian and char fixes for PPC)
- * OpenMPT Devs
+ * Notes : (currently none)
+ * Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#include "stdafx.h"
#include "Loaders.h"
+#include "ChunkReader.h"
-#define DBM_FILE_MAGIC 0x304d4244
-#define DBM_ID_NAME 0x454d414e
-#define DBM_NAMELEN 0x2c000000
-#define DBM_ID_INFO 0x4f464e49
-#define DBM_INFOLEN 0x0a000000
-#define DBM_ID_SONG 0x474e4f53
-#define DBM_ID_INST 0x54534e49
-#define DBM_ID_VENV 0x564e4556
-#define DBM_ID_PATT 0x54544150
-#define DBM_ID_SMPL 0x4c504d53
-
#ifdef NEEDS_PRAGMA_PACK
#pragma pack(push, 1)
#endif
struct PACKED DBMFileHeader
{
- uint32 dbm_id; // "DBM0" = 0x304d4244
- uint8 trkVerHi; // Tracker version: 02.15
- uint8 trkVerLo;
- uint16 reserved;
- uint32 name_id; // "NAME" = 0x454d414e
- uint32 name_len; // name length: always 44
- char songname[44];
- uint32 info_id; // "INFO" = 0x4f464e49
- uint32 info_len; // 0x0a000000
+ char dbm0[4];
+ uint8 trkVerHi;
+ uint8 trkVerLo;
+ char reserved[2];
+};
+
+
+// RIFF-style Chunk
+struct PACKED DBMChunk
+{
+ // 32-Bit chunk identifiers
+ enum ChunkIdentifiers
+ {
+ idNAME = 0x454D414E,
+ idINFO = 0x4F464E49,
+ idSONG = 0x474E4F53,
+ idINST = 0x54534E49,
+ idVENV = 0x564E4556,
+ idPENV = 0x564E4550,
+ idPATT = 0x54544150,
+ idPNAM = 0x4D414E50,
+ idSMPL = 0x4c504d53,
+ idMPEG = 0x4745504D,
+ };
+
+ typedef ChunkIdentifiers id_type;
+
+ uint32 id;
+ uint32 length;
+
+ size_t GetLength() const
+ {
+ return SwapBytesReturnBE(length);
+ }
+
+ id_type GetID() const
+ {
+ return static_cast<id_type>(SwapBytesReturnLE(id));
+ }
+};
+
+STATIC_ASSERT(sizeof(DBMChunk) == 8);
+
+
+struct PACKED DBMInfoChunk
+{
uint16 instruments;
uint16 samples;
uint16 songs;
uint16 patterns;
uint16 channels;
- uint32 song_id; // "SONG" = 0x474e4f53
- uint32 song_len;
- char songname2[44];
- uint16 orders;
-// uint16 orderlist[0]; // orderlist[orders] in words
+
+ // Convert all multi-byte numeric values to current platform's endianness or vice versa.
+ void ConvertEndianness()
+ {
+ SwapBytesBE(instruments);
+ SwapBytesBE(samples);
+ SwapBytesBE(songs);
+ SwapBytesBE(patterns);
+ SwapBytesBE(channels);
+ }
};
-STATIC_ASSERT(sizeof(DBMFileHeader) == 132);
+STATIC_ASSERT(sizeof(DBMInfoChunk) == 10);
+
+// Instrument header
struct PACKED DBMInstrument
{
+ enum DBMInstrFlags
+ {
+ smpLoop = 0x01,
+ smpPingPongLoop = 0x02,
+ };
+
char name[30];
- uint16 sampleno;
- uint16 volume;
- uint32 finetune;
- uint32 loopstart;
- uint32 looplen;
- uint16 panning;
- uint16 flags;
+ uint16 sample; // Sample reference
+ uint16 volume; // 0...64
+ uint32 sampleRate;
+ uint32 loopStart;
+ uint32 loopLength;
+ int16 panning; // -128...128
+ uint16 flags; // See DBMInstrFlags
+
+ // Convert all multi-byte numeric values to current platform's endianness or vice versa.
+ void ConvertEndianness()
+ {
+ SwapBytesBE(sample);
+ SwapBytesBE(volume);
+ SwapBytesBE(sampleRate);
+ SwapBytesBE(loopStart);
+ SwapBytesBE(loopLength);
+ SwapBytesBE(panning);
+ SwapBytesBE(flags);
+ }
};
STATIC_ASSERT(sizeof(DBMInstrument) == 50);
+
+// Volume or panning envelope
struct PACKED DBMEnvelope
{
+ enum DBMEnvelopeFlags
+ {
+ envEnabled = 0x01,
+ envSustain = 0x02,
+ envLoop = 0x04,
+ };
+
uint16 instrument;
- uint8 flags;
- uint8 numpoints;
+ uint8 flags; // See DBMEnvelopeFlags
+ uint8 numSegments; // Number of envelope points - 1
uint8 sustain1;
- uint8 loopbegin;
- uint8 loopend;
- uint8 sustain2;
- uint16 volenv[2 * 32];
+ uint8 loopBegin;
+ uint8 loopEnd;
+ uint8 sustain2; // Second sustain point
+ uint16 data[2 * 32];
+
+ // Convert all multi-byte numeric values to current platform's endianness or vice versa.
+ void ConvertEndianness()
+ {
+ SwapBytesBE(instrument);
+ for(int i = 0; i < CountOf(data); i++)
+ {
+ SwapBytesBE(data[i]);
+ }
+ }
};
STATIC_ASSERT(sizeof(DBMEnvelope) == 136);
-struct PACKED DBMPattern
-{
- uint16 rows;
- uint32 packedsize;
- uint8 patterndata[2]; // [packedsize]
-};
-STATIC_ASSERT(sizeof(DBMPattern) == 8);
-
-struct PACKED DBMSample
-{
- uint32 flags;
- uint32 samplesize;
- uint8 sampledata[2]; // [samplesize]
-};
-
-STATIC_ASSERT(sizeof(DBMSample) == 10);
-
#ifdef NEEDS_PRAGMA_PACK
#pragma pack(pop)
#endif
-static const ModCommand::COMMAND dbmEffects[23] =
+static const ModCommand::COMMAND dbmEffects[] =
{
CMD_ARPEGGIO, CMD_PORTAMENTOUP, CMD_PORTAMENTODOWN, CMD_TONEPORTAMENTO,
CMD_VIBRATO, CMD_TONEPORTAVOL, CMD_VIBRATOVOL, CMD_TREMOLO,
@@ -115,8 +167,8 @@
};
-void ConvertDBMEffect(uint8 &command, uint8 ¶m)
-//-------------------------------------------------
+static void ConvertDBMEffect(uint8 &command, uint8 ¶m)
+//--------------------------------------------------------
{
if(command < CountOf(dbmEffects))
command = dbmEffects[command];
@@ -197,310 +249,335 @@
}
-bool CSoundFile::ReadDBM(const BYTE *lpStream, const DWORD dwMemLength, ModLoadingFlags loadFlags)
-//------------------------------------------------------------------------------------------------
+// Read a chunk of volume or panning envelopes
+static void ReadDBMEnvelopeChunk(FileReader chunk, enmEnvelopeTypes envType, CSoundFile &sndFile, bool scaleEnv)
+//--------------------------------------------------------------------------------------------------------------
{
- const DBMFileHeader *pfh = (DBMFileHeader *)lpStream;
- DWORD dwMemPos;
- uint16 nOrders, nSamples, nInstruments, nPatterns;
+ uint16 numEnvs = chunk.ReadUint16BE();
+ for(uint16 i = 0; i < numEnvs; i++)
+ {
+ DBMEnvelope dbmEnv;
+ chunk.ReadConvertEndianness(dbmEnv);
- if ((!lpStream) || (dwMemLength <= sizeof(DBMFileHeader)) || (!pfh->channels)
- || (pfh->dbm_id != DBM_FILE_MAGIC) || (!pfh->songs) || (pfh->song_id != DBM_ID_SONG)
- || (pfh->name_id != DBM_ID_NAME) || (pfh->name_len != DBM_NAMELEN)
- || (pfh->info_id != DBM_ID_INFO) || (pfh->info_len != DBM_INFOLEN)) return false;
- dwMemPos = sizeof(DBMFileHeader);
- nOrders = BigEndianW(pfh->orders);
- if (dwMemPos + 2 * nOrders + 8*3 >= dwMemLength)
+ ModInstrument *mptIns;
+ if(dbmEnv.instrument && dbmEnv.instrument < MAX_INSTRUMENTS && (mptIns = sndFile.Instruments[dbmEnv.instrument]) != nullptr)
+ {
+ InstrumentEnvelope &mptEnv = mptIns->GetEnvelope(envType);
+
+ if(dbmEnv.numSegments)
+ {
+ if(dbmEnv.flags & DBMEnvelope::envEnabled) mptEnv.dwFlags.set(ENV_ENABLED);
+ if(dbmEnv.flags & DBMEnvelope::envSustain) mptEnv.dwFlags.set(ENV_SUSTAIN);
+ if(dbmEnv.flags & DBMEnvelope::envLoop) mptEnv.dwFlags.set(ENV_LOOP);
+ }
+
+ mptEnv.nNodes = std::min<uint32>(dbmEnv.numSegments + 1, MAX_ENVPOINTS);
+
+ mptEnv.nLoopStart = dbmEnv.loopBegin;
+ mptEnv.nLoopEnd = dbmEnv.loopEnd;
+ mptEnv.nSustainStart = mptEnv.nSustainEnd = dbmEnv.sustain1;
+
+ for(uint32 i = 0; i < mptEnv.nNodes; i++)
+ {
+ mptEnv.Ticks[i] = dbmEnv.data[i * 2];
+ uint16 val = dbmEnv.data[i * 2 + 1];
+ if(scaleEnv)
+ {
+ // Panning envelopes are -128...128 in DigiBooster Pro 3.x
+ val = (val + 128) / 4;
+ }
+ LimitMax(val, uint16(64));
+ mptEnv.Values[i] = static_cast<uint8>(val);
+ }
+ }
+ }
+}
+
+
+bool CSoundFile::ReadDBM(FileReader &file, ModLoadingFlags loadFlags)
+//-------------------------------------------------------------------
+{
+ DBMFileHeader fileHeader;
+
+ file.Rewind();
+ if(!file.Read(fileHeader)
+ || memcmp(fileHeader.dbm0, "DBM0", 4)
+ || fileHeader.trkVerHi > 3)
+ {
return false;
- else if(loadFlags == onlyVerifyHeader)
+ } else if(loadFlags == onlyVerifyHeader)
+ {
return true;
+ }
+ ChunkReader chunkFile(file);
+ ChunkReader::ChunkList<DBMChunk> chunks = chunkFile.ReadChunks<DBMChunk>(1);
+
+ // Globals
+ FileReader infoChunk = chunks.GetChunk(DBMChunk::idINFO);
+ DBMInfoChunk infoData;
+ if(!infoChunk.ReadConvertEndianness(infoData))
+ {
+ return false;
+ }
+
InitializeGlobals();
InitializeChannels();
-
- nInstruments = BigEndianW(pfh->instruments);
- nSamples = BigEndianW(pfh->samples);
- nPatterns = BigEndianW(pfh->patterns);
m_nType = MOD_TYPE_DBM;
- m_nChannels = CLAMP(BigEndianW(pfh->channels), 1, MAX_BASECHANNELS); // note: MAX_BASECHANNELS is currently 127, but DBM supports up to 128 channels.
- madeWithTracker = mpt::String::Format("Digi Booster %x.%x", pfh->trkVerHi, pfh->trkVerLo);
+ m_nChannels = Clamp(infoData.channels, uint16(1), uint16(MAX_BASECHANNELS)); // note: MAX_BASECHANNELS is currently 127, but DBM supports up to 128 channels.
+ m_nInstruments = std::min<INSTRUMENTINDEX>(infoData.instruments + 1, MAX_INSTRUMENTS - 1);
+ m_nSamples = std::min<SAMPLEINDEX>(infoData.samples, MAX_SAMPLES - 1);
+ madeWithTracker = mpt::String::Format("DigiBooster Pro %x.%x", fileHeader.trkVerHi, fileHeader.trkVerLo);
- if(pfh->songname[0])
+ // Name chunk
+ FileReader nameChunk = chunks.GetChunk(DBMChunk::idNAME);
+ nameChunk.ReadString<mpt::String::maybeNullTerminated>(songName, nameChunk.GetLength());
+
+ // Song chunks
+ std::vector<FileReader> songChunks = chunks.GetAllChunks(DBMChunk::idSONG);
+ Order.clear();
+ for(size_t i = 0; i < songChunks.size(); i++)
{
- mpt::String::Read<mpt::String::maybeNullTerminated>(songName, pfh->songname);
- } else
- {
- mpt::String::Read<mpt::String::maybeNullTerminated>(songName, pfh->songname2);
+ FileReader &songChunk = songChunks[i];
+ char name[44];
+ songChunk.ReadString<mpt::String::maybeNullTerminated>(name, 44);
+ if(songName.empty())
+ {
+ songName = name;
+ }
+#ifdef DBM_USE_REAL_SUBSONGS
+ if(i > 0) Order.AddSequence(false);
+ Order.SetSequence(i);
+ Order.m_sName = name;
+#endif // DBM_USE_REAL_SUBSONGS
+
+ const uint16 numOrders = songChunk.ReadUint16BE();
+ const ORDERINDEX startIndex = Order.GetLength();
+ Order.resize(startIndex + numOrders + 1, Order.GetInvalidPatIndex());
+
+ for(uint16 ord = 0; ord < numOrders; ord++)
+ {
+ Order[startIndex + ord] = static_cast<PATTERNINDEX>(songChunk.ReadUint16BE());
+ }
}
+#ifdef DBM_USE_REAL_SUBSONGS
+ Order.SetSequence(0);
+#endif // DBM_USE_REAL_SUBSONGS
- Order.resize(nOrders, Order.GetInvalidPatIndex());
- for (UINT iOrd=0; iOrd < nOrders; iOrd++)
+ // Read instruments
+ FileReader instChunk = chunks.GetChunk(DBMChunk::idINST);
+ if(instChunk.IsValid())
{
- if (iOrd >= MAX_ORDERS) break;
- Order[iOrd] = (PATTERNINDEX)BigEndianW(*((WORD *)(lpStream + dwMemPos + iOrd * 2)));
+ for(INSTRUMENTINDEX i = 1; i < GetNumInstruments(); i++)
+ {
+ DBMInstrument instrHeader;
+ instChunk.ReadConvertEndianness(instrHeader);
+
+ ModInstrument *mptIns = AllocateInstrument(i, instrHeader.sample);
+ if(mptIns == nullptr || instrHeader.sample >= MAX_SAMPLES)
+ {
+ continue;
+ }
+ ModSample &mptSmp = Samples[instrHeader.sample];
+
+ mpt::String::Read<mpt::String::maybeNullTerminated>(mptIns->name, instrHeader.name);
+ mpt::String::Read<mpt::String::maybeNullTerminated>(m_szNames[instrHeader.sample], instrHeader.name);
+
+ mptIns->nFadeOut = 1024; // ???
+ mptIns->nPan = static_cast<uint16>(instrHeader.panning + 128);
+ LimitMax(mptIns->nPan, uint32(256));
+ mptIns->dwFlags.set(INS_SETPANNING);
+
+ // Sample Info
+ mptSmp.Initialize();
+ mptSmp.nVolume = std::min(instrHeader.volume, uint16(64)) * 4u;
+ mptSmp.nC5Speed = instrHeader.sampleRate;
+
+ if(instrHeader.loopLength && (instrHeader.flags & (DBMInstrument::smpLoop | DBMInstrument::smpPingPongLoop)))
+ {
+ mptSmp.nLoopStart = instrHeader.loopStart;
+ mptSmp.nLoopEnd = mptSmp.nLoopStart + instrHeader.loopLength;
+ mptSmp.uFlags.set(CHN_LOOP);
+ if(instrHeader.flags & DBMInstrument::smpPingPongLoop) mptSmp.uFlags.set(CHN_PINGPONGLOOP);
+ }
+ }
}
- dwMemPos += 2 * nOrders;
- while (dwMemPos + 10 < dwMemLength)
+
+ // Read envelopes
+ ReadDBMEnvelopeChunk(chunks.GetChunk(DBMChunk::idVENV), ENV_VOLUME, *this, false);
+ ReadDBMEnvelopeChunk(chunks.GetChunk(DBMChunk::idPENV), ENV_PANNING, *this, fileHeader.trkVerHi > 2);
+
+ // Patterns
+ FileReader patternChunk = chunks.GetChunk(DBMChunk::idPATT);
+ if(patternChunk.IsValid() && (loadFlags & loadPatternData))
{
- uint32 chunk_id = LittleEndian(((uint32 *)(lpStream + dwMemPos))[0]);
- uint32 chunk_size = BigEndian(((uint32 *)(lpStream + dwMemPos))[1]);
- uint32 chunk_pos;
+ FileReader patternNameChunk = chunks.GetChunk(DBMChunk::idPNAM);
+ patternNameChunk.Skip(1); // Encoding, should be UTF-8 or ASCII
- dwMemPos += 8;
- chunk_pos = dwMemPos;
- if ((dwMemPos + chunk_size > dwMemLength) || (chunk_size > dwMemLength)) break;
- dwMemPos += chunk_size;
- // Instruments
- if (chunk_id == DBM_ID_INST)
+ for(PATTERNINDEX pat = 0; pat < infoData.patterns; pat++)
{
- if (nInstruments >= MAX_INSTRUMENTS) nInstruments = MAX_INSTRUMENTS-1;
- for(INSTRUMENTINDEX iIns = 0; iIns < nInstruments; iIns++)
+ uint16 numRows = patternChunk.ReadUint16BE();
+ uint32 packedSize = patternChunk.ReadUint32BE();
+ FileReader chunk = patternChunk.GetChunk(packedSize);
+
+ if(Patterns.Insert(pat, numRows))
{
- ModSample *psmp;
- ModInstrument *pIns;
- DBMInstrument *pih;
- uint16 nsmp;
+ continue;
+ }
- if (chunk_pos + sizeof(DBMInstrument) > dwMemPos) break;
+ std::string patName;
+ patternNameChunk.ReadString<mpt::String::maybeNullTerminated>(patName, patternNameChunk.ReadUint8());
+ Patterns[pat].SetName(patName);
- pih = (DBMInstrument *)(lpStream + chunk_pos);
- nsmp = BigEndianW(pih->sampleno);
- psmp = ((nsmp) && (nsmp < MAX_SAMPLES)) ? &Samples[nsmp] : nullptr;
+ PatternRow patRow = Patterns[pat].GetRow(0);
+ ROWINDEX row = 0;
+ while(chunk.AreBytesLeft() && row < numRows)
+ {
+ const uint8 ch = chunk.ReadUint8();
- pIns = AllocateInstrument(iIns + 1, nsmp);
- if(pIns == nullptr)
+ if(!ch)
{
- break;
+ row++;
+ patRow = Patterns[pat].GetRow(row);
+ continue;
}
- mpt::String::Read<mpt::String::maybeNullTerminated>(pIns->name, pih->name);
- if (psmp)
- {
- mpt::String::Read<mpt::String::maybeNullTerminated>(m_szNames[nsmp], pih->name);
- }
+ ModCommand dummy;
+ ModCommand &m = ch <= GetNumChannels() ? patRow[ch - 1] : dummy;
- pIns->nFadeOut = 1024; // ???
- pIns->nPan = BigEndianW(pih->panning);
- if ((pIns->nPan) && (pIns->nPan < 256))
- pIns->dwFlags = INS_SETPANNING;
- else
- pIns->nPan = 128;
+ const uint8 b = chunk.ReadUint8();
- // Sample Info
- if(psmp)
+ if(b & 0x01)
{
- uint16 sflags = BigEndianW(pih->flags);
- psmp->nVolume = BigEndianW(pih->volume) * 4;
- if(/*!psmp->nVolume ||*/ psmp->nVolume > 256) psmp->nVolume = 256; // XXX First condition looks like a typical "modplug-ism"
- psmp->nGlobalVol = 64;
- psmp->nC5Speed = BigEndian(pih->finetune);
+ uint8 note = chunk.ReadUint8();
- if(pih->looplen && (sflags & 3))
+ if(note == 0x1F)
+ note = NOTE_KEYOFF;
+ else if(note > 0 && note < 0xFE)
{
- psmp->nLoopStart = BigEndian(pih->loopstart);
- psmp->nLoopEnd = psmp->nLoopStart + BigEndian(pih->looplen);
- psmp->uFlags |= CHN_LOOP;
- psmp->uFlags &= ~CHN_PINGPONGLOOP;
- if(sflags & 2) psmp->uFlags |= CHN_PINGPONGLOOP;
+ note = ((note >> 4) * 12) + (note & 0x0F) + 13;
}
+ m.note = note;
}
- chunk_pos += sizeof(DBMInstrument);
- m_nInstruments = iIns + 1;
- }
- } else
- // Volume Envelopes
- if (chunk_id == DBM_ID_VENV)
- {
- UINT nEnvelopes = lpStream[chunk_pos+1];
-
- chunk_pos += 2;
- for (UINT iEnv=0; iEnv<nEnvelopes; iEnv++)
- {
- DBMEnvelope *peh;
- UINT nins;
-
- if (chunk_pos + sizeof(DBMEnvelope) > dwMemPos) break;
- peh = (DBMEnvelope *)(lpStream+chunk_pos);
- nins = BigEndianW(peh->instrument);
- if ((nins) && (nins < MAX_INSTRUMENTS) && (Instruments[nins]) && (peh->numpoints))
+ if(b & 0x02)
{
- ModInstrument *pIns = Instruments[nins];
+ m.instr = chunk.ReadUint8();
+ }
+ if(b & 0x3C)
+ {
+ uint8 cmd1 = CMD_NONE, cmd2 = CMD_NONE;
+ uint8 param1 = 0, param2 = 0;
+ if(b & 0x04) cmd2 = chunk.ReadUint8();
+ if(b & 0x08) param2 = chunk.ReadUint8();
+ if(b & 0x10) cmd1 = chunk.ReadUint8();
+ if(b & 0x20) param1 = chunk.ReadUint8();
+ ConvertDBMEffect(cmd1, param1);
+ ConvertDBMEffect(cmd2, param2);
- pIns->VolEnv.dwFlags.set(ENV_ENABLED, (peh->flags & 1) != 0);
- pIns->VolEnv.dwFlags.set(ENV_SUSTAIN, (peh->flags & 2) != 0);
- pIns->VolEnv.dwFlags.set(ENV_LOOP, (peh->flags & 4) != 0);
- pIns->VolEnv.nNodes = peh->numpoints + 1;
- if (pIns->VolEnv.nNodes > MAX_ENVPOINTS) pIns->VolEnv.nNodes = MAX_ENVPOINTS;
- pIns->VolEnv.nLoopStart = peh->loopbegin;
- pIns->VolEnv.nLoopEnd = peh->loopend;
- pIns->VolEnv.nSustainStart = pIns->VolEnv.nSustainEnd = peh->sustain1;
- for(uint32 i=0; i<pIns->VolEnv.nNodes; i++)
+ // this is the same conversion algorithm as in the ULT loader. maybe this should be merged at some point...
+ if (cmd2 == CMD_VOLUME || (cmd2 == CMD_NONE && cmd1 != CMD_VOLUME))
{
- pIns->VolEnv.Ticks[i] = BigEndianW(peh->volenv[i * 2]);
- pIns->VolEnv.Values[i] = (BYTE)BigEndianW(peh->volenv[i * 2 + 1]);
+ std::swap(cmd1, cmd2);
+ std::swap(param1, param2);
}
- }
- chunk_pos += sizeof(DBMEnvelope);
- }
- } else
- // Packed Pattern Data
- if (chunk_id == DBM_ID_PATT && (loadFlags & loadPatternData))
- {
- if (nPatterns > MAX_PATTERNS) nPatterns = MAX_PATTERNS;
- for(PATTERNINDEX iPat = 0; iPat < nPatterns; iPat++)
- {
- DBMPattern *pph;
- DWORD pksize;
- UINT nRows;
- if (chunk_pos + sizeof(DBMPattern) > dwMemPos) break;
- pph = (DBMPattern *)(lpStream+chunk_pos);
- pksize = BigEndian(pph->packedsize);
- if ((chunk_pos + pksize + 6 > dwMemPos) || (pksize > dwMemPos)) break;
- nRows = BigEndianW(pph->rows);
- if ((nRows >= 4) && (nRows <= 256))
- {
- Patterns.Insert(iPat, nRows);
- ModCommand *m = Patterns[iPat];
- if (m)
+ int n;
+ for(n = 0; n < 4; n++)
{
- LPBYTE pkdata = (LPBYTE)&pph->patterndata;
- UINT row = 0;
- UINT i = 0;
-
- while ((i+3<pksize) && (row < nRows))
+ if(ModCommand::ConvertVolEffect(cmd1, param1, (n >> 1) != 0))
{
- UINT ch = pkdata[i++];
-
- if (ch)
- {
- BYTE b = pkdata[i++];
- ch--;
- if (ch < m_nChannels)
- {
- if (b & 0x01)
- {
- uint8 note = pkdata[i++];
-
- if (note == 0x1F) note = NOTE_KEYOFF; else
- if ((note) && (note < 0xFE))
- {
- note = ((note >> 4) * 12) + (note & 0x0F) + 13;
- }
- m[ch].note = note;
- }
- if (b & 0x02) m[ch].instr = pkdata[i++];
- if (b & 0x3C)
- {
- uint8 cmd1 = CMD_NONE, cmd2 = CMD_NONE;
- uint8 param1 = 0, param2 = 0;
- if (b & 0x04) cmd2 = pkdata[i++];
- if (b & 0x08) param2 = pkdata[i++];
- if (b & 0x10) cmd1 = pkdata[i++];
- if (b & 0x20) param1 = pkdata[i++];
- ConvertDBMEffect(cmd1, param1);
- ConvertDBMEffect(cmd2, param2);
-
- // this is the same conversion algorithm as in the ULT loader. maybe this should be merged at some point...
- if (cmd2 == CMD_VOLUME || (cmd2 == CMD_NONE && cmd1 != CMD_VOLUME))
- {
- std::swap(cmd1, cmd2);
- std::swap(param1, param2);
- }
-
- int n;
- for (n = 0; n < 4; n++)
- {
- if(ModCommand::ConvertVolEffect(cmd1, param1, (n >> 1) != 0))
- {
- n = 5;
- break;
- }
- std::swap(cmd1, cmd2);
- std::swap(param1, param2);
- }
- if (n < 5)
- {
- if (ModCommand::GetEffectWeight((ModCommand::COMMAND)cmd1) > ModCommand::GetEffectWeight((ModCommand::COMMAND)cmd2))
- {
- std::swap(cmd1, cmd2);
- std::swap(param1, param2);
- }
- cmd1 = CMD_NONE;
- }
- if (!cmd1)
- param1 = 0;
- if (!cmd2)
- param2 = 0;
-
- m[ch].volcmd = cmd1;
- m[ch].vol = param1;
- m[ch].command = cmd2;
- m[ch].param = param2;
- m[ch].ExtendedMODtoS3MEffect();
- }
- } else
- {
- if (b & 0x01) i++;
- if (b & 0x02) i++;
- if (b & 0x04) i++;
- if (b & 0x08) i++;
- if (b & 0x10) i++;
- if (b & 0x20) i++;
- }
- } else
- {
- row++;
- m += m_nChannels;
- }
+ n = 5;
+ break;
}
+ std::swap(cmd1, cmd2);
+ std::swap(param1, param2);
}
+ if(n < 5)
+ {
+ if (ModCommand::GetEffectWeight((ModCommand::COMMAND)cmd1) > ModCommand::GetEffectWeight((ModCommand::COMMAND)cmd2))
+ {
+ std::swap(cmd1, cmd2);
+ std::swap(param1, param2);
+ }
+ cmd1 = CMD_NONE;
+ }
+ if(cmd1 == CMD_NONE)
+ param1 = 0;
+ if(cmd2 == CMD_NONE)
+ param2 = 0;
+
+ m.volcmd = cmd1;
+ m.vol = param1;
+ m.command = cmd2;
+ m.param = param2;
+ m.ExtendedMODtoS3MEffect();
}
- chunk_pos += 6 + pksize;
}
- } else
- // Reading Sample Data
- if (chunk_id == DBM_ID_SMPL && (loadFlags & loadSampleData))
+ }
+ }
+
+ // Samples
+ FileReader sampleChunk = chunks.GetChunk(DBMChunk::idSMPL);
+ if(sampleChunk.IsValid() && (loadFlags & loadSampleData))
+ {
+ for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++)
{
- if (nSamples >= MAX_SAMPLES) nSamples = MAX_SAMPLES-1;
- m_nSamples = nSamples;
- for (UINT iSmp=1; iSmp<=nSamples; iSmp++)
+ uint32 sampleFlags = sampleChunk.ReadUint32BE();
+ uint32 sampleLength = sampleChunk.ReadUint32BE();
+
+ ModSample &sample = Samples[smp];
+ sample.nLength = sampleLength;
+
+ if(sampleFlags & 7)
{
- DBMSample *psh;
- DWORD samplesize;
- DWORD sampleflags;
+ SampleIO(
+ (sampleFlags & 4) ? SampleIO::_32bit : ((sampleFlags & 2) ? SampleIO::_16bit : SampleIO::_8bit),
+ SampleIO::mono,
+ SampleIO::bigEndian,
+ SampleIO::signedPCM)
+ .ReadSample(sample, sampleChunk);
+ }
+ }
+ }
- if (chunk_pos + sizeof(DBMSample) >= dwMemPos) break;
- psh = (DBMSample *)(lpStream+chunk_pos);
- chunk_pos += 8;
- samplesize = BigEndian(psh->samplesize);
- sampleflags = BigEndian(psh->flags);
+#if !defined(NO_MP3_SAMPLES) && 0
+ // Compressed samples - this does not quite work yet...
+ FileReader mpegChunk = chunks.GetChunk(DBMChunk::idMPEG);
+ if(mpegChunk.IsValid() && (loadFlags & loadSampleData))
+ {
+ for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++)
+ {
+ Samples[smp].nLength = mpegChunk.ReadUint32BE();
+ }
+ mpegChunk.Skip(2); // 0x00 0x40
- ModSample &sample = Samples[iSmp];
- sample.nLength = samplesize;
- if(sampleflags & 2)
- {
- samplesize *= 2;
- }
- if(chunk_pos + samplesize > dwMemPos || samplesize > dwMemLength)
- {
- break;
- }
+ // Read whole MPEG stream into one sample and then split it up.
+ FileReader chunk = mpegChunk.GetChunk(mpegChunk.BytesLeft());
+ if(ReadMP3Sample(0, chunk))
+ {
+ ModSample &srcSample = Samples[0];
+ const uint8 *smpData = static_cast<uint8 *>(srcSample.pSample);
- if(sampleflags & 3)
+ for(SAMPLEINDEX smp = 1; smp <= GetNumSamples(); smp++)
+ {
+ ModSample &sample = Samples[smp];
+ sample.uFlags.set(srcSample.uFlags);
+ sample.nLength *= 2;
+ LimitMax(sample.nLength, srcSample.nLength);
+ if(sample.nLength)
{
- FileReader chunk(psh->sampledata, samplesize);
- SampleIO(
- (sampleflags & 2) ? SampleIO::_16bit : SampleIO::_8bit,
- SampleIO::mono,
- SampleIO::bigEndian,
- SampleIO::signedPCM)
- .ReadSample(sample, chunk);
+ sample.AllocateSample();
+ memcpy(sample.pSample, smpData, sample.GetSampleSizeInBytes());
+ CSoundFile::AdjustSampleLoop(sample);
+ smpData += sample.GetSampleSizeInBytes();
+ srcSample.nLength -= sample.nLength;
}
- chunk_pos += samplesize;
}
+ srcSample.FreeSample();
}
}
+#endif // NO_MP3_SAMPLES
+
return true;
}
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2013-10-22 08:56:26 UTC (rev 2979)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2013-10-22 13:39:42 UTC (rev 2980)
@@ -703,7 +703,7 @@
&& !ReadMed(lpStream, dwMemLength, loadFlags)
&& !ReadMTM(file, loadFlags)
&& !ReadMDL(lpStream, dwMemLength, loadFlags)
- && !ReadDBM(lpStream, dwMemLength, loadFlags)
+ && !ReadDBM(file, loadFlags)
&& !Read669(file, loadFlags)
&& !ReadFAR(file, loadFlags)
&& !ReadAMS(file, loadFlags)
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2013-10-22 08:56:26 UTC (rev 2979)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2013-10-22 13:39:42 UTC (rev 2980)
@@ -538,7 +538,7 @@
bool ReadOKT(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
bool ReadDMF(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
bool ReadPTM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
- bool ReadDBM(const LPCBYTE lpStream, const DWORD dwMemLength, ModLoadingFlags loadFlags = loadCompleteModule);
+ bool ReadDBM(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
bool ReadAMF_Asylum(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
bool ReadAMF_DSMI(FileReader &file, ModLoadingFlags loadFlags = loadCompleteModule);
bool ReadMT2(const LPCBYTE lpStream, const DWORD dwMemLength, ModLoadingFlags loadFlags = loadCompleteModule);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2013-11-01 16:29:17
|
Revision: 3062
http://sourceforge.net/p/modplug/code/3062
Author: saga-games
Date: 2013-11-01 16:29:11 +0000 (Fri, 01 Nov 2013)
Log Message:
-----------
[Mod] Re-enable reading of ADPCM-compressed samples in MOD loader.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_mod.cpp
trunk/OpenMPT/soundlib/Load_ptm.cpp
Modified: trunk/OpenMPT/soundlib/Load_mod.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mod.cpp 2013-10-29 22:28:54 UTC (rev 3061)
+++ trunk/OpenMPT/soundlib/Load_mod.cpp 2013-11-01 16:29:11 UTC (rev 3062)
@@ -708,7 +708,12 @@
{
for(SAMPLEINDEX smp = 1; smp <= 31; smp++)
{
- MODSampleHeader::GetSampleFormat().ReadSample(Samples[smp], file);
+ SampleIO(
+ SampleIO::_8bit,
+ SampleIO::mono,
+ SampleIO::bigEndian,
+ file.ReadMagic("ADPCM") ? SampleIO::ADPCM : SampleIO::signedPCM)
+ .ReadSample(Samples[smp], file);
}
}
Modified: trunk/OpenMPT/soundlib/Load_ptm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_ptm.cpp 2013-10-29 22:28:54 UTC (rev 3061)
+++ trunk/OpenMPT/soundlib/Load_ptm.cpp 2013-11-01 16:29:11 UTC (rev 3062)
@@ -194,7 +194,7 @@
}
// Reading Patterns
- if(!(loadFlags && loadPatternData))
+ if(!(loadFlags & loadPatternData))
{
return true;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2013-11-10 02:20:32
|
Revision: 3163
http://sourceforge.net/p/modplug/code/3163
Author: manxorist
Date: 2013-11-10 02:20:26 +0000 (Sun, 10 Nov 2013)
Log Message:
-----------
[Ref] Instrument path names are only needed for .itp files and should thus be #ifdef MODPLUG_TRACKER .
Modified Paths:
--------------
trunk/OpenMPT/soundlib/SampleFormats.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp
===================================================================
--- trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-11-10 01:31:49 UTC (rev 3162)
+++ trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-11-10 02:20:26 UTC (rev 3163)
@@ -178,16 +178,16 @@
RemoveInstrumentSamples(nInstr);
}
+#ifdef MODPLUG_TRACKER
// -> CODE#0023
// -> DESC="IT project files (.itp)"
m_szInstrumentPath[nInstr - 1].clear();
-#ifdef MODPLUG_TRACKER
if(GetpModDoc())
{
GetpModDoc()->m_bsInstrumentModified.reset(nInstr - 1);
}
+// -! NEW_FEATURE#0023
#endif // MODPLUG_TRACKER
-// -! NEW_FEATURE#0023
CriticalSection cs;
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2013-11-10 01:31:49 UTC (rev 3162)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2013-11-10 02:20:26 UTC (rev 3163)
@@ -403,10 +403,12 @@
SongMessage songMessage;
std::string madeWithTracker;
+#ifdef MODPLUG_TRACKER
// -> CODE#0023
// -> DESC="IT project files (.itp)"
std::string m_szInstrumentPath[MAX_INSTRUMENTS];
// -! NEW_FEATURE#0023
+#endif // MODPLUG_TRACKER
bool m_bIsRendering;
bool m_bPatternTransitionOccurred;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2013-11-13 22:31:10
|
Revision: 3212
http://sourceforge.net/p/modplug/code/3212
Author: saga-games
Date: 2013-11-13 22:31:02 +0000 (Wed, 13 Nov 2013)
Log Message:
-----------
[Ref] Rewrite 8SVX loader using FileReader.
[New] Add support for 16SVX samples (untested - MilkyTracker code claims they are stored as little-endian, but here they are implemented as big-endian for now)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/SampleFormats.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/soundlib/SampleFormats.cpp
===================================================================
--- trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-11-13 19:41:56 UTC (rev 3211)
+++ trunk/OpenMPT/soundlib/SampleFormats.cpp 2013-11-13 22:31:02 UTC (rev 3212)
@@ -73,7 +73,7 @@
&& !ReadAIFFSample(nSample, file, mayNormalize)
&& !ReadITSSample(nSample, file)
&& !ReadPATSample(nSample, const_cast<BYTE*>(lpMemFile), dwFileLength)
- && !Read8SVXSample(nSample, const_cast<BYTE*>(lpMemFile), dwFileLength)
+ && !ReadIFFSample(nSample, file)
&& !ReadS3ISample(nSample, file)
&& !ReadFLACSample(nSample, file)
&& !ReadMP3Sample(nSample, file))
@@ -1690,121 +1690,148 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
-// 8SVX Samples
+// 8SVX / 16SVX Samples
-#define IFFID_8SVX 0x58565338
-#define IFFID_VHDR 0x52444856
-#define IFFID_BODY 0x59444f42
-#define IFFID_NAME 0x454d414e
-#define IFFID_ANNO 0x4f4e4e41
-
#ifdef NEEDS_PRAGMA_PACK
#pragma pack(push, 1)
#endif
-typedef struct PACKED IFF8SVXFILEHEADER
+// IFF File Header
+struct PACKED IFFHeader
{
- DWORD dwFORM; // "FORM"
- DWORD dwSize;
- DWORD dw8SVX; // "8SVX"
-} IFF8SVXFILEHEADER;
+ char form[4]; // "FORM"
+ uint32 size;
+ char magic[4]; // "8SVX" or "16SV"
-STATIC_ASSERT(sizeof(IFF8SVXFILEHEADER) == 12);
+ // Convert all multi-byte numeric values to current platform's endianness or vice versa.
+ void ConvertEndianness()
+ {
+ SwapBytesBE(size);
+ }
+};
-typedef struct PACKED IFFVHDR
+STATIC_ASSERT(sizeof(IFFHeader) == 12);
+
+
+// General IFF Chunk header
+struct PACKED IFFChunk
{
- DWORD dwVHDR; // "VHDR"
- DWORD dwSize;
- ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */
- repeatHiSamples, /* # samples in the high octave repeat part */
- samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */
- WORD samplesPerSec; /* data sampling rate */
- BYTE ctOctave, /* # octaves of waveforms */
- sCompression; /* data compression technique used */
- DWORD Volume;
-} IFFVHDR;
+ // 32-Bit chunk identifiers
+ enum ChunkIdentifiers
+ {
+ idVHDR = 0x52444856,
+ idBODY = 0x59444F42,
+ idNAME = 0x454D414E,
+ };
-STATIC_ASSERT(sizeof(IFFVHDR) == 28);
+ typedef ChunkIdentifiers id_type;
-typedef struct PACKED IFFBODY
+ uint32 id; // See ChunkIdentifiers
+ uint32 length; // Chunk size without header
+
+ size_t GetLength() const
+ {
+ if(length == 0) // Broken files
+ return SIZE_MAX;
+ return SwapBytesReturnBE(length);
+ }
+
+ id_type GetID() const
+ {
+ return static_cast<id_type>(SwapBytesReturnLE(id));
+ }
+};
+
+STATIC_ASSERT(sizeof(AIFFChunk) == 8);
+
+
+struct PACKED IFFSampleHeader
{
- DWORD dwBody;
- DWORD dwSize;
-} IFFBODY;
+ uint32 oneShotHiSamples; // Samples in the high octave 1-shot part
+ uint32 repeatHiSamples; // Samples in the high octave repeat part
+ uint32 samplesPerHiCycle; // Samples/cycle in high octave, else 0
+ uint16 samplesPerSec; // Data sampling rate
+ uint8 octave; // Octaves of waveforms
+ uint8 compression; // Data compression technique used
+ uint32 volume;
-STATIC_ASSERT(sizeof(IFFBODY) == 8);
+ // Convert all multi-byte numeric values to current platform's endianness or vice versa.
+ void ConvertEndianness()
+ {
+ SwapBytesBE(oneShotHiSamples);
+ SwapBytesBE(repeatHiSamples);
+ SwapBytesBE(samplesPerHiCycle);
+ SwapBytesBE(samplesPerSec);
+ SwapBytesBE(volume);
+ }
+};
+STATIC_ASSERT(sizeof(IFFSampleHeader) == 20);
+
#ifdef NEEDS_PRAGMA_PACK
#pragma pack(pop)
#endif
+bool CSoundFile::ReadIFFSample(SAMPLEINDEX nSample, FileReader &file)
+//--------------------------------------------------------------------
+{
+ file.Rewind();
-bool CSoundFile::Read8SVXSample(SAMPLEINDEX nSample, LPBYTE lpMemFile, DWORD dwFileLength)
-//----------------------------------------------------------------------------------------
-{
- IFF8SVXFILEHEADER *pfh = (IFF8SVXFILEHEADER *)lpMemFile;
- IFFVHDR *pvh = (IFFVHDR *)(lpMemFile + 12);
- ModSample &sample = Samples[nSample];
- DWORD dwMemPos = 12;
+ IFFHeader fileHeader;
+ if(!file.ReadConvertEndianness(fileHeader)
+ || memcmp(fileHeader.form, "FORM", 4 )
+ || (memcmp(fileHeader.magic, "8SVX", 4) && memcmp(fileHeader.magic, "16SV", 4)))
+ {
+ return false;
+ }
+
+ ChunkReader chunkFile(file);
+ ChunkReader::ChunkList<IFFChunk> chunks = chunkFile.ReadChunks<IFFChunk>(2);
+
+ FileReader vhdrChunk = chunks.GetChunk(IFFChunk::idVHDR);
+ FileReader bodyChunk = chunks.GetChunk(IFFChunk::idBODY);
+ IFFSampleHeader sampleHeader;
+ if(!bodyChunk.IsValid()
+ || !vhdrChunk.IsValid()
+ || !vhdrChunk.ReadConvertEndianness(sampleHeader))
+ {
+ return false;
+ }
- if ((!lpMemFile) || (dwFileLength < sizeof(IFFVHDR)+12) || (pfh->dwFORM != IFFID_FORM)
- || (pfh->dw8SVX != IFFID_8SVX) || (BigEndian(pfh->dwSize) >= dwFileLength)
- || (pvh->dwVHDR != IFFID_VHDR) || (BigEndian(pvh->dwSize) >= dwFileLength)) return false;
-
DestroySampleThreadsafe(nSample);
// Default values
+ ModSample &sample = Samples[nSample];
sample.Initialize();
- sample.nLoopStart = BigEndian(pvh->oneShotHiSamples);
- sample.nLoopEnd = sample.nLoopStart + BigEndian(pvh->repeatHiSamples);
- sample.nVolume = (WORD)(BigEndianW((WORD)pvh->Volume) >> 8);
- sample.nC5Speed = BigEndianW(pvh->samplesPerSec);
- if((!sample.nVolume) || (sample.nVolume > 256)) sample.nVolume = 256;
+ sample.nLoopStart = sampleHeader.oneShotHiSamples;
+ sample.nLoopEnd = sample.nLoopStart + sampleHeader.repeatHiSamples;
+ sample.nC5Speed = sampleHeader.samplesPerSec;
+ sample.nVolume = static_cast<uint16>(sampleHeader.volume >> 8);
+ if(!sample.nVolume || sample.nVolume > 256) sample.nVolume = 256;
if(!sample.nC5Speed) sample.nC5Speed = 22050;
sample.Convert(MOD_TYPE_IT, GetType());
- dwMemPos += BigEndian(pvh->dwSize) + 8;
- while (dwMemPos + 8 < dwFileLength)
+ FileReader nameChunk = chunks.GetChunk(IFFChunk::idNAME);
+ if(nameChunk.IsValid())
{
- DWORD dwChunkId = *((LPDWORD)(lpMemFile+dwMemPos));
- DWORD dwChunkLen = BigEndian(*((LPDWORD)(lpMemFile+dwMemPos+4)));
- LPBYTE pChunkData = (LPBYTE)(lpMemFile+dwMemPos+8);
- // Hack for broken files: Trim claimed length if it's too long
- dwChunkLen = MIN(dwChunkLen, dwFileLength - dwMemPos);
- switch(dwChunkId)
- {
- case IFFID_NAME:
- {
- const UINT len = MIN(dwChunkLen, MAX_SAMPLENAME - 1);
- MemsetZero(m_szNames[nSample]);
- memcpy(m_szNames[nSample], pChunkData, len);
- }
- break;
- case IFFID_BODY:
- if (!sample.pSample)
- {
- UINT len = dwChunkLen;
- if (len > dwFileLength - dwMemPos - 8) len = dwFileLength - dwMemPos - 8;
- if (len > 4)
- {
- sample.nLength = len;
- if ((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd <= sample.nLength)) sample.uFlags |= CHN_LOOP;
+ nameChunk.ReadString<mpt::String::maybeNullTerminated>(m_szNames[nSample], nameChunk.GetLength());
+ } else
+ {
+ strcpy(m_szNames[nSample], "");
+ }
- FileReader chunk(pChunkData, len);
- SampleIO(
- SampleIO::_8bit,
- SampleIO::mono,
- SampleIO::bigEndian,
- SampleIO::signedPCM)
- .ReadSample(sample, chunk);
- }
- }
- break;
- }
- dwMemPos += dwChunkLen + 8;
- }
- return (sample.pSample != nullptr);
+ sample.nLength = mpt::saturate_cast<SmpLength>(bodyChunk.GetLength());
+ if((sample.nLoopStart + 4 < sample.nLoopEnd) && (sample.nLoopEnd <= sample.nLength)) sample.uFlags.set(CHN_LOOP);
+
+ SampleIO(
+ memcmp(fileHeader.magic, "8SVX", 4) ? SampleIO::_16bit : SampleIO::_8bit,
+ SampleIO::mono,
+ SampleIO::bigEndian,
+ SampleIO::signedPCM)
+ .ReadSample(sample, bodyChunk);
+
+ return true;
}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2013-11-13 19:41:56 UTC (rev 3211)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2013-11-13 22:31:02 UTC (rev 3212)
@@ -747,7 +747,7 @@
bool ReadXISample(SAMPLEINDEX nSample, FileReader &file);
bool ReadITSSample(SAMPLEINDEX nSample, FileReader &file, bool rewind = true);
bool ReadITISample(SAMPLEINDEX nSample, FileReader &file);
- bool Read8SVXSample(SAMPLEINDEX nInstr, const LPBYTE lpMemFile, DWORD dwFileLength);
+ bool ReadIFFSample(SAMPLEINDEX nInstr, FileReader &file);
bool ReadFLACSample(SAMPLEINDEX sample, FileReader &file);
bool ReadMP3Sample(SAMPLEINDEX sample, FileReader &file);
#ifndef MODPLUG_NO_FILESAVE
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2013-11-18 00:53:47
|
Revision: 3260
http://sourceforge.net/p/modplug/code/3260
Author: saga-games
Date: 2013-11-18 00:53:40 +0000 (Mon, 18 Nov 2013)
Log Message:
-----------
[Fix] Extended IT/MPTM instruments (referencing samples >= 256) from versions older than OpenMPT 1.20 were not readable.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ITTools.cpp
trunk/OpenMPT/soundlib/ITTools.h
Modified: trunk/OpenMPT/soundlib/ITTools.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ITTools.cpp 2013-11-18 00:32:28 UTC (rev 3259)
+++ trunk/OpenMPT/soundlib/ITTools.cpp 2013-11-18 00:53:40 UTC (rev 3260)
@@ -421,7 +421,7 @@
if(usedExtension)
{
// If we actually had to extend the sample map, update the magic bytes and instrument size.
- memcpy(iti.dummy, "MPTX", 4);
+ memcpy(iti.dummy, "XTPM", 4);
instSize = sizeof(ITInstrumentEx);
}
@@ -436,7 +436,8 @@
uint32 insSize = iti.ConvertToMPT(mptIns, fromType);
// Is this actually an extended instrument?
- if(insSize == 0 || memcmp(iti.dummy, "MPTX", 4))
+ // Note: OpenMPT 1.20 - 1.22 accidentally wrote "MPTX" here (since revision 1203), while previous versions wrote the reversed version, "XTPM".
+ if(insSize == 0 || (memcmp(iti.dummy, "MPTX", 4) && memcmp(iti.dummy, "XTPM", 4)))
{
return insSize;
}
Modified: trunk/OpenMPT/soundlib/ITTools.h
===================================================================
--- trunk/OpenMPT/soundlib/ITTools.h 2013-11-18 00:32:28 UTC (rev 3259)
+++ trunk/OpenMPT/soundlib/ITTools.h 2013-11-18 00:53:40 UTC (rev 3260)
@@ -217,11 +217,6 @@
// MPT IT Instrument Extension
struct PACKED ITInstrumentEx
{
- enum Magic
- {
- mptx = 0x5854504D, // "MPTX" Extended Instrument Header Magic Bytes
- };
-
ITInstrument iti; // Normal IT Instrument
uint8 keyboardhi[120]; // High Byte of Sample map
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2013-12-15 13:51:25
|
Revision: 3477
http://sourceforge.net/p/modplug/code/3477
Author: manxorist
Date: 2013-12-15 13:51:15 +0000 (Sun, 15 Dec 2013)
Log Message:
-----------
[Fix] Tuning: Correct a bogus check in CTuningBase::IsStepCountRangeSufficient which apparently tried to avoid integer overflows.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/tuning.h
trunk/OpenMPT/soundlib/tuningbase.h
Modified: trunk/OpenMPT/soundlib/tuning.h
===================================================================
--- trunk/OpenMPT/soundlib/tuning.h 2013-12-15 12:30:03 UTC (rev 3476)
+++ trunk/OpenMPT/soundlib/tuning.h 2013-12-15 13:51:15 UTC (rev 3477)
@@ -158,7 +158,7 @@
std::vector<RATIOTYPE> m_RatioTableFine;
//The lowest index of note in the table
- NOTEINDEXTYPE m_StepMin;
+ NOTEINDEXTYPE m_StepMin; // this should REALLY be called 'm_NoteMin' renaming was missed in r192
//For groupgeometric tunings, tells the 'group size' and 'group ratio'
//m_GroupSize should always be >= 0.
Modified: trunk/OpenMPT/soundlib/tuningbase.h
===================================================================
--- trunk/OpenMPT/soundlib/tuningbase.h 2013-12-15 12:30:03 UTC (rev 3476)
+++ trunk/OpenMPT/soundlib/tuningbase.h 2013-12-15 13:51:15 UTC (rev 3477)
@@ -175,7 +175,7 @@
bool IsValidNote(const NOTEINDEXTYPE n) const {return (n >= GetValidityRange().first && n <= GetValidityRange().second);}
//Checking that step distances can be presented with
- //value range of STEPINDEXTYPE with given finestepcount ja validityrange.
+ //value range of STEPINDEXTYPE with given finestepcount and validityrange.
bool IsStepCountRangeSufficient(USTEPINDEXTYPE fs, VRPAIR vrp);
virtual const char* GetTuningTypeDescription() const;
@@ -301,9 +301,13 @@
inline bool CTuningBase::IsStepCountRangeSufficient(USTEPINDEXTYPE fs, VRPAIR vrp)
-//------------------------------------------------------------------
+//--------------------------------------------------------------------------------
{
- if(vrp.first == STEPINDEXTYPE_MIN && vrp.second == STEPINDEXTYPE_MAX) return true;
+ { // avoid integer overload
+ //if(vrp.first == STEPINDEXTYPE_MIN && vrp.second == STEPINDEXTYPE_MAX) return true;
+ ASSERT(NOTEINDEXTYPE_MIN / 2 < vrp.first && vrp.second < NOTEINDEXTYPE_MAX / 2);
+ if(NOTEINDEXTYPE_MIN / 2 >= vrp.first || vrp.second >= NOTEINDEXTYPE_MAX / 2) return true;
+ }
if(fs > static_cast<USTEPINDEXTYPE>(STEPINDEXTYPE_MAX) / (vrp.second - vrp.first + 1)) return false;
else return true;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2013-12-23 22:12:02
|
Revision: 3520
http://sourceforge.net/p/modplug/code/3520
Author: saga-games
Date: 2013-12-23 22:11:54 +0000 (Mon, 23 Dec 2013)
Log Message:
-----------
[Fix] IT compatibility: If there's a note delay, slide commands in the volume column next to it should not start before the delay has finished. Test case: SlideDelay.it
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ModChannel.cpp
trunk/OpenMPT/soundlib/ModChannel.h
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/ModChannel.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ModChannel.cpp 2013-12-23 20:08:14 UTC (rev 3519)
+++ trunk/OpenMPT/soundlib/ModChannel.cpp 2013-12-23 22:11:54 UTC (rev 3520)
@@ -35,6 +35,7 @@
}
nTremorCount = 0;
nEFxSpeed = 0;
+ isFirstTick = false;
}
if(resetMask & resetSetPosAdvanced)
Modified: trunk/OpenMPT/soundlib/ModChannel.h
===================================================================
--- trunk/OpenMPT/soundlib/ModChannel.h 2013-12-23 20:08:14 UTC (rev 3519)
+++ trunk/OpenMPT/soundlib/ModChannel.h 2013-12-23 22:11:54 UTC (rev 3520)
@@ -102,6 +102,7 @@
uint8 nActiveMacro, nFilterMode;
uint8 nEFxSpeed, nEFxDelay; // memory for Invert Loop (EFx, .MOD only)
uint8 nNoteSlideCounter, nNoteSlideSpeed, nNoteSlideStep; // IMF / PTM Note Slide
+ bool isFirstTick;
ModCommand rowCommand;
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2013-12-23 20:08:14 UTC (rev 3519)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2013-12-23 22:11:54 UTC (rev 3520)
@@ -1610,6 +1610,7 @@
bool bPorta = (cmd == CMD_TONEPORTAMENTO) || (cmd == CMD_TONEPORTAVOL) || (volcmd == VOLCMD_TONEPORTAMENTO);
UINT nStartTick = 0;
+ pChn->isFirstTick = (m_nTickCount == 0);
pChn->dwFlags.reset(CHN_FASTVOLRAMP);
@@ -1785,6 +1786,13 @@
triggerNote = true;
}
+ // IT compatibility: Tick-0 vs non-tick-0 effect distinction is always based on tick delay.
+ // Test case: SlideDelay.it
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ {
+ pChn->isFirstTick = triggerNote;
+ }
+
// Handles note/instrument/volume changes
if(triggerNote)
{
@@ -2156,7 +2164,7 @@
case VOLCMD_FINEVOLUP:
// IT Compatibility: Fine volume slides in the volume column are only executed on the first tick, not on multiples of the first tick in case of pattern delay
// Test case: FineVolColSlide.it
- if(m_nTickCount == 0 || !IsCompatibleMode(TRK_IMPULSETRACKER))
+ if(m_nTickCount == nStartTick || !IsCompatibleMode(TRK_IMPULSETRACKER))
{
// IT Compatibility: Volume column volume slides have their own memory
// Test case: VolColMemory.it
@@ -2167,7 +2175,7 @@
case VOLCMD_FINEVOLDOWN:
// IT Compatibility: Fine volume slides in the volume column are only executed on the first tick, not on multiples of the first tick in case of pattern delay
// Test case: FineVolColSlide.it
- if(m_nTickCount == 0 || !IsCompatibleMode(TRK_IMPULSETRACKER))
+ if(m_nTickCount == nStartTick || !IsCompatibleMode(TRK_IMPULSETRACKER))
{
// IT Compatibility: Volume column volume slides have their own memory
// Test case: VolColMemory.it
@@ -2775,7 +2783,7 @@
}
}
// Regular Slide
- if(!m_SongFlags[SONG_FIRSTTICK])
+ if(!pChn->isFirstTick)
{
DoFreqSlide(pChn, -int(param) * 4);
}
@@ -2827,7 +2835,7 @@
}
}
- if(!m_SongFlags[SONG_FIRSTTICK])
+ if(!pChn->isFirstTick)
{
DoFreqSlide(pChn, int(param) * 4);
}
@@ -2849,7 +2857,7 @@
if(doFineSlides && actualParam >= 0xE0 && !GetModFlag(MSF_OLD_MIDI_PITCHBENDS))
{
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(Chn[nChn].isFirstTick)
{
// Extra fine slide...
pitchBend = (actualParam & 0x0F) * sgn(param);
@@ -2859,7 +2867,7 @@
pitchBend *= 4;
}
}
- } else if(!m_SongFlags[SONG_FIRSTTICK] || GetModFlag(MSF_OLD_MIDI_PITCHBENDS))
+ } else if(!Chn[nChn].isFirstTick || GetModFlag(MSF_OLD_MIDI_PITCHBENDS))
{
// Regular slide
pitchBend = param * 4;
@@ -2894,7 +2902,7 @@
if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
if ((pChn->nPeriod) && (param))
{
@@ -2929,7 +2937,7 @@
if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
if ((pChn->nPeriod) && (param))
{
@@ -2964,7 +2972,7 @@
if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
if ((pChn->nPeriod) && (param))
{
@@ -2999,7 +3007,7 @@
if(param) pChn->nOldFinePortaUpDown = param; else param = pChn->nOldFinePortaUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
if ((pChn->nPeriod) && (param))
{
@@ -3112,7 +3120,7 @@
} //End candidate MPT behavior.
if(param) pChn->nPortamentoSlide = param * 4;
- if(pChn->nPeriod && pChn->nPortamentoDest && !m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->nPeriod && pChn->nPortamentoDest && !pChn->isFirstTick)
{
if (pChn->nPeriod < pChn->nPortamentoDest)
{
@@ -3213,7 +3221,7 @@
return;
} else //Slide -15
{
- if(m_SongFlags[SONG_FIRSTTICK] && !m_SongFlags[SONG_FASTVOLSLIDES])
+ if(pChn->isFirstTick && !m_SongFlags[SONG_FASTVOLSLIDES])
{
newvolume -= 0x0F * 4;
}
@@ -3227,14 +3235,14 @@
return;
} else //Slide +15
{
- if(m_SongFlags[SONG_FIRSTTICK] && !m_SongFlags[SONG_FASTVOLSLIDES])
+ if(pChn->isFirstTick && !m_SongFlags[SONG_FASTVOLSLIDES])
{
newvolume += 0x0F * 4;
}
}
}
}
- if(!m_SongFlags[SONG_FIRSTTICK] || m_SongFlags[SONG_FASTVOLSLIDES])
+ if(!pChn->isFirstTick || m_SongFlags[SONG_FASTVOLSLIDES])
{
// IT compatibility: Ignore slide commands with both nibbles set.
if (param & 0x0F)
@@ -3354,7 +3362,7 @@
if(param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
pChn->nVolume += param * 4;
if(pChn->nVolume > 256) pChn->nVolume = 256;
@@ -3379,7 +3387,7 @@
if(param) pChn->nOldFineVolUpDown = param; else param = pChn->nOldFineVolUpDown;
}
- if(m_SongFlags[SONG_FIRSTTICK])
+ if(pChn->isFirstTick)
{
pChn->nVolume -= param * 4;
if(pChn->nVolume < 0) pChn->nVolume = 0;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-01-01 22:15:02
|
Revision: 3543
http://sourceforge.net/p/modplug/code/3543
Author: saga-games
Date: 2014-01-01 22:14:52 +0000 (Wed, 01 Jan 2014)
Log Message:
-----------
[Ref] Compare more FourCCs as strings, and where it's not possible to do so, use new macros MAGIC[2|4][BE|LE] to construct the magic numbers to increase readability.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ITTools.cpp
trunk/OpenMPT/soundlib/ITTools.h
trunk/OpenMPT/soundlib/Load_dmf.cpp
trunk/OpenMPT/soundlib/Load_gdm.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/Load_itp.cpp
trunk/OpenMPT/soundlib/Load_okt.cpp
trunk/OpenMPT/soundlib/Load_psm.cpp
trunk/OpenMPT/soundlib/Load_s3m.cpp
trunk/OpenMPT/soundlib/Loaders.h
trunk/OpenMPT/soundlib/S3MTools.cpp
trunk/OpenMPT/soundlib/S3MTools.h
trunk/OpenMPT/soundlib/SampleFormats.cpp
trunk/OpenMPT/soundlib/load_j2b.cpp
Modified: trunk/OpenMPT/soundlib/ITTools.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ITTools.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/ITTools.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -18,7 +18,6 @@
void ITFileHeader::ConvertEndianness()
//------------------------------------
{
- SwapBytesLE(id);
SwapBytesLE(ordnum);
SwapBytesLE(insnum);
SwapBytesLE(smpnum);
@@ -29,7 +28,6 @@
SwapBytesLE(special);
SwapBytesLE(msglength);
SwapBytesLE(msgoffset);
- SwapBytesLE(reserved);
}
@@ -118,7 +116,6 @@
void ITOldInstrument::ConvertEndianness()
//---------------------------------------
{
- SwapBytesLE(id);
SwapBytesLE(fadeout);
SwapBytesLE(trkvers);
}
@@ -129,7 +126,7 @@
//-------------------------------------------------------------
{
// Header
- if(id != ITOldInstrument::magic)
+ if(memcmp(id, "IMPI", 4))
{
return;
}
@@ -196,7 +193,6 @@
void ITInstrument::ConvertEndianness()
//------------------------------------
{
- SwapBytesLE(id);
SwapBytesLE(fadeout);
SwapBytesLE(trkvers);
SwapBytesLE(mbank);
@@ -210,7 +206,7 @@
MemsetZero(*this);
// Header
- id = ITInstrument::magic;
+ memcpy(id, "IMPI", 4);
trkvers = 0x0214;
mpt::String::Write<mpt::String::nullTerminated>(filename, mptIns.filename);
@@ -289,7 +285,7 @@
uint32 ITInstrument::ConvertToMPT(ModInstrument &mptIns, MODTYPE modFormat) const
//-------------------------------------------------------------------------------
{
- if(id != ITInstrument::magic)
+ if(memcmp(id, "IMPI", 4))
{
return 0;
}
@@ -456,7 +452,6 @@
void ITSample::ConvertEndianness()
//--------------------------------
{
- SwapBytesLE(id);
SwapBytesLE(length);
SwapBytesLE(loopbegin);
SwapBytesLE(loopend);
@@ -474,7 +469,7 @@
MemsetZero(*this);
// Header
- id = ITSample::magic;
+ memcpy(id, "IMPS", 4);
mpt::String::Write<mpt::String::nullTerminated>(filename, mptSmp.filename);
//mpt::String::Write<mpt::String::nullTerminated>(name, m_szNames[nsmp]);
@@ -546,7 +541,7 @@
uint32 ITSample::ConvertToMPT(ModSample &mptSmp) const
//----------------------------------------------------
{
- if(id != ITSample::magic)
+ if(memcmp(id, "IMPS", 4))
{
return 0;
}
Modified: trunk/OpenMPT/soundlib/ITTools.h
===================================================================
--- trunk/OpenMPT/soundlib/ITTools.h 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/ITTools.h 2014-01-01 22:14:52 UTC (rev 3543)
@@ -20,15 +20,6 @@
struct PACKED ITFileHeader
{
- // Magic Bytes
- enum Magic
- {
- itMagic = 0x4D504D49, // "IMPM" IT Header Magic Bytes
- mptmMagic = 0x2E6D7074, // "tpm." Old MPTM header magic bytes
- omptMagic = 0x54504D4F, // "OMPT" Magic Bytes for non-standard OpenMPT IT files
- chibiMagic = 0x49424843, // "CHBI" Magic Bytes in the IT header to identify ChibiTracker
- };
-
// Header Flags
enum ITHeaderFlags
{
@@ -52,7 +43,7 @@
embedMIDIConfiguration = 0x08,
};
- uint32 id; // Magic Bytes (IMPM)
+ char id[4]; // Magic Bytes (IMPM)
char songname[26]; // Song Name, null-terminated (but may also contain nulls)
uint8 highlight_minor; // Rows per Beat highlight
uint8 highlight_major; // Rows per Measure highlight
@@ -72,7 +63,7 @@
uint8 pwd; // Pitch Wheel Depth
uint16 msglength; // Length of Song Message
uint32 msgoffset; // Offset of Song Message in File (IT crops message after first null)
- uint32 reserved; // ChibiTracker writes "CHBI" here. OpenMPT writes "OMPT" here in some cases, see Load_it.cpp
+ char reserved[4]; // ChibiTracker writes "CHBI" here. OpenMPT writes "OMPT" here in some cases, see Load_it.cpp
uint8 chnpan[64]; // Initial Channel Panning
uint8 chnvol[64]; // Initial Channel Volume
@@ -116,12 +107,6 @@
// Old Impulse Instrument Format (cmwt < 0x200)
struct PACKED ITOldInstrument
{
- // Magic Bytes
- enum Magic
- {
- magic = 0x49504D49, // "IMPI" IT Instrument Header Magic Bytes
- };
-
enum ITOldInstrFlags
{
envEnabled = 0x01,
@@ -129,7 +114,7 @@
envSustain = 0x04,
};
- uint32 id; // Magic Bytes (IMPI)
+ char id[4]; // Magic Bytes (IMPI)
char filename[13]; // DOS Filename, null-terminated
uint8 flags; // Volume Envelope Flags
uint8 vls; // Envelope Loop Start
@@ -162,12 +147,6 @@
// Impulse Instrument Format
struct PACKED ITInstrument
{
- // Magic Bytes
- enum Magic
- {
- magic = 0x49504D49, // "IMPI" IT Instrument Header Magic Bytes
- };
-
enum ITInstrumentFlags
{
ignorePanning = 0x80,
@@ -175,7 +154,7 @@
enableResonance = 0x80,
};
- uint32 id; // Magic Bytes (IMPI)
+ char id[4]; // Magic Bytes (IMPI)
char filename[13]; // DOS Filename, null-terminated
uint8 nna; // New Note Action
uint8 dct; // Duplicate Note Check Type
@@ -263,7 +242,7 @@
cvtPTM8to16 = 0x08,
};
- uint32 id; // Magic Bytes (IMPS)
+ char id[4]; // Magic Bytes (IMPS)
char filename[13]; // DOS Filename, null-terminated
uint8 gvl; // Global Volume
uint8 flags; // Sample Flags
Modified: trunk/OpenMPT/soundlib/Load_dmf.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_dmf.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_dmf.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -44,14 +44,14 @@
// 32-Bit chunk identifiers
enum ChunkIdentifiers
{
- idCMSG = 0x47534D43, // Song message
- idSEQU = 0x55514553, // Order list
- idPATT = 0x54544150, // Patterns
- idSMPI = 0x49504D53, // Sample headers
- idSMPD = 0x44504D53, // Sample data
- idSMPJ = 0x4A504D53, // Sample jump table (XTrakcker 32 only)
- idENDE = 0x45444E45, // Last four bytes of DMF file
- idSETT = 0x9C219DE4, // Probably contains GUI settings
+ idCMSG = MAGIC4LE('C','M','S','G'), // Song message
+ idSEQU = MAGIC4LE('S','E','Q','U'), // Order list
+ idPATT = MAGIC4LE('P','A','T','T'), // Patterns
+ idSMPI = MAGIC4LE('S','M','P','I'), // Sample headers
+ idSMPD = MAGIC4LE('S','M','P','D'), // Sample data
+ idSMPJ = MAGIC4LE('S','M','P','J'), // Sample jump table (XTrakcker 32 only)
+ idENDE = MAGIC4LE('E','N','D','E'), // Last four bytes of DMF file
+ idSETT = MAGIC4LE('S','E','T','T'), // Probably contains GUI settings
};
typedef ChunkIdentifiers id_type;
Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_gdm.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -24,18 +24,11 @@
// GDM File Header
struct PACKED GDMFileHeader
{
- // Header magic bytes
- enum HeaderMagic
- {
- magicGDM_ = 0xFE4D4447,
- magicGMFS = 0x53464D47,
- };
-
- uint32 magic; // ID: 'GDM\xFE'
+ char magic[4]; // ID: 'GDM\xFE'
char songTitle[32]; // Music's title
char songMusician[32]; // Name of music's composer
char dosEOF[3]; // 13, 10, 26
- uint32 magic2; // ID: 'GMFS'
+ char magic2[4]; // ID: 'GMFS'
uint8 formatMajorVer; // Format major version
uint8 formatMinorVer; // Format minor version
uint16 trackerID; // Composing Tracker ID code (00 = 2GDM)
@@ -66,8 +59,6 @@
// Convert all multi-byte numeric values to current platform's endianness or vice versa.
void ConvertEndianness()
{
- SwapBytesLE(magic);
- SwapBytesLE(magic2);
SwapBytesLE(trackerID);
SwapBytesLE(originalFormat);
SwapBytesLE(orderOffset);
@@ -143,9 +134,9 @@
GDMFileHeader fileHeader;
if(!file.ReadConvertEndianness(fileHeader)
- || fileHeader.magic != GDMFileHeader::magicGDM_
+ || memcmp(fileHeader.magic, "GDM\xFE", 4)
|| fileHeader.dosEOF[0] != 13 || fileHeader.dosEOF[1] != 10 || fileHeader.dosEOF[2] != 26
- || fileHeader.magic2 != GDMFileHeader::magicGMFS
+ || memcmp(fileHeader.magic2, "GMFS", 4)
|| fileHeader.formatMajorVer != 1 || fileHeader.formatMinorVer != 0
|| fileHeader.originalFormat >= CountOf(gdmFormatOrigin)
|| fileHeader.originalFormat == 0)
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -321,7 +321,7 @@
ITFileHeader fileHeader;
if(!file.ReadConvertEndianness(fileHeader)
- || (fileHeader.id != ITFileHeader::itMagic && fileHeader.id != ITFileHeader::mptmMagic)
+ || (memcmp(fileHeader.id, "IMPM", 4) && memcmp(fileHeader.id, "tpm.", 4))
|| fileHeader.insnum > 0xFF
|| fileHeader.smpnum >= MAX_SAMPLES
|| !file.CanRead(fileHeader.ordnum + (fileHeader.insnum + fileHeader.smpnum + fileHeader.patnum) * 4))
@@ -344,8 +344,9 @@
mptStartPos = file.GetLength();
}
- if(fileHeader.id == ITFileHeader::mptmMagic)
+ if(!memcmp(fileHeader.id, "tpm.", 4))
{
+ // Legacy MPTM files (old 1.17.02.xx releases)
ChangeModTypeTo(MOD_TYPE_MPT);
} else
{
@@ -366,7 +367,7 @@
// OpenMPT Version number (Major.Minor)
// This will only be interpreted as "made with ModPlug" (i.e. disable compatible playback etc) if the "reserved" field is set to "OMPT" - else, compatibility was used.
m_dwLastSavedWithVersion = (fileHeader.cwtv & 0x0FFF) << 16;
- if(fileHeader.reserved == ITFileHeader::omptMagic)
+ if(!memcmp(fileHeader.reserved, "OMPT", 4))
interpretModPlugMade = true;
} else if(fileHeader.cmwt == 0x888 || fileHeader.cwtv == 0x888)
{
@@ -648,7 +649,7 @@
ITSample sampleHeader;
if(smpPos[i] > 0 && file.Seek(smpPos[i]) && file.ReadConvertEndianness(sampleHeader))
{
- if(sampleHeader.id == ITSample::magic)
+ if(!memcmp(sampleHeader.id, "IMPS", 4))
{
size_t sampleOffset = sampleHeader.ConvertToMPT(Samples[i + 1]);
@@ -930,7 +931,7 @@
if(m_dwLastSavedWithVersion && madeWithTracker.empty())
{
madeWithTracker = "OpenMPT " + MptVersion::ToStr(m_dwLastSavedWithVersion);
- if(fileHeader.reserved != ITFileHeader::omptMagic && (fileHeader.cwtv & 0xF000) == 0x5000)
+ if(memcmp(fileHeader.reserved, "OMPT", 4) && (fileHeader.cwtv & 0xF000) == 0x5000)
{
madeWithTracker += " (compatibility export)";
} else if(MptVersion::IsTestBuild(m_dwLastSavedWithVersion))
@@ -958,7 +959,7 @@
m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5);
madeWithTracker = "ModPlug tracker 1.00a5";
interpretModPlugMade = true;
- } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && fileHeader.reserved == ITFileHeader::chibiMagic)
+ } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !memcmp(fileHeader.reserved, "CHBI", 4))
{
madeWithTracker = "ChibiTracker";
} else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !(fileHeader.special & 3) && fileHeader.reserved == 0 && !strcmp(Samples[1].filename, "XXXXXXXX.YYY"))
@@ -1122,7 +1123,7 @@
// Writing Header
MemsetZero(itHeader);
dwChnNamLen = 0;
- itHeader.id = ITFileHeader::itMagic;
+ memcpy(itHeader.id, "IMPM", 4);
mpt::String::Write<mpt::String::nullTerminated>(itHeader.songname, songName);
itHeader.highlight_minor = (uint8)std::min(m_nDefaultRowsPerBeat, ROWINDEX(uint8_max));
@@ -1177,7 +1178,7 @@
if(!compatibilityExport)
{
// This way, we indicate that the file will most likely contain OpenMPT hacks. Compatibility export puts 0 here.
- itHeader.reserved = ITFileHeader::omptMagic;
+ memcpy(itHeader.reserved, "OMPT", 4);
}
}
@@ -1885,35 +1886,35 @@
void CSoundFile::SaveExtendedInstrumentProperties(UINT nInstruments, FILE* f) const
//---------------------------------------------------------------------------------
{
- uint32 code = MULTICHAR4_LE_MSVC('M','P','T','X'); // write extension header code
+ uint32 code = MAGIC4BE('M','P','T','X'); // write extension header code
fwrite(&code, 1, sizeof(uint32), f);
if (nInstruments == 0)
return;
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('V','R','.','.'), sizeof(ModInstrument().nVolRampUp), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('M','i','P','.'), sizeof(ModInstrument().nMixPlug), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('M','C','.','.'), sizeof(ModInstrument().nMidiChannel),f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('M','P','.','.'), sizeof(ModInstrument().nMidiProgram),f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('M','B','.','.'), sizeof(ModInstrument().wMidiBank), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','.','.','.'), sizeof(ModInstrument().nPan), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('G','V','.','.'), sizeof(ModInstrument().nGlobalVol), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('F','O','.','.'), sizeof(ModInstrument().nFadeOut), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('R','.','.','.'), sizeof(ModInstrument().nResampling), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('C','S','.','.'), sizeof(ModInstrument().nCutSwing), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('R','S','.','.'), sizeof(ModInstrument().nResSwing), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('F','M','.','.'), sizeof(ModInstrument().nFilterMode), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','E','R','N'), sizeof(ModInstrument().PitchEnv.nReleaseNode ), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('A','E','R','N'), sizeof(ModInstrument().PanEnv.nReleaseNode), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('V','E','R','N'), sizeof(ModInstrument().VolEnv.nReleaseNode), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','T','T','L'), sizeof(ModInstrument().wPitchToTempoLock), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','V','E','H'), sizeof(ModInstrument().nPluginVelocityHandling), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','V','O','H'), sizeof(ModInstrument().nPluginVolumeHandling), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','R','.','.'), sizeof(ModInstrument().nVolRampUp), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','i','P','.'), sizeof(ModInstrument().nMixPlug), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','C','.','.'), sizeof(ModInstrument().nMidiChannel),f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','P','.','.'), sizeof(ModInstrument().nMidiProgram),f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','B','.','.'), sizeof(ModInstrument().wMidiBank), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','.','.','.'), sizeof(ModInstrument().nPan), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('G','V','.','.'), sizeof(ModInstrument().nGlobalVol), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('F','O','.','.'), sizeof(ModInstrument().nFadeOut), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('R','.','.','.'), sizeof(ModInstrument().nResampling), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('C','S','.','.'), sizeof(ModInstrument().nCutSwing), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('R','S','.','.'), sizeof(ModInstrument().nResSwing), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('F','M','.','.'), sizeof(ModInstrument().nFilterMode), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','R','N'), sizeof(ModInstrument().PitchEnv.nReleaseNode ), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('A','E','R','N'), sizeof(ModInstrument().PanEnv.nReleaseNode), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','R','N'), sizeof(ModInstrument().VolEnv.nReleaseNode), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','T','T','L'), sizeof(ModInstrument().wPitchToTempoLock), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','V','E','H'), sizeof(ModInstrument().nPluginVelocityHandling), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','V','O','H'), sizeof(ModInstrument().nPluginVolumeHandling), f, nInstruments);
if(!(GetType() & MOD_TYPE_XM))
{
// XM instrument headers already have support for this
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('M','P','W','D'), sizeof(ModInstrument().midiPWD), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('M','P','W','D'), sizeof(ModInstrument().midiPWD), f, nInstruments);
}
if(GetType() & MOD_TYPE_MPT)
@@ -1928,17 +1929,17 @@
// write full envelope information for MPTM files (more env points)
if(maxNodes > 25)
{
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('V','E','.','.'), sizeof(ModInstrument().VolEnv.nNodes), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('V','P','[','.'), sizeof(ModInstrument().VolEnv.Ticks), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('V','E','[','.'), sizeof(ModInstrument().VolEnv.Values), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','.','.'), sizeof(ModInstrument().VolEnv.nNodes), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','P','[','.'), sizeof(ModInstrument().VolEnv.Ticks), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('V','E','[','.'), sizeof(ModInstrument().VolEnv.Values), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','E','.','.'), sizeof(ModInstrument().PanEnv.nNodes), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','P','[','.'), sizeof(ModInstrument().PanEnv.Ticks), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','E','[','.'), sizeof(ModInstrument().PanEnv.Values), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','.','.'), sizeof(ModInstrument().PanEnv.nNodes), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','P','[','.'), sizeof(ModInstrument().PanEnv.Ticks), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','E','[','.'), sizeof(ModInstrument().PanEnv.Values), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','i','E','.'), sizeof(ModInstrument().PitchEnv.nNodes), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','i','P','['), sizeof(ModInstrument().PitchEnv.Ticks), f, nInstruments);
- WriteInstrumentPropertyForAllInstruments(MULTICHAR4_LE_MSVC('P','i','E','['), sizeof(ModInstrument().PitchEnv.Values), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','E','.'), sizeof(ModInstrument().PitchEnv.nNodes), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','P','['), sizeof(ModInstrument().PitchEnv.Ticks), f, nInstruments);
+ WriteInstrumentPropertyForAllInstruments(MAGIC4BE('P','i','E','['), sizeof(ModInstrument().PitchEnv.Values), f, nInstruments);
}
}
@@ -1967,12 +1968,12 @@
//--------------------------------------------------------
{
//Extra song data - Yet Another Hack.
- const uint32 code = MULTICHAR4_LE_MSVC('M','P','T','S');
+ const uint32 code = MAGIC4BE('M','P','T','S');
fwrite(&code, 1, sizeof(uint32), f);
#define WRITEMODULARHEADER(c1, c2, c3, c4, fsize) \
{ \
- const uint32 code = MULTICHAR4_LE_MSVC(c1, c2, c3, c4); \
+ const uint32 code = MAGIC4BE(c1, c2, c3, c4); \
fwrite(&code, 1, sizeof(code), f); \
const uint16 size = (fsize); \
fwrite(&size, 1, sizeof(size), f); \
@@ -2079,7 +2080,7 @@
{
uint32 code = file.ReadUint32LE();
- if(code == MULTICHAR4_LE_MSVC('M','P','T','S')) //Reached song extensions, break out of this loop
+ if(code == MAGIC4BE('M','P','T','S')) //Reached song extensions, break out of this loop
{
file.SkipBack(4);
return;
@@ -2153,23 +2154,23 @@
switch (code) // interpret field code
{
- case MULTICHAR4_LE_MSVC('D','T','.','.'): ReadField(chunk, size, m_nDefaultTempo); break;
- case MULTICHAR4_LE_MSVC('R','P','B','.'): ReadField(chunk, size, m_nDefaultRowsPerBeat); break;
- case MULTICHAR4_LE_MSVC('R','P','M','.'): ReadField(chunk, size, m_nDefaultRowsPerMeasure); break;
- case MULTICHAR4_LE_MSVC('C','.','.','.'): if(modtype != MOD_TYPE_XM) ReadField(chunk, size, m_nChannels); break;
- case MULTICHAR4_LE_MSVC('T','M','.','.'): ReadField(chunk, size, m_nTempoMode); break;
- case MULTICHAR4_LE_MSVC('P','M','M','.'): ReadFieldCast(chunk, size, m_nMixLevels); break;
- case MULTICHAR4_LE_MSVC('C','W','V','.'): ReadField(chunk, size, m_dwCreatedWithVersion); break;
- case MULTICHAR4_LE_MSVC('L','S','W','V'): ReadField(chunk, size, m_dwLastSavedWithVersion); break;
- case MULTICHAR4_LE_MSVC('S','P','A','.'): ReadField(chunk, size, m_nSamplePreAmp); break;
- case MULTICHAR4_LE_MSVC('V','S','T','V'): ReadField(chunk, size, m_nVSTiVolume); break;
- case MULTICHAR4_LE_MSVC('D','G','V','.'): ReadField(chunk, size, m_nDefaultGlobalVolume); break;
- case MULTICHAR4_LE_MSVC('R','P','.','.'): if(modtype != MOD_TYPE_XM) ReadField(chunk, size, m_nRestartPos); break;
- case MULTICHAR4_LE_MSVC('M','S','F','.'): ReadFieldFlagSet(chunk, size, m_ModFlags); break;
+ case MAGIC4BE('D','T','.','.'): ReadField(chunk, size, m_nDefaultTempo); break;
+ case MAGIC4BE('R','P','B','.'): ReadField(chunk, size, m_nDefaultRowsPerBeat); break;
+ case MAGIC4BE('R','P','M','.'): ReadField(chunk, size, m_nDefaultRowsPerMeasure); break;
+ case MAGIC4BE('C','.','.','.'): if(modtype != MOD_TYPE_XM) ReadField(chunk, size, m_nChannels); break;
+ case MAGIC4BE('T','M','.','.'): ReadField(chunk, size, m_nTempoMode); break;
+ case MAGIC4BE('P','M','M','.'): ReadFieldCast(chunk, size, m_nMixLevels); break;
+ case MAGIC4BE('C','W','V','.'): ReadField(chunk, size, m_dwCreatedWithVersion); break;
+ case MAGIC4BE('L','S','W','V'): ReadField(chunk, size, m_dwLastSavedWithVersion); break;
+ case MAGIC4BE('S','P','A','.'): ReadField(chunk, size, m_nSamplePreAmp); break;
+ case MAGIC4BE('V','S','T','V'): ReadField(chunk, size, m_nVSTiVolume); break;
+ case MAGIC4BE('D','G','V','.'): ReadField(chunk, size, m_nDefaultGlobalVolume); break;
+ case MAGIC4BE('R','P','.','.'): if(modtype != MOD_TYPE_XM) ReadField(chunk, size, m_nRestartPos); break;
+ case MAGIC4BE('M','S','F','.'): ReadFieldFlagSet(chunk, size, m_ModFlags); break;
#ifdef MODPLUG_TRACKER
- case MULTICHAR4_LE_MSVC('M','I','M','A'): GetMIDIMapper().Deserialize(chunk); break;
+ case MAGIC4BE('M','I','M','A'): GetMIDIMapper().Deserialize(chunk); break;
#endif
- case MULTICHAR4_LE_MSVC('C','h','n','S'):
+ case MAGIC4BE('C','h','n','S'):
if(size <= (MAX_BASECHANNELS - 64) * 2 && (size % 2u) == 0)
{
STATIC_ASSERT(CountOf(ChnSettings) >= 64);
@@ -2227,7 +2228,7 @@
}
uint32 modularInstSize = 0;
- uint32 id = MULTICHAR4_LE_MSVC('I','N','S','M');
+ uint32 id = MAGIC4BE('I','N','S','M');
SwapBytesLE(id);
fwrite(&id, 1, sizeof(id), f); // mark this as an instrument with modular extensions
long sizePos = ftell(f); // we will want to write the modular data's total size here
@@ -2235,7 +2236,7 @@
// Write chunks
{ //VST Slot chunk:
- id = MULTICHAR4_LE_MSVC('P','L','U','G');
+ id = MAGIC4BE('P','L','U','G');
SwapBytesLE(id);
fwrite(&id, 1, sizeof(uint32), f);
fwrite(&(pIns->nMixPlug), 1, sizeof(uint8), f);
@@ -2286,7 +2287,7 @@
switch (chunkID)
{
- case MULTICHAR4_LE_MSVC('P','L','U','G'):
+ case MAGIC4BE('P','L','U','G'):
// Chunks don't tell us their length - stupid!
ins.nMixPlug = modularData.ReadUint8();
break;
Modified: trunk/OpenMPT/soundlib/Load_itp.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_itp.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_itp.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -34,7 +34,7 @@
// v1.01: Added option to embed instrument headers
#define ITP_VERSION 0x00000103 // v1.03
-#define ITP_FILE_ID 0x2E697470 // .itp ASCII
+#define ITP_FILE_ID MAGIC4BE('.','i','t','p') // .itp ASCII
// Read variable-length ITP string.
@@ -231,7 +231,7 @@
file.ReadConvertEndianness(sampleHeader);
size = file.ReadUint32LE();
- if(realSample >= 1 && realSample < MAX_SAMPLES && sampleHeader.id == ITSample::magic)
+ if(realSample >= 1 && realSample < MAX_SAMPLES && !memcmp(sampleHeader.id, "IMPS", 4))
{
sampleHeader.ConvertToMPT(Samples[realSample]);
mpt::String::Read<mpt::String::nullTerminated>(m_szNames[realSample], sampleHeader.name);
Modified: trunk/OpenMPT/soundlib/Load_okt.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_okt.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_okt.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -21,14 +21,14 @@
// IFF chunk names
enum ChunkIdentifiers
{
- idCMOD = 0x434D4F44,
- idSAMP = 0x53414D50,
- idSPEE = 0x53504545,
- idSLEN = 0x534C454E,
- idPLEN = 0x504C454E,
- idPATT = 0x50415454,
- idPBOD = 0x50424F44,
- idSBOD = 0x53424F44,
+ idCMOD = MAGIC4BE('C','M','O','D'),
+ idSAMP = MAGIC4BE('S','A','M','P'),
+ idSPEE = MAGIC4BE('S','P','E','E'),
+ idSLEN = MAGIC4BE('S','L','E','N'),
+ idPLEN = MAGIC4BE('P','L','E','N'),
+ idPATT = MAGIC4BE('P','A','T','T'),
+ idPBOD = MAGIC4BE('P','B','O','D'),
+ idSBOD = MAGIC4BE('S','B','O','D'),
};
uint32 signature; // IFF chunk name
Modified: trunk/OpenMPT/soundlib/Load_psm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_psm.cpp 2014-01-01 21:55:55 UTC (rev 3542)
+++ trunk/OpenMPT/soundlib/Load_psm.cpp 2014-01-01 22:14:52 UTC (rev 3543)
@@ -39,23 +39,14 @@
// PSM File Header
struct PACKED PSMFileHeader
{
- // Magic Bytes
- enum PSMMagic
- {
- magicPSM_ = 0x204D5350,
- magicFILE = 0x454C4946,
- };
-
- uint32 formatID; // "PSM " (new format)
+ char formatID[4]; // "PSM " (new format)
uint32 fileSize; // Filesize - 12
- uint32 fileInfoID; // "FILE" Start of file info
+ char fileInfoID[4]; // "FILE"
// Convert all multi-byte numeric values to current platform's endianness or vice versa.
void ConvertEndianness()
{
- SwapBytesLE(formatID);
SwapBytesLE(fileSize);
- SwapBytesLE(fileInfoID);
}
};
@@ -67,16 +58,16 @@
// 32-Bit chunk identifiers
enum ChunkIdentifiers
{
- idTITL = 0x4C544954,
- idSDFT = 0x54464453,
- idPBOD = 0x444F4250,
- idSONG = 0x474E4F53,
- idDATE = 0x45544144,
- idOPLH = 0x484C504F,
- idPPAN = 0x4E415050,
- idPATT = 0x54544150,
- idDSAM = 0x4D415344,
- idDSMP = 0x504D5344,
+ idTITL = MAGIC4LE('T','I','T','L'),
+ idSDFT = MAGIC4LE('S','D','F','T'),
+ idPBOD = MAGIC4LE('P','B','O','D'),
+ idSONG = MAGIC4LE('S','O','N','G'),
+ idDATE = MAGIC4LE('D','A','T','E'),
+ idOPLH = MAGIC4LE('O','P','L','H'),
+ idPPAN = MAGIC4LE('P','P','A','N'),
+ idPATT = MAGIC4LE('P','A','T','T'),
+ idDSAM = MAGIC4LE('D','S','A','M'),
+ idDSMP = MAGIC4LE('D','S','M','P'),
};
typedef ChunkIdentifiers id_type;
@@ -277,9 +268,9 @@
bool newFormat = false; // The game "Sinaria" uses a slightly modified PSM structure
// Check header
- if(fileHeader.formatID != PSMFileHeader::magicPSM_ // "PSM "
+ if(memcmp(fileHeader.formatID, "PSM ", 4)
|| fileHeader.fileSize != file.BytesLeft()
- || fileHeader.fileInfoID != PSMFileHeader::magicFILE) // "FILE"
+ || memcmp(fileHeader.fileInfoID, "FILE", 4))
{
return false;
} else if(loadFlags == onlyVerifyHeader)
@@ -609,7 +600,7 @@
SAMPLEINDEX smp = static_cast<SAMPLEINDEX>(sampleHeader.sampleNumber + 1);
if(smp < MAX_SAMPLES)
{
- m_nSamples = MAX(m_nSamples, smp);
+ m_nSamples = std::max(m_nSamples, smp);
mpt::String::Read<mpt::String::nullTerminated>(m_szNames[smp], sampleHeader.sampleName);
sampleHeader.ConvertToMPT(Samples[smp]);
@@ -627,7 +618,7 @@
SAMPLEINDEX smp = static_cast<SAMPLEINDEX>(sampleHeader.sampleNumber + 1);
if(smp < MAX_SAMPLES)
{
- m_nSamples = MAX(m_nSamples, smp);
+ m_nSamples = std::max(m_nSamples, smp);
mpt::String::Read<mpt::String::nullTerminated>(m_szNames[smp], sampleHeader.sampleName);
sampleHeader.ConvertToMPT(Samples[smp]);
@@ -972,15 +963,13 @@
// 32-Bit chunk identifiers
enum PSM16Magic
{
- magicPSM_ = 0xFE4D5350,
-
- idPORD = 0x44524f50,
- idPPAN = 0x4E415050,
- idPSAH = 0x48415350,
- idPPAT = 0x54415050,
+ idPORD = MAGIC4LE('P','O','R','D'),
+ idPPAN = MAGIC4LE('P','P','A','N'),
+ idPSAH = MAGIC4LE('P','S','A','H'),
+ idPPAT = MAGIC4LE('P','P','A','T'),
};
- uint32 formatID; // "PSM\xFE" (PSM16)
+ char ...
[truncated message content] |
|
From: <sag...@us...> - 2014-01-05 17:10:28
|
Revision: 3562
http://sourceforge.net/p/modplug/code/3562
Author: saga-games
Date: 2014-01-05 17:10:19 +0000 (Sun, 05 Jan 2014)
Log Message:
-----------
[Fix] GDM: Use S91 command for surround so that it's independent from exact Xxx / 8xx interpretation (probably a rather theoretical fix, but let's better be safe than sorry)
[Fix] IT: Tracker detection was partially broken
[Fix] DBM: Volume slides also work at one tick per row (libopenmpt only)
[Fix] Fill order list with stop patterns when using ModSequence::ReadAsByte (relatively theoretical fix)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_gdm.cpp
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/ModSequence.cpp
trunk/OpenMPT/soundlib/ModSequence.h
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_gdm.cpp 2014-01-05 14:59:40 UTC (rev 3561)
+++ trunk/OpenMPT/soundlib/Load_gdm.cpp 2014-01-05 17:10:19 UTC (rev 3562)
@@ -441,14 +441,11 @@
switch(m.param & 0x0F)
{
case 0x0: // Surround Off
- m.param = 0x90;
- break;
case 0x1: // Surround On
- m.command = CMD_PANNING8;
- m.param = 0xA4;
+ m.param += 0x90;
break;
case 0x2: // Set normal loop - not implemented in BWSB or 2GDM.
- case 0x3: // Set bidi loop - dito
+ case 0x3: // Set bidi loop - ditto
m.command = CMD_NONE;
break;
case 0x4: // Play sample forwards
@@ -460,9 +457,9 @@
m.param = 0x9F;
break;
case 0x6: // Monaural sample - also not implemented.
- case 0x7: // Stereo sample - dito
- case 0x8: // Stop sample on end - dito
- case 0x9: // Loop sample on end - dito
+ case 0x7: // Stereo sample - ditto
+ case 0x8: // Stop sample on end - ditto
+ case 0x9: // Loop sample on end - ditto
default:
m.command = CMD_NONE;
break;
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2014-01-05 14:59:40 UTC (rev 3561)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2014-01-05 17:10:19 UTC (rev 3562)
@@ -375,7 +375,7 @@
// Exact version number will be determined later.
interpretModPlugMade = true;
m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 17, 00, 00);
- } else if(fileHeader.cwtv == 0x0217 && fileHeader.cmwt == 0x0200 && fileHeader.reserved == 0)
+ } else if(fileHeader.cwtv == 0x0217 && fileHeader.cmwt == 0x0200 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4))
{
if(memchr(fileHeader.chnpan, 0xFF, sizeof(fileHeader.chnpan)) != NULL)
{
@@ -390,7 +390,7 @@
madeWithTracker = "OpenMPT 1.17 (compatibility export)";
}
interpretModPlugMade = true;
- } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0202 && fileHeader.reserved == 0)
+ } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0202 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4))
{
// ModPlug Tracker b3.3 - 1.09, instruments 557 bytes apart
m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 09, 00, 00);
@@ -543,7 +543,7 @@
// Oops, we were not supposed to read this.
file.SkipBack(2);
}
- } else if(fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.cmwt == 0x0214 && fileHeader.cwtv == 0x0214 && fileHeader.reserved == 0 && (fileHeader.special & (ITFileHeader::embedEditHistory | ITFileHeader::embedPatternHighlights)) == 0)
+ } else if(fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0 && fileHeader.cmwt == 0x0214 && fileHeader.cwtv == 0x0214 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4) && (fileHeader.special & (ITFileHeader::embedEditHistory | ITFileHeader::embedPatternHighlights)) == 0)
{
// Another non-conforming application is unmo3 < v2.4.0.1, which doesn't set the special bit
// at all, but still writes the two edit history length bytes (zeroes)...
@@ -950,10 +950,10 @@
&& fileHeader.highlight_major == 0 && fileHeader.highlight_minor == 0
&& fileHeader.insnum == 0 && fileHeader.patnum + 1 == fileHeader.ordnum
&& fileHeader.globalvol == 128 && fileHeader.mv == 100 && fileHeader.speed == 1 && fileHeader.sep == 128 && fileHeader.pwd == 0
- && fileHeader.msglength == 0 && fileHeader.msgoffset == 0 && fileHeader.reserved == 0)
+ && fileHeader.msglength == 0 && fileHeader.msgoffset == 0 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4))
{
madeWithTracker = "OpenSPC conversion";
- } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && fileHeader.reserved == 0)
+ } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0200 && !memcmp(fileHeader.reserved, "\0\0\0\0", 4))
{
// ModPlug Tracker 1.00a5, instruments 560 bytes apart
m_dwLastSavedWithVersion = MAKE_VERSION_NUMERIC(1, 00, 00, A5);
@@ -962,7 +962,7 @@
} else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !memcmp(fileHeader.reserved, "CHBI", 4))
{
madeWithTracker = "ChibiTracker";
- } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !(fileHeader.special & 3) && fileHeader.reserved == 0 && !strcmp(Samples[1].filename, "XXXXXXXX.YYY"))
+ } else if(fileHeader.cwtv == 0x0214 && fileHeader.cmwt == 0x0214 && !(fileHeader.special & 3) && !memcmp(fileHeader.reserved, "\0\0\0\0", 4) && !strcmp(Samples[1].filename, "XXXXXXXX.YYY"))
{
madeWithTracker = "CheeseTracker";
} else
Modified: trunk/OpenMPT/soundlib/ModSequence.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.cpp 2014-01-05 14:59:40 UTC (rev 3561)
+++ trunk/OpenMPT/soundlib/ModSequence.cpp 2014-01-05 17:10:19 UTC (rev 3562)
@@ -660,8 +660,8 @@
#ifdef MODPLUG_TRACKER
// Check if a playback position is currently locked (inaccessible)
-bool ModSequence::IsPositionLocked(ORDERINDEX position)
-//-----------------------------------------------------
+bool ModSequence::IsPositionLocked(ORDERINDEX position) const
+//-----------------------------------------------------------
{
return(m_sndFile.m_lockOrderStart != ORDERINDEX_INVALID
&& (position < m_sndFile.m_lockOrderStart || position > m_sndFile.m_lockOrderEnd));
@@ -741,6 +741,7 @@
}
+// TODO: Need a way to declare skip/stop indices?
bool ModSequence::ReadAsByte(FileReader &file, size_t howMany, size_t readEntries)
//--------------------------------------------------------------------------------
{
@@ -760,6 +761,8 @@
{
(*this)[i] = file.ReadUint8();
}
+ std::fill(begin() + readEntries, end(), GetInvalidPatIndex());
+
file.Skip(howMany - readEntries);
return true;
}
Modified: trunk/OpenMPT/soundlib/ModSequence.h
===================================================================
--- trunk/OpenMPT/soundlib/ModSequence.h 2014-01-05 14:59:40 UTC (rev 3561)
+++ trunk/OpenMPT/soundlib/ModSequence.h 2014-01-05 17:10:19 UTC (rev 3562)
@@ -112,7 +112,7 @@
#ifdef MODPLUG_TRACKER
// Check if a playback position is currently locked (inaccessible)
- bool IsPositionLocked(ORDERINDEX position);
+ bool IsPositionLocked(ORDERINDEX position) const;
#endif // MODPLUG_TRACKER
// Sequence name setter
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-05 14:59:40 UTC (rev 3561)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-05 17:10:19 UTC (rev 3562)
@@ -2780,7 +2780,7 @@
}
}
// Regular Slide
- if(!pChn->isFirstTick)
+ if(!pChn->isFirstTick || (m_nMusicSpeed == 1 && GetType() == MOD_TYPE_DBM))
{
DoFreqSlide(pChn, -int(param) * 4);
}
@@ -2832,7 +2832,7 @@
}
}
- if(!pChn->isFirstTick)
+ if(!pChn->isFirstTick || (m_nMusicSpeed == 1 && GetType() == MOD_TYPE_DBM))
{
DoFreqSlide(pChn, int(param) * 4);
}
@@ -3239,7 +3239,7 @@
}
}
}
- if(!pChn->isFirstTick || m_SongFlags[SONG_FASTVOLSLIDES])
+ if(!pChn->isFirstTick || m_SongFlags[SONG_FASTVOLSLIDES] || (m_nMusicSpeed == 1 && GetType() == MOD_TYPE_DBM))
{
// IT compatibility: Ignore slide commands with both nibbles set.
if (param & 0x0F)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-01-12 18:03:32
|
Revision: 3569
http://sourceforge.net/p/modplug/code/3569
Author: saga-games
Date: 2014-01-12 18:03:25 +0000 (Sun, 12 Jan 2014)
Log Message:
-----------
[Fix] MT2: Channel volume was not imported. Some volume slide commands didn't work in libopenmpt, too.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_mt2.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_mt2.cpp 2014-01-12 12:44:10 UTC (rev 3568)
+++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2014-01-12 18:03:25 UTC (rev 3569)
@@ -207,7 +207,9 @@
m->command = p->fxparam2;
m->param = p->fxparam1;
that->ConvertModCommand(*m);
+#ifdef MODPLUG_TRACKER
m->Convert(MOD_TYPE_XM, MOD_TYPE_IT);
+#endif // MODPLUG_TRACKER
} else
{
// TODO: MT2 Effects
@@ -296,7 +298,7 @@
switch(dwId)
{
// MSG
- case 0x0047534D:
+ case MAGIC4LE('M','S','G','\0'):
if (dwLen > 3)
{
DWORD nTxtLen = dwLen;
@@ -304,11 +306,25 @@
songMessage.Read(lpStream + dwMemPos + 1, nTxtLen - 1, SongMessage::leCRLF);
}
break;
+ case MAGIC4LE('T','R','K','S'):
+ if (dwLen >= 2)
+ {
+ m_nSamplePreAmp = LittleEndianW(*(uint16 *)(lpStream+dwMemPos)) >> 9;
+ dwMemPos += 2;
+ }
+ for(CHANNELINDEX c = 0; c < GetNumChannels(); c++)
+ {
+ ChnSettings[c].Reset();
+ if(dwMemPos + 1030 < dwMemLength)
+ {
+ ChnSettings[c].nVolume = LittleEndianW(*(uint16 *)(lpStream+dwMemPos)) >> 9;
+ LimitMax(ChnSettings[c].nVolume, uint16(64));
+ dwMemPos += 1030;
+ }
+ }
+ break;
// SUM -> author name (or "Unregistered")
// TMAP
- // TRKS
- case 0x534b5254:
- break;
}
dwMemPos += dwLen;
}
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-12 12:44:10 UTC (rev 3568)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-01-12 18:03:25 UTC (rev 3569)
@@ -28,7 +28,12 @@
// Formats which have 7-bit (0...128) instead of 6-bit (0...64) global volume commands, or which are imported to this range (mostly formats which are converted to IT internally)
-#define GLOBALVOL_7BIT_FORMATS (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_MT2 | MOD_TYPE_IMF | MOD_TYPE_J2B | MOD_TYPE_MID | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DBM | MOD_TYPE_PTM)
+#ifdef MODPLUG_TRACKER
+#define GLOBALVOL_7BIT_FORMATS_EXT (MOD_TYPE_MT2)
+#else
+#define GLOBALVOL_7BIT_FORMATS_EXT 0
+#endif // MODPLUG_TRACKER
+#define GLOBALVOL_7BIT_FORMATS (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_IMF | MOD_TYPE_J2B | MOD_TYPE_MID | MOD_TYPE_AMS | MOD_TYPE_AMS2 | MOD_TYPE_DBM | MOD_TYPE_PTM | GLOBALVOL_7BIT_FORMATS_EXT)
////////////////////////////////////////////////////////////
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-02-01 14:07:04
|
Revision: 3603
http://sourceforge.net/p/modplug/code/3603
Author: manxorist
Date: 2014-02-01 14:06:58 +0000 (Sat, 01 Feb 2014)
Log Message:
-----------
[Fix] Add missing typenames.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/IntMixer.h
trunk/OpenMPT/soundlib/MixerInterface.h
Modified: trunk/OpenMPT/soundlib/IntMixer.h
===================================================================
--- trunk/OpenMPT/soundlib/IntMixer.h 2014-02-01 13:52:36 UTC (rev 3602)
+++ trunk/OpenMPT/soundlib/IntMixer.h 2014-02-01 14:06:58 UTC (rev 3603)
@@ -136,12 +136,12 @@
for(int i = 0; i < Traits::numChannelsIn; i++)
{
- Traits::output_t vol1 =
+ typename Traits::output_t vol1 =
(lut[0] * Traits::Convert(inBuffer[i - 3 * Traits::numChannelsIn]))
+ (lut[1] * Traits::Convert(inBuffer[i - 2 * Traits::numChannelsIn]))
+ (lut[2] * Traits::Convert(inBuffer[i - Traits::numChannelsIn]))
+ (lut[3] * Traits::Convert(inBuffer[i]));
- Traits::output_t vol2 =
+ typename Traits::output_t vol2 =
(lut[4] * Traits::Convert(inBuffer[i + 1 * Traits::numChannelsIn]))
+ (lut[5] * Traits::Convert(inBuffer[i + 2 * Traits::numChannelsIn]))
+ (lut[6] * Traits::Convert(inBuffer[i + 3 * Traits::numChannelsIn]))
Modified: trunk/OpenMPT/soundlib/MixerInterface.h
===================================================================
--- trunk/OpenMPT/soundlib/MixerInterface.h 2014-02-01 13:52:36 UTC (rev 3602)
+++ trunk/OpenMPT/soundlib/MixerInterface.h 2014-02-01 14:06:58 UTC (rev 3603)
@@ -66,7 +66,7 @@
static void SampleLoop(ModChannel &chn, const CResampler &resampler, typename Traits::output_t * MPT_RESTRICT outBuffer, int numSamples)
{
register ModChannel &c = chn;
- const Traits::input_t * MPT_RESTRICT inSample = static_cast<const Traits::input_t *>(c.pCurrentSample) + c.nPos * Traits::numChannelsIn;
+ const typename Traits::input_t * MPT_RESTRICT inSample = static_cast<const typename Traits::input_t *>(c.pCurrentSample) + c.nPos * Traits::numChannelsIn;
int32 smpPos = c.nPosLo; // 16.16 sample position relative to c.nPos
@@ -82,7 +82,7 @@
register int samples = numSamples;
do
{
- Traits::outbuf_t outSample;
+ typename Traits::outbuf_t outSample;
interpolate(outSample, inSample + (smpPos >> 16) * Traits::numChannelsIn, (smpPos & 0xFFFF));
filter(outSample, c);
mix(outSample, c, outBuffer);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-02-01 15:06:06
|
Revision: 3611
http://sourceforge.net/p/modplug/code/3611
Author: manxorist
Date: 2014-02-01 15:05:58 +0000 (Sat, 01 Feb 2014)
Log Message:
-----------
[Ref] m_bChannelMuteTogglePending is not and will not be used in libopenmpt. Guard it with #ifdef MODPLUG_TRACKER.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Sndfile.cpp
trunk/OpenMPT/soundlib/Sndfile.h
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-01 14:56:59 UTC (rev 3610)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-01 15:05:58 UTC (rev 3611)
@@ -615,7 +615,9 @@
m_dwLastSavedWithVersion=0;
m_dwCreatedWithVersion=0;
+#ifdef MODPLUG_TRACKER
m_bChannelMuteTogglePending.reset();
+#endif // MODPLUG_TRACKER
MemsetZero(ChnMix);
MemsetZero(Instruments);
@@ -1309,6 +1311,8 @@
}
+#ifdef MODPLUG_TRACKER
+
void CSoundFile::PatternTranstionChnSolo(const CHANNELINDEX chnIndex)
//-------------------------------------------------------------------
{
@@ -1332,7 +1336,9 @@
}
}
+#endif // MODPLUG_TRACKER
+
void CSoundFile::LoopPattern(PATTERNINDEX nPat, ROWINDEX nRow)
//------------------------------------------------------------
{
@@ -1462,7 +1468,10 @@
GetpModDoc()->Record2Channel(nChn, false);
}
#endif // MODPLUG_TRACKER
+
+#ifdef MODPLUG_TRACKER
m_bChannelMuteTogglePending[nChn] = false;
+#endif // MODPLUG_TRACKER
return false;
}
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2014-02-01 14:56:59 UTC (rev 3610)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2014-02-01 15:05:58 UTC (rev 3611)
@@ -425,7 +425,9 @@
MIDIMacroConfig m_MidiCfg; // MIDI Macro config table
SNDMIXPLUGIN m_MixPlugins[MAX_MIXPLUGINS]; // Mix plugins
char m_szNames[MAX_SAMPLES][MAX_SAMPLENAME]; // Song and sample names
+#ifdef MODPLUG_TRACKER
std::bitset<MAX_BASECHANNELS> m_bChannelMuteTogglePending;
+#endif // MODPLUG_TRACKER
uint32 m_dwCreatedWithVersion;
uint32 m_dwLastSavedWithVersion;
@@ -533,8 +535,11 @@
const CModSpecifications& GetModSpecifications() const {return *m_pModSpecs;}
static const CModSpecifications& GetModSpecifications(const MODTYPE type);
+#ifdef MODPLUG_TRACKER
void PatternTranstionChnSolo(const CHANNELINDEX chnIndex);
void PatternTransitionChnUnmuteAll();
+#endif // MODPLUG_TRACKER
+
double GetCurrentBPM() const;
void DontLoopPattern(PATTERNINDEX nPat, ROWINDEX nRow = 0); //rewbs.playSongFromCursor
CHANNELINDEX GetMixStat() const { return m_nMixStat; }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-03 17:43:40
|
Revision: 3638
http://sourceforge.net/p/modplug/code/3638
Author: saga-games
Date: 2014-02-03 17:43:32 +0000 (Mon, 03 Feb 2014)
Log Message:
-----------
[Mod] XM compatibility: FT2 uses square root pan law. Let's use it in compatible play mode.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Sndmix.cpp
trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp
trunk/OpenMPT/soundlib/SoundFilePlayConfig.h
trunk/OpenMPT/soundlib/Tables.cpp
trunk/OpenMPT/soundlib/Tables.h
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-03 17:00:01 UTC (rev 3637)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-03 17:43:32 UTC (rev 3638)
@@ -1931,6 +1931,17 @@
pChn->newLeftVol = (realvol * (256 - pan)) >> 8;
pChn->newRightVol = (realvol * 128) >> 8;
}
+ } else if(GetType() == MOD_TYPE_XM && m_PlayConfig.getEmulateQuirks())
+ {
+ // FT2 uses square root panning. There is a 257-entry LUT for this,
+ // but FT2's internal panning ranges from 0 to 255 only, meaning that
+ // you can never truly achieve 100% right panning in FT2, only 100% left.
+ // Test case: FT2PanLaw.xm
+ LimitMax(pan, 255);
+ const int panL = pan > 0 ? XMPanningTable[256 - pan] : 65536;
+ const int panR = XMPanningTable[pan];
+ pChn->newLeftVol = (realvol * panL) >> 16;
+ pChn->newRightVol = (realvol * panR) >> 16;
} else
{
pChn->newLeftVol = (realvol * (256 - pan)) >> 8;
Modified: trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp
===================================================================
--- trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp 2014-02-03 17:00:01 UTC (rev 3637)
+++ trunk/OpenMPT/soundlib/SoundFilePlayConfig.cpp 2014-02-03 17:43:32 UTC (rev 3638)
@@ -43,6 +43,7 @@
setNormalVSTiVol(100.0);
setNormalGlobalVol(128.0);
setExtraSampleAttenuation(MIXING_ATTENUATION);
+ setEmulateQuirks(false);
break;
// Ericus' version gives us floats in [-0.06;0.06] and requires attenuation to
@@ -59,6 +60,7 @@
setNormalVSTiVol(100.0);
setNormalGlobalVol(128.0);
setExtraSampleAttenuation(MIXING_ATTENUATION);
+ setEmulateQuirks(false);
break;
// 117RC2 gives us floats in [-1.0; 1.0] and hopefully plays VSTis at
@@ -76,6 +78,7 @@
setNormalVSTiVol(100.0);
setNormalGlobalVol(128.0);
setExtraSampleAttenuation(MIXING_ATTENUATION);
+ setEmulateQuirks(false);
break;
// 117RC3 ignores the horrible global, system-specific pre-amp,
@@ -94,6 +97,7 @@
setNormalVSTiVol(128.0);
setNormalGlobalVol(256.0);
setExtraSampleAttenuation(0);
+ setEmulateQuirks(false);
break;
// A mixmode that is intended to be compatible to legacy trackers (IT/FT2/etc).
@@ -111,166 +115,10 @@
setNormalVSTiVol(256.0);
setNormalGlobalVol(256.0);
setExtraSampleAttenuation(1);
+ setEmulateQuirks(true);
break;
}
return;
}
-
-
-
-//getters and setters.
-bool CSoundFilePlayConfig::getGlobalVolumeAppliesToMaster() const
-//---------------------------------------------------------------
-{
- return m_globalVolumeAppliesToMaster;
-}
-
-
-void CSoundFilePlayConfig::setGlobalVolumeAppliesToMaster(bool inGlobalVolumeAppliesToMaster)
-//-------------------------------------------------------------------------------------------
-{
- m_globalVolumeAppliesToMaster=inGlobalVolumeAppliesToMaster;
-}
-
-float CSoundFilePlayConfig::getVSTiGainFactor() const
-//---------------------------------------------------
-{
- return m_VSTiVolume;
-}
-
-float CSoundFilePlayConfig::getVSTiVolume() const
-//-----------------------------------------------
-{
- return m_VSTiVolume;
-}
-
-void CSoundFilePlayConfig::setVSTiVolume(float inVSTiVolume)
-//-----------------------------------------------------------
-{
- m_VSTiVolume = inVSTiVolume;
-}
-
-float CSoundFilePlayConfig::getVSTiAttenuation() const
-//----------------------------------------------------
-{
- return m_VSTiAttenuation;
-}
-
-void CSoundFilePlayConfig::setVSTiAttenuation(float inVSTiAttenuation)
-//---------------------------------------------------------------------
-{
- m_VSTiAttenuation = inVSTiAttenuation;
-}
-
-float CSoundFilePlayConfig::getIntToFloat() const
-//-----------------------------------------------
-{
- return m_IntToFloat;
-}
-
-void CSoundFilePlayConfig::setIntToFloat(float inIntToFloat)
-//-----------------------------------------------------------
-{
- m_IntToFloat = inIntToFloat;
-}
-
-
-float CSoundFilePlayConfig::getFloatToInt() const
-//-----------------------------------------------
-{
- return m_FloatToInt;
-}
-
-
-void CSoundFilePlayConfig::setFloatToInt(float inFloatToInt)
-//-----------------------------------------------------------
-{
- m_FloatToInt = inFloatToInt;
-}
-
-bool CSoundFilePlayConfig::getUseGlobalPreAmp() const
-//---------------------------------------------------
-{
- return m_ignorePreAmp;
-}
-
-void CSoundFilePlayConfig::setUseGlobalPreAmp(bool inUseGlobalPreAmp)
-//-------------------------------------------------------------------
-{
- m_ignorePreAmp = inUseGlobalPreAmp;
-}
-
-
-forcePanningMode CSoundFilePlayConfig::getForcePanningMode() const
-//----------------------------------------------------------------
-{
- return m_forceSoftPanning;
-}
-
-void CSoundFilePlayConfig::setForcePanningMode(forcePanningMode inForceSoftPanning)
-//---------------------------------------------------------------------------------
-{
- m_forceSoftPanning = inForceSoftPanning;
-}
-
-void CSoundFilePlayConfig::setDisplayDBValues(bool in)
-//----------------------------------------------------
-{
- m_displayDBValues = in;
-}
-
-void CSoundFilePlayConfig::setNormalSamplePreAmp(double in)
-//---------------------------------------------------------
-{
- m_normalSamplePreAmp = in;
-}
-
-void CSoundFilePlayConfig::setNormalVSTiVol(double in)
-//----------------------------------------------------
-{
- m_normalVSTiVol = in;
-}
-
-void CSoundFilePlayConfig::setNormalGlobalVol(double in)
-//------------------------------------------------------
-{
- m_normalGlobalVol = in;
-}
-
-bool CSoundFilePlayConfig::getDisplayDBValues() const
-//---------------------------------------------------
-{
- return m_displayDBValues;
-}
-
-double CSoundFilePlayConfig::getNormalSamplePreAmp() const
-//--------------------------------------------------------
-{
- return m_normalSamplePreAmp;
-}
-
-double CSoundFilePlayConfig::getNormalVSTiVol() const
-//---------------------------------------------------
-{
- return m_normalVSTiVol;
-}
-
-double CSoundFilePlayConfig::getNormalGlobalVol() const
-//-----------------------------------------------------
-{
- return m_normalGlobalVol;
-}
-
-void CSoundFilePlayConfig::setExtraSampleAttenuation(int attn)
-//------------------------------------------------------------
-{
- m_extraAttenuation = attn;
-}
-
-int CSoundFilePlayConfig::getExtraSampleAttenuation() const
-//---------------------------------------------------------
-{
- return m_extraAttenuation;
-}
Modified: trunk/OpenMPT/soundlib/SoundFilePlayConfig.h
===================================================================
--- trunk/OpenMPT/soundlib/SoundFilePlayConfig.h 2014-02-03 17:00:01 UTC (rev 3637)
+++ trunk/OpenMPT/soundlib/SoundFilePlayConfig.h 2014-02-03 17:43:32 UTC (rev 3638)
@@ -49,48 +49,50 @@
void SetMixLevels(int mixLevelType);
//getters/setters
- float getIntToFloat() const;
- void setIntToFloat(float);
- float getFloatToInt() const;
- void setFloatToInt(float);
+ bool getGlobalVolumeAppliesToMaster() const { return m_globalVolumeAppliesToMaster; }
+ void setGlobalVolumeAppliesToMaster(bool inGlobalVolumeAppliesToMaster) { m_globalVolumeAppliesToMaster=inGlobalVolumeAppliesToMaster; }
+ // user-controllable VSTi gain factor.
+ float getVSTiVolume() const { return m_VSTiVolume; }
+ void setVSTiVolume(float inVSTiVolume) { m_VSTiVolume = inVSTiVolume; }
+
// default VSTi gain factor, different depending on the MPT version we're "emulating"
- void setVSTiAttenuation(float);
- float getVSTiAttenuation() const;
+ float getVSTiAttenuation() const { return m_VSTiAttenuation; }
+ void setVSTiAttenuation(float inVSTiAttenuation) { m_VSTiAttenuation = inVSTiAttenuation; }
- // user-controllable VSTi gain factor.
- void setVSTiVolume(float);
- float getVSTiVolume() const;
+ float getIntToFloat() const { return m_IntToFloat; }
+ void setIntToFloat(float inIntToFloat) { m_IntToFloat = inIntToFloat; }
- void setGlobalVolumeAppliesToMaster(bool);
- bool getGlobalVolumeAppliesToMaster() const;
-
- void setUseGlobalPreAmp(bool);
- bool getUseGlobalPreAmp() const;
+ float getFloatToInt() const { return m_FloatToInt; }
+ void setFloatToInt(float inFloatToInt) { m_FloatToInt = inFloatToInt; }
- void setForcePanningMode(forcePanningMode);
- forcePanningMode getForcePanningMode() const;
+ bool getUseGlobalPreAmp() const { return m_ignorePreAmp; }
+ void setUseGlobalPreAmp(bool inUseGlobalPreAmp) { m_ignorePreAmp = inUseGlobalPreAmp; }
- void setDisplayDBValues(bool);
- bool getDisplayDBValues() const;
+ forcePanningMode getForcePanningMode() const { return m_forceSoftPanning; }
+ void setForcePanningMode(forcePanningMode inForceSoftPanning) { m_forceSoftPanning = inForceSoftPanning; }
+ bool getDisplayDBValues() const { return m_displayDBValues; }
+ void setDisplayDBValues(bool in) { m_displayDBValues = in; }
+
+ // Values at which volumes are unchanged
+ double getNormalSamplePreAmp() const { return m_normalSamplePreAmp; }
+ void setNormalSamplePreAmp(double in) { m_normalSamplePreAmp = in; }
+ double getNormalVSTiVol() const { return m_normalVSTiVol; }
+ void setNormalVSTiVol(double in) { m_normalVSTiVol = in; }
+ double getNormalGlobalVol() const { return m_normalGlobalVol; }
+ void setNormalGlobalVol(double in) { m_normalGlobalVol = in; }
+
// Extra sample attenuation in bits
- void setExtraSampleAttenuation(int);
- int getExtraSampleAttenuation() const;
+ int getExtraSampleAttenuation() const { return m_extraAttenuation; }
+ void setExtraSampleAttenuation(int attn) { m_extraAttenuation = attn; }
- //Values at which volumes are unchanged
- double getNormalSamplePreAmp() const;
- double getNormalVSTiVol() const;
- double getNormalGlobalVol() const;
- void setNormalSamplePreAmp(double);
- void setNormalVSTiVol(double);
- void setNormalGlobalVol(double);
+ // True if format-specific mixing quirks should be emulated.
+ bool getEmulateQuirks() const { return m_emualteQuirks; }
+ void setEmulateQuirks(bool emulate) { m_emualteQuirks = emulate; }
-private:
+protected:
-//calculated internally (getters only):
- float getVSTiGainFactor() const;
-
float m_IntToFloat;
float m_FloatToInt;
float m_VSTiAttenuation;
@@ -100,11 +102,11 @@
double m_normalVSTiVol;
double m_normalGlobalVol;
+ int m_extraAttenuation;
+ forcePanningMode m_forceSoftPanning;
bool m_globalVolumeAppliesToMaster;
bool m_ignorePreAmp;
- forcePanningMode m_forceSoftPanning;
bool m_displayDBValues;
-
- int m_extraAttenuation;
+ bool m_emualteQuirks;
};
Modified: trunk/OpenMPT/soundlib/Tables.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Tables.cpp 2014-02-03 17:00:01 UTC (rev 3637)
+++ trunk/OpenMPT/soundlib/Tables.cpp 2014-02-03 17:43:32 UTC (rev 3638)
@@ -675,7 +675,7 @@
// LUT for 2 * damping factor
-const float ITResonanceTable[128] =
+const float ITResonanceTable[128] =
{
1.0000000000000000f, 0.9786446094512940f, 0.9577452540397644f, 0.9372922182083130f,
0.9172759056091309f, 0.8976871371269226f, 0.8785166740417481f, 0.8597555756568909f,
@@ -712,6 +712,29 @@
};
+// FT2's square root panning law LUT.
+// Formula to generate this table: round(65536 * sqrt(n / 256))
+const uint16 XMPanningTable[256] =
+{
+ 0, 4096, 5793, 7094, 8192, 9159, 10033, 10837, 11585, 12288, 12953, 13585, 14189, 14768, 15326, 15864,
+ 16384, 16888, 17378, 17854, 18318, 18770, 19212, 19644, 20066, 20480, 20886, 21283, 21674, 22058, 22435, 22806,
+ 23170, 23530, 23884, 24232, 24576, 24915, 25249, 25580, 25905, 26227, 26545, 26859, 27170, 27477, 27780, 28081,
+ 28378, 28672, 28963, 29251, 29537, 29819, 30099, 30377, 30652, 30924, 31194, 31462, 31727, 31991, 32252, 32511,
+ 32768, 33023, 33276, 33527, 33776, 34024, 34270, 34514, 34756, 34996, 35235, 35472, 35708, 35942, 36175, 36406,
+ 36636, 36864, 37091, 37316, 37540, 37763, 37985, 38205, 38424, 38642, 38858, 39073, 39287, 39500, 39712, 39923,
+ 40132, 40341, 40548, 40755, 40960, 41164, 41368, 41570, 41771, 41972, 42171, 42369, 42567, 42763, 42959, 43154,
+ 43348, 43541, 43733, 43925, 44115, 44305, 44494, 44682, 44869, 45056, 45242, 45427, 45611, 45795, 45977, 46160,
+ 46341, 46522, 46702, 46881, 47059, 47237, 47415, 47591, 47767, 47942, 48117, 48291, 48465, 48637, 48809, 48981,
+ 49152, 49322, 49492, 49661, 49830, 49998, 50166, 50332, 50499, 50665, 50830, 50995, 51159, 51323, 51486, 51649,
+ 51811, 51972, 52134, 52294, 52454, 52614, 52773, 52932, 53090, 53248, 53405, 53562, 53719, 53874, 54030, 54185,
+ 54340, 54494, 54647, 54801, 54954, 55106, 55258, 55410, 55561, 55712, 55862, 56012, 56162, 56311, 56459, 56608,
+ 56756, 56903, 57051, 57198, 57344, 57490, 57636, 57781, 57926, 58071, 58215, 58359, 58503, 58646, 58789, 58931,
+ 59073, 59215, 59357, 59498, 59639, 59779, 59919, 60059, 60199, 60338, 60477, 60615, 60753, 60891, 61029, 61166,
+ 61303, 61440, 61576, 61712, 61848, 61984, 62119, 62254, 62388, 62523, 62657, 62790, 62924, 63057, 63190, 63323,
+ 63455, 63587, 63719, 63850, 63982, 64113, 64243, 64374, 64504, 64634, 64763, 64893, 65022, 65151, 65279, 65408,
+};
+
+
// Reversed sinc coefficients for 4x256 taps polyphase FIR resampling filter
const int16 CResampler::FastSincTable[256*4] =
{ // Cubic Spline
Modified: trunk/OpenMPT/soundlib/Tables.h
===================================================================
--- trunk/OpenMPT/soundlib/Tables.h 2014-02-03 17:00:01 UTC (rev 3637)
+++ trunk/OpenMPT/soundlib/Tables.h 2014-02-03 17:43:32 UTC (rev 3638)
@@ -33,3 +33,4 @@
extern const uint32 LinearSlideUpTable[256];
extern const uint32 LinearSlideDownTable[256];
extern const float ITResonanceTable[128];
+extern const uint16 XMPanningTable[256];
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-05 00:22:14
|
Revision: 3660
http://sourceforge.net/p/modplug/code/3660
Author: saga-games
Date: 2014-02-05 00:22:08 +0000 (Wed, 05 Feb 2014)
Log Message:
-----------
[Ref] Small cleanup in mmcmp code
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Mmcmp.cpp
trunk/OpenMPT/soundlib/Sndfile.cpp
Modified: trunk/OpenMPT/soundlib/Mmcmp.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-02-04 20:24:58 UTC (rev 3659)
+++ trunk/OpenMPT/soundlib/Mmcmp.cpp 2014-02-05 00:22:08 UTC (rev 3660)
@@ -1,7 +1,7 @@
/*
* mmcmp.cpp
* ---------
- * Purpose: Handling of compressed modules (XPK, PowerPack PP20)
+ * Purpose: Handling of compressed modules (MMCMP, XPK, PowerPack PP20)
* Notes : (currently none)
* Authors: Olivier Lapicque
* OpenMPT Devs
@@ -25,8 +25,7 @@
struct PACKED MMCMPFILEHEADER
{
- char id_ziRC[4]; // "ziRC"
- char id_ONia[4]; // "ONia"
+ char id[8]; // "ziRCONia"
uint16 hdrsize;
void ConvertEndianness();
};
@@ -192,8 +191,7 @@
MMCMPFILEHEADER mfh;
if(!file.ReadConvertEndianness(mfh)) return false;
- if(std::memcmp(mfh.id_ziRC, "ziRC", 4) != 0) return false;
- if(std::memcmp(mfh.id_ONia, "ONia", 4) != 0) return false;
+ if(std::memcmp(mfh.id, "ziRCONia", 8) != 0) return false;
if(mfh.hdrsize != sizeof(MMCMPHEADER)) return false;
MMCMPHEADER mmh;
if(!file.ReadConvertEndianness(mmh)) return false;
@@ -445,40 +443,40 @@
static int32 bfextu(const uint8 *p, int32 bo, int32 bc, XPK_BufferBounds &bufs)
//-----------------------------------------------------------------------------
{
- int32 r;
-
- p += bo / 8;
+ int32 r;
+
+ p += bo / 8;
if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error();
- r = *(p++);
- r <<= 8;
+ r = *(p++);
+ r <<= 8;
if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error();
- r |= *(p++);
- r <<= 8;
- r |= *p;
- r <<= bo % 8;
- r &= 0xffffff;
- r >>= 24 - bc;
+ r |= *(p++);
+ r <<= 8;
+ r |= *p;
+ r <<= bo % 8;
+ r &= 0xffffff;
+ r >>= 24 - bc;
- return r;
+ return r;
}
static int32 bfexts(const uint8 *p, int32 bo, int32 bc, XPK_BufferBounds &bufs)
//-----------------------------------------------------------------------------
{
- int32 r;
-
- p += bo / 8;
+ int32 r;
+
+ p += bo / 8;
if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error();
- r = *(p++);
- r <<= 8;
+ r = *(p++);
+ r <<= 8;
if(p < bufs.pSrcBeg || p >= bufs.pSrcEnd) throw XPK_error();
- r |= *(p++);
- r <<= 8;
- r |= *p;
- r <<= (bo % 8) + 8;
- r >>= 32 - bc;
+ r |= *(p++);
+ r <<= 8;
+ r |= *p;
+ r <<= (bo % 8) + 8;
+ r >>= 32 - bc;
- return r;
+ return r;
}
@@ -486,7 +484,7 @@
//------------------------------------------------------------------------------
{
if(len <= 0) return false;
- static uint8 xpk_table[] = {
+ static const uint8 xpk_table[] = {
2,3,4,5,6,7,8,0,3,2,4,5,6,7,8,0,4,3,5,2,6,7,8,0,5,4,6,2,3,7,8,0,6,5,7,2,3,4,8,0,7,6,8,2,3,4,5,0,8,7,6,2,3,4,5,0
};
int32 d0,d1,d2,d3,d4,d5,d6,a2,a5;
@@ -500,7 +498,7 @@
bufs.pSrcEnd = src + srcLen;
bufs.pDstBeg = dst;
bufs.pDstEnd = dst + len;
-
+
c = src;
while (len > 0)
{
@@ -525,7 +523,7 @@
len -= cp;
continue;
}
-
+
if (type != 1)
{
#ifdef MMCMP_LOG
@@ -552,8 +550,8 @@
d5 = 0;
d6 = 8;
goto l734;
-
- l6dc:
+
+ l6dc:
if (bfextu(src,d0,1,bufs)) goto l726;
d0 += 1;
if (! bfextu(src,d0,1,bufs)) goto l75a;
@@ -562,21 +560,21 @@
d6 = 2;
goto l708;
- l6f6:
+ l6f6:
d0 += 1;
if (!bfextu(src,d0,1,bufs)) goto l706;
d6 = bfextu(src,d0,3,bufs);
d0 += 3;
goto l70a;
-
- l706:
+
+ l706:
d6 = 3;
- l708:
+ l708:
d0 += 1;
- l70a:
+ l70a:
d6 = xpk_table[(8*a2) + d6 -17];
if (d6 != 8) goto l730;
- l718:
+ l718:
if (d2 >= 20)
{
d5 = 1;
@@ -585,14 +583,14 @@
d5 = 0;
goto l734;
- l726:
+ l726:
d0 += 1;
d6 = 8;
if (d6 == a2) goto l718;
d6 = a2;
- l730:
+ l730:
d5 = 4;
- l732:
+ l732:
d2 += 8;
l734:
while ((d5 >= 0) && (cup1 > 0))
@@ -608,7 +606,7 @@
}
if (d1 != 31) d1++;
a2 = d6;
- l74c:
+ l74c:
d6 = d2;
d6 >>= 3;
d2 -= d6;
@@ -616,25 +614,25 @@
}
return true;
-l75a:
+l75a:
d0 += 1;
if (bfextu(src,d0,1,bufs)) goto l766;
d4 = 2;
goto l79e;
-
-l766:
+
+l766:
d0 += 1;
if (bfextu(src,d0,1,bufs)) goto l772;
d4 = 4;
goto l79e;
-l772:
+l772:
d0 += 1;
if (bfextu(src,d0,1,bufs)) goto l77e;
d4 = 6;
goto l79e;
-l77e:
+l77e:
d0 += 1;
if (bfextu(src,d0,1,bufs)) goto l792;
d0 += 1;
@@ -642,14 +640,14 @@
d0 += 3;
d6 += 8;
goto l7a8;
-
-l792:
+
+l792:
d0 += 1;
d6 = bfextu(src,d0,5,bufs);
d0 += 5;
d4 = 16;
goto l7a6;
-
+
l79e:
d0 += 1;
d6 = bfextu(src,d0,1,bufs);
@@ -685,7 +683,7 @@
}
d6 += 2;
phist = dst + a5 - d4 - 1;
-
+
while ((d6 >= 0) && (cup1 > 0))
{
if(phist < bufs.pDstBeg || phist >= bufs.pDstEnd) throw XPK_error();
@@ -767,8 +765,8 @@
result = (result<<1) | (bitbuffer&1);
bitbuffer >>= 1;
bitcount--;
- }
- return result;
+ }
+ return result;
}
@@ -850,4 +848,3 @@
return result;
}
-
Modified: trunk/OpenMPT/soundlib/Sndfile.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-04 20:24:58 UTC (rev 3659)
+++ trunk/OpenMPT/soundlib/Sndfile.cpp 2014-02-05 00:22:08 UTC (rev 3660)
@@ -748,16 +748,11 @@
if(file.IsValid())
{
- LPCBYTE lpStream = reinterpret_cast<const unsigned char*>(file.GetRawData());
- DWORD dwMemLength = file.GetLength();
-
#ifndef NO_ARCHIVE_SUPPORT
CUnarchiver unarchiver(file);
if(unarchiver.ExtractBestFile(GetSupportedExtensions(true)))
{
file = unarchiver.GetOutputFile();
- lpStream = (LPCBYTE)file.GetRawData();
- dwMemLength = file.GetLength();
}
#endif
@@ -769,10 +764,11 @@
if(packedContainerType != MOD_CONTAINERTYPE_NONE)
{
file = FileReader(&(unpackedData[0]), unpackedData.size());
- lpStream = (LPCBYTE)file.GetRawData();
- dwMemLength = file.GetLength();
}
+ LPCBYTE lpStream = reinterpret_cast<const unsigned char*>(file.GetRawData());
+ DWORD dwMemLength = file.GetLength();
+
if(!ReadXM(file, loadFlags)
// -> CODE#0023
// -> DESC="IT project files (.itp)"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-07 18:43:28
|
Revision: 3670
http://sourceforge.net/p/modplug/code/3670
Author: saga-games
Date: 2014-02-07 18:43:19 +0000 (Fri, 07 Feb 2014)
Log Message:
-----------
[Fix] IT compatibilty: Panbrello random waveform takes speed parameter into account now (test case: RandomWaveform.it)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ModChannel.h
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/soundlib/ModChannel.h
===================================================================
--- trunk/OpenMPT/soundlib/ModChannel.h 2014-02-07 16:12:51 UTC (rev 3669)
+++ trunk/OpenMPT/soundlib/ModChannel.h 2014-02-07 18:43:19 UTC (rev 3670)
@@ -96,6 +96,7 @@
uint8 nVibratoType, nVibratoSpeed, nVibratoDepth;
uint8 nTremoloType, nTremoloSpeed, nTremoloDepth;
uint8 nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth;
+ int8 nPanbrelloRandomMemory;
uint8 nOldCmdEx, nOldVolParam, nOldTempo;
uint8 nOldOffset, nOldHiOffset;
uint8 nCutOff, nResonance;
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-07 16:12:51 UTC (rev 3669)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-07 18:43:19 UTC (rev 3670)
@@ -565,31 +565,35 @@
int CSoundFile::GetVibratoDelta(int type, int position) const
//-----------------------------------------------------------
{
- switch(type & 0x03)
+ // IT compatibility: IT has its own, more precise tables
+ if(IsCompatibleMode(TRK_IMPULSETRACKER))
{
- case 0:
- default:
- // IT compatibility: IT has its own, more precise tables
- return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITSinusTable[position] : ModSinusTable[position];
-
- case 1:
- // IT compatibility: IT has its own, more precise tables
- return IsCompatibleMode(TRK_IMPULSETRACKER) ? ITRampDownTable[position] : ModRampDownTable[position];
-
- case 2:
- // IT compatibility: IT has its own, more precise tables
- if(IsCompatibleMode(TRK_IMPULSETRACKER))
+ switch(type & 0x03)
+ {
+ case 0:
+ default:
+ return ITSinusTable[position];
+ case 1:
+ return ITRampDownTable[position];
+ case 2:
return position < 128 ? 64 : 0;
- else
+ case 3:
+ return (rand() & 0x7F) - 0x40;
+ }
+ } else
+ {
+ switch(type & 0x03)
+ {
+ case 0:
+ default:
+ return ModSinusTable[position];
+ case 1:
+ return ModRampDownTable[position];
+ case 2:
return position < 32 ? 127 : -127;
-
- case 3:
- //IT compatibility 19. Use random values
- if(IsCompatibleMode(TRK_IMPULSETRACKER))
- // TODO delay is not taken into account!
- return (rand() & 0x7F) - 0x40;
- else
+ case 3:
return ModRandomTable[position];
+ }
}
}
@@ -1070,7 +1074,7 @@
{
if(pChn->dwFlags[CHN_PANBRELLO])
{
- UINT panpos;
+ uint32 panpos;
// IT compatibility: IT has its own, more precise tables
if(IsCompatibleMode(TRK_IMPULSETRACKER))
panpos = pChn->nPanbrelloPos & 0xFF;
@@ -1079,7 +1083,22 @@
int pdelta = GetVibratoDelta(pChn->nPanbrelloType, panpos);
- pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
+ // IT compatibility: Sample-and-hold style random panbrello (tremolo and vibrato don't use this mechanism in IT)
+ // Test case: RandomWaveform.it
+ if(IsCompatibleMode(TRK_IMPULSETRACKER) && pChn->nPanbrelloType == 3)
+ {
+ if(pChn->nPanbrelloPos == 0 || pChn->nPanbrelloPos >= pChn->nPanbrelloSpeed)
+ {
+ pChn->nPanbrelloPos = 0;
+ pChn->nPanbrelloRandomMemory = static_cast<int8>(pdelta);
+ }
+ pChn->nPanbrelloPos++;
+ pdelta = pChn->nPanbrelloRandomMemory;
+ } else
+ {
+ pChn->nPanbrelloPos += pChn->nPanbrelloSpeed;
+ }
+
pdelta = ((pdelta * (int)pChn->nPanbrelloDepth) + 2) >> 3;
pdelta += pChn->nRealPan;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-12 22:17:34
|
Revision: 3708
http://sourceforge.net/p/modplug/code/3708
Author: saga-games
Date: 2014-02-12 22:17:26 +0000 (Wed, 12 Feb 2014)
Log Message:
-----------
[New] Implemented arpeggio effect for instrument plugins. Implementation is subject to change until the next official release.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ModChannel.h
trunk/OpenMPT/soundlib/Snd_fx.cpp
trunk/OpenMPT/soundlib/Sndfile.h
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/soundlib/ModChannel.h
===================================================================
--- trunk/OpenMPT/soundlib/ModChannel.h 2014-02-12 17:23:45 UTC (rev 3707)
+++ trunk/OpenMPT/soundlib/ModChannel.h 2014-02-12 22:17:26 UTC (rev 3708)
@@ -89,6 +89,7 @@
uint8 nRestoreCutoffOnNewNote; //Like above
uint8 nNote, nNNA;
uint8 nLastNote; // Last note, ignoring note offs and cuts - for MIDI macros
+ uint8 nArpeggioLastNote, nArpeggioBaseNote; // For plugin arpeggio
uint8 nNewNote, nNewIns, nOldIns, nCommand, nArpeggio;
uint8 nOldVolumeSlide, nOldFineVolUpDown;
uint8 nOldPortaUpDown, nOldFinePortaUpDown, nOldExtraFinePortaUpDown;
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-12 17:23:45 UTC (rev 3707)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-02-12 22:17:26 UTC (rev 3708)
@@ -2344,7 +2344,10 @@
// Arpeggio
case CMD_ARPEGGIO:
// IT compatibility 01. Don't ignore Arpeggio if no note is playing (also valid for ST3)
- if ((m_nTickCount) || (((!pChn->nPeriod) || !pChn->nNote) && !IsCompatibleMode(TRK_IMPULSETRACKER | TRK_SCREAMTRACKER))) break;
+ if(m_nTickCount) break;
+ if((!pChn->nPeriod || !pChn->nNote)
+ && (pChn->pModInstrument == nullptr || !pChn->pModInstrument->HasValidMIDIChannel()) // Plugin arpeggio
+ && !IsCompatibleMode(TRK_IMPULSETRACKER | TRK_SCREAMTRACKER)) break;
if ((!param) && (!(GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)))) break; // Only important when editing MOD/XM files
pChn->nCommand = CMD_ARPEGGIO;
if (param) pChn->nArpeggio = param;
@@ -4119,7 +4122,7 @@
{
// Not an internal device. Pass on to appropriate plugin.
const CHANNELINDEX plugChannel = (nChn < GetNumChannels()) ? nChn + 1 : pChn->nMasterChn;
- if(plugChannel > 0 && plugChannel <= GetNumChannels()) // XXX do we need this? I guess it might be relevant for previewing notes in the pattern...
+ if(plugChannel > 0 && plugChannel <= GetNumChannels()) // XXX do we need this? I guess it might be relevant for previewing notes in the pattern... Or when using this mechanism for volume/panning!
{
PLUGINDEX nPlug = 0;
if(!pChn->dwFlags[CHN_NOFX])
Modified: trunk/OpenMPT/soundlib/Sndfile.h
===================================================================
--- trunk/OpenMPT/soundlib/Sndfile.h 2014-02-12 17:23:45 UTC (rev 3707)
+++ trunk/OpenMPT/soundlib/Sndfile.h 2014-02-12 22:17:26 UTC (rev 3708)
@@ -729,7 +729,7 @@
void ProcessPitchPanSeparation(ModChannel *pChn);
void ProcessPanbrello(ModChannel *pChn);
- void ProcessArpeggio(ModChannel *pChn, int &period, CTuning::NOTEINDEXTYPE &arpeggioSteps);
+ void ProcessArpeggio(CHANNELINDEX nChn, int &period, CTuning::NOTEINDEXTYPE &arpeggioSteps);
void ProcessVibrato(CHANNELINDEX nChn, int &period, CTuning::RATIOTYPE &vibratoFactor);
void ProcessSampleAutoVibrato(ModChannel *pChn, int &period, CTuning::RATIOTYPE &vibratoFactor, int &nPeriodFrac);
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-12 17:23:45 UTC (rev 3707)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-12 22:17:26 UTC (rev 3708)
@@ -521,7 +521,6 @@
}
// Should we process tick0 effects?
if (!m_nMusicSpeed) m_nMusicSpeed = 1;
- m_SongFlags.set(SONG_FIRSTTICK);
//End of row? stop pattern step (aka "play row").
#ifdef MODPLUG_TRACKER
@@ -549,6 +548,7 @@
}
} else
{
+ m_SongFlags.set(SONG_FIRSTTICK);
m_SongFlags.reset(SONG_BREAKTOROW);
}
@@ -1108,51 +1108,54 @@
}
-void CSoundFile::ProcessArpeggio(ModChannel *pChn, int &period, CTuning::NOTEINDEXTYPE &arpeggioSteps)
-//----------------------------------------------------------------------------------------------------
+void CSoundFile::ProcessArpeggio(CHANNELINDEX nChn, int &period, CTuning::NOTEINDEXTYPE &arpeggioSteps)
+//-----------------------------------------------------------------------------------------------------
{
- if (pChn->nCommand == CMD_ARPEGGIO)
+ ModChannel *pChn = &Chn[nChn];
+
+#ifndef NO_VST
+ // Plugin arpeggio
+ if(pChn->pModInstrument && pChn->pModInstrument->nMixPlug)
{
-#ifndef NO_VST
-#if 0
- // EXPERIMENTAL VSTi arpeggio. Far from perfect!
- // Note: We could use pChn->nLastNote here to simplify things.
- if(pChn->pModInstrument && pChn->pModInstrument->nMixPlug && !m_SongFlags[SONG_FIRSTTICK])
+ const ModInstrument *pIns = pChn->pModInstrument;
+ IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin;
+ if(pPlugin)
{
- const ModInstrument *pIns = pChn->pModInstrument;
- IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin;
- if(pPlugin)
+ uint8 step = 0;
+ const bool arpOnRow = (pChn->rowCommand.command == CMD_ARPEGGIO);
+ if(arpOnRow)
{
- // Temporary logic: This ensures that the first and last tick are both playing the base note.
- int nCount = (int)m_nTickCount - (int)(m_nMusicSpeed * (m_nPatternDelay + 1) + m_nFrameDelay - 1);
- int nStep = 0, nLastStep = 0;
- nCount = -nCount;
- switch(nCount % 3)
+ switch(m_nTickCount % 3)
{
- case 0:
- nStep = 0;
- nLastStep = pChn->nArpeggio & 0x0F;
- break;
- case 1:
- nStep = pChn->nArpeggio >> 4;
- nLastStep = 0;
- break;
- case 2:
- nStep = pChn->nArpeggio & 0x0F;
- nLastStep = pChn->nArpeggio >> 4;
- break;
+ case 1: step = pChn->nArpeggio >> 4; break;
+ case 2: step = pChn->nArpeggio & 0x0F; break;
}
- // First tick is always 0
- if(m_nTickCount == 1)
- nLastStep = 0;
+ pChn->nArpeggioBaseNote = pChn->nLastNote;
+ }
- pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, pChn->nNote + nStep, pChn->nVolume, nChn);
- pPlugin->MidiCommand(pIns->nMidiChannel, pIns->nMidiProgram, pIns->wMidiBank, pChn->nNote + nLastStep + NOTE_KEYOFF, 0, nChn);
- }
+ // Trigger new note:
+ // - If there's an arpeggio on this row and
+ // - the note to trigger is not the same as the previous arpeggio note or
+ // - a pattern note has just been triggered on this tick
+ // - If there's no arpeggio
+ // - but an arpeggio note is still active and
+ // - there's no note stop or new note that would stop it anyway
+ if((arpOnRow && pChn->nArpeggioLastNote != pChn->nArpeggioBaseNote + step && (!m_SongFlags[SONG_FIRSTTICK] || !pChn->rowCommand.IsNote()))
+ || (!arpOnRow && pChn->rowCommand.note == NOTE_NONE && pChn->nArpeggioLastNote != NOTE_NONE))
+ pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, pChn->nArpeggioBaseNote + step, static_cast<uint16>(pChn->nVolume), nChn);
+ if(pChn->nArpeggioLastNote != NOTE_NONE)
+ pPlugin->MidiCommand(GetBestMidiChannel(nChn), pIns->nMidiProgram, pIns->wMidiBank, pChn->nArpeggioLastNote + NOTE_MAX_SPECIAL, 0, nChn);
+
+ if(pChn->rowCommand.command == CMD_ARPEGGIO)
+ pChn->nArpeggioLastNote = pChn->nArpeggioBaseNote + step;
+ else
+ pChn->nArpeggioLastNote = NOTE_NONE;
}
-#endif // 0
+ }
#endif // NO_VST
+ if(pChn->nCommand == CMD_ARPEGGIO)
+ {
if((GetType() & MOD_TYPE_MPT) && pChn->pModInstrument && pChn->pModInstrument->pTuning)
{
switch(m_nTickCount % 3)
@@ -1764,7 +1767,7 @@
period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC5Speed);
}
- ProcessArpeggio(pChn, period, arpeggioSteps);
+ ProcessArpeggio(nChn, period, arpeggioSteps);
// Preserve Amiga freq limits.
// In ST3, the frequency is always clamped to periods 113 to 856, while in ProTracker,
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-18 19:11:38
|
Revision: 3735
http://sourceforge.net/p/modplug/code/3735
Author: saga-games
Date: 2014-02-18 19:11:29 +0000 (Tue, 18 Feb 2014)
Log Message:
-----------
[Fix] Disabling a sustain loop could disable normal loops.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ModSample.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
Modified: trunk/OpenMPT/soundlib/ModSample.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ModSample.cpp 2014-02-18 18:55:50 UTC (rev 3734)
+++ trunk/OpenMPT/soundlib/ModSample.cpp 2014-02-18 19:11:29 UTC (rev 3735)
@@ -241,7 +241,7 @@
uFlags.set(CHN_PINGPONGSUSTAIN, pingpong && enable);
} else
{
- nLoopStart = nLoopEnd = 0;
+ nSustainStart = nSustainEnd = 0;
uFlags.reset(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN);
}
PrecomputeLoops(sndFile, true);
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-18 18:55:50 UTC (rev 3734)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-02-18 19:11:29 UTC (rev 3735)
@@ -210,7 +210,6 @@
void PrecomputeLoopsImpl(ModSample &smp, const CSoundFile &sndFile)
//-----------------------------------------------------------------
{
- smp.SanitizeLoops();
const int numChannels = smp.GetNumChannels();
const int copySamples = numChannels * InterpolationMaxLookahead;
// Optimization: Put normal loop wraparound buffer right at the sample end if the normal loop ends there.
@@ -262,6 +261,8 @@
if(smp.nLength == 0 || smp.pSample == nullptr)
return false;
+ smp.SanitizeLoops();
+
// Update channels with possibly changed loop values
if(updateChannels)
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-02-18 20:42:17
|
Revision: 3737
http://sourceforge.net/p/modplug/code/3737
Author: manxorist
Date: 2014-02-18 20:42:09 +0000 (Tue, 18 Feb 2014)
Log Message:
-----------
[Fix] Fix signed integer overflow in IT sample decompression integrator (found with clang sanitizer).
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ITCompression.cpp
trunk/OpenMPT/soundlib/ITCompression.h
Modified: trunk/OpenMPT/soundlib/ITCompression.cpp
===================================================================
--- trunk/OpenMPT/soundlib/ITCompression.cpp 2014-02-18 19:18:18 UTC (rev 3736)
+++ trunk/OpenMPT/soundlib/ITCompression.cpp 2014-02-18 20:42:09 UTC (rev 3737)
@@ -426,7 +426,7 @@
v -= (topBit << 1);
mem1 += v;
mem2 += mem1;
- static_cast<typename Properties::sample_t *>(target)[writePos] = static_cast<typename Properties::sample_t>(is215 ? mem2 : mem1);
+ static_cast<typename Properties::sample_t *>(target)[writePos] = static_cast<typename Properties::sample_t>(is215 ? (int)mem2 : (int)mem1);
writtenSamples++;
writePos += mptSample.GetNumChannels();
curLength--;
Modified: trunk/OpenMPT/soundlib/ITCompression.h
===================================================================
--- trunk/OpenMPT/soundlib/ITCompression.h 2014-02-18 19:18:18 UTC (rev 3736)
+++ trunk/OpenMPT/soundlib/ITCompression.h 2014-02-18 20:42:09 UTC (rev 3737)
@@ -80,7 +80,7 @@
SmpLength writePos; // Absolut write position in sample (for stereo samples)
SmpLength curLength; // Length of currently processed block
FileReader::off_t dataPos; // Position in input block
- int mem1, mem2; // Integrator memory
+ unsigned int mem1, mem2; // Integrator memory
// Bit reader
int bitPos; // Current bit position in this byte
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-02-18 20:53:15
|
Revision: 3738
http://sourceforge.net/p/modplug/code/3738
Author: manxorist
Date: 2014-02-18 20:53:06 +0000 (Tue, 18 Feb 2014)
Log Message:
-----------
[Fix] Taking references or pointers (of non-packed type) to members of packed structures is not allowed and causes unaligned memory access later on. Avoid it in XM instrument I/O code by passing an envelope type enum and accessing the packed envelope data directly depending on which envelope is selected. (found with clang sanitizer)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/XMTools.cpp
trunk/OpenMPT/soundlib/XMTools.h
Modified: trunk/OpenMPT/soundlib/XMTools.cpp
===================================================================
--- trunk/OpenMPT/soundlib/XMTools.cpp 2014-02-18 20:42:09 UTC (rev 3737)
+++ trunk/OpenMPT/soundlib/XMTools.cpp 2014-02-18 20:53:06 UTC (rev 3738)
@@ -49,16 +49,25 @@
// Convert OpenMPT's internal envelope representation to XM envelope data.
-void XMInstrument::ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, uint16 *envData)
-//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+void XMInstrument::ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, EnvType env)
+//---------------------------------------------------------------------------------------------------------------------------------------------------------------------
{
numPoints = static_cast<uint8>(std::min(12u, mptEnv.nNodes));
// Envelope Data
for(size_t i = 0; i < numPoints; i++)
{
- envData[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
- envData[i * 2 + 1] = mptEnv.Values[i];
+ switch(env)
+ {
+ case EnvTypeVol:
+ volEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
+ volEnv[i * 2 + 1] = mptEnv.Values[i];
+ break;
+ case EnvTypePan:
+ panEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
+ panEnv[i * 2 + 1] = mptEnv.Values[i];
+ break;
+ }
}
// Envelope Flags
@@ -84,8 +93,8 @@
volFade = static_cast<uint16>(std::min(mptIns.nFadeOut, uint32(32767)));
// Convert envelopes
- ConvertEnvelopeToXM(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, volEnv);
- ConvertEnvelopeToXM(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, panEnv);
+ ConvertEnvelopeToXM(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol);
+ ConvertEnvelopeToXM(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan);
// Create sample assignment table
std::vector<SAMPLEINDEX> sampleList = GetSampleList(mptIns, compatibilityExport);
@@ -146,16 +155,25 @@
// Convert XM envelope data to an OpenMPT's internal envelope representation.
-void XMInstrument::ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, const uint16 (&envData)[24]) const
-//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+void XMInstrument::ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
{
mptEnv.nNodes = MIN(numPoints, 12);
// Envelope Data
for(size_t i = 0; i < 12; i++)
{
- mptEnv.Ticks[i] = envData[i * 2];
- mptEnv.Values[i] = static_cast<uint8>(envData[i * 2 + 1]);
+ switch(env)
+ {
+ case EnvTypeVol:
+ mptEnv.Ticks[i] = volEnv[i * 2];
+ mptEnv.Values[i] = static_cast<uint8>(volEnv[i * 2 + 1]);
+ break;
+ case EnvTypePan:
+ mptEnv.Ticks[i] = panEnv[i * 2];
+ mptEnv.Values[i] = static_cast<uint8>(panEnv[i * 2 + 1]);
+ break;
+ }
if(i > 0 && mptEnv.Ticks[i] < mptEnv.Ticks[i - 1])
{
@@ -199,8 +217,8 @@
mptIns.nFadeOut = volFade;
// Convert envelopes
- ConvertEnvelopeToMPT(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, volEnv);
- ConvertEnvelopeToMPT(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, panEnv);
+ ConvertEnvelopeToMPT(mptIns.VolEnv, volPoints, volFlags, volSustain, volLoopStart, volLoopEnd, EnvTypeVol);
+ ConvertEnvelopeToMPT(mptIns.PanEnv, panPoints, panFlags, panSustain, panLoopStart, panLoopEnd, EnvTypePan);
// Create sample assignment table
for(size_t i = 0; i < CountOf(sampleMap); i++)
Modified: trunk/OpenMPT/soundlib/XMTools.h
===================================================================
--- trunk/OpenMPT/soundlib/XMTools.h 2014-02-18 20:42:09 UTC (rev 3737)
+++ trunk/OpenMPT/soundlib/XMTools.h 2014-02-18 20:53:06 UTC (rev 3738)
@@ -85,10 +85,15 @@
// Convert all multi-byte numeric values to current platform's endianness or vice versa.
void ConvertEndianness();
+ enum EnvType
+ {
+ EnvTypeVol,
+ EnvTypePan,
+ };
// Convert OpenMPT's internal envelope representation to XM envelope data.
- void ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, uint16 *envData);
+ void ConvertEnvelopeToXM(const InstrumentEnvelope &mptEnv, uint8 &numPoints, uint8 &flags, uint8 &sustain, uint8 &loopStart, uint8 &loopEnd, EnvType env);
// Convert XM envelope data to an OpenMPT's internal envelope representation.
- void ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, const uint16 (&envData)[24]) const;
+ void ConvertEnvelopeToMPT(InstrumentEnvelope &mptEnv, uint8 numPoints, uint8 flags, uint8 sustain, uint8 loopStart, uint8 loopEnd, EnvType env) const;
// Convert OpenMPT's internal sample representation to an XMInstrument.
uint16 ConvertToXM(const ModInstrument &mptIns, bool compatibilityExport);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-02-23 18:49:24
|
Revision: 3762
http://sourceforge.net/p/modplug/code/3762
Author: manxorist
Date: 2014-02-23 18:49:17 +0000 (Sun, 23 Feb 2014)
Log Message:
-----------
[Ref] Silence some clang 3.3 warnings.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/MIDIMacros.cpp
trunk/OpenMPT/soundlib/SampleIO.cpp
Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp
===================================================================
--- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2014-02-23 17:52:33 UTC (rev 3761)
+++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2014-02-23 18:49:17 UTC (rev 3762)
@@ -80,8 +80,12 @@
#pragma GCC diagnostic ignored "-Wswitch"
#elif MPT_COMPILER_CLANG
#pragma clang diagnostic push
+#if MPT_CLANG_AT_LEAST(3,3,0)
+#pragma clang diagnostic ignored "-Wswitch"
+#else
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
+#endif
void MIDIMacroConfig::CreateParameteredMacro(char (¶meteredMacro)[MACRO_LENGTH], parameteredMacroType macroType, int subType) const
//-------------------------------------------------------------------------------------------------------------------------------------
@@ -134,8 +138,12 @@
#pragma GCC diagnostic ignored "-Wswitch"
#elif MPT_COMPILER_CLANG
#pragma clang diagnostic push
+#if MPT_CLANG_AT_LEAST(3,3,0)
+#pragma clang diagnostic ignored "-Wswitch"
+#else
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
+#endif
// Create Zxx (Z80 - ZFF) from one out of five presets
void MIDIMacroConfig::CreateFixedMacro(char (&fixedMacros)[128][MACRO_LENGTH], fixedMacroType macroType) const
Modified: trunk/OpenMPT/soundlib/SampleIO.cpp
===================================================================
--- trunk/OpenMPT/soundlib/SampleIO.cpp 2014-02-23 17:52:33 UTC (rev 3761)
+++ trunk/OpenMPT/soundlib/SampleIO.cpp 2014-02-23 18:49:17 UTC (rev 3762)
@@ -30,8 +30,12 @@
#pragma GCC diagnostic ignored "-Wswitch"
#elif MPT_COMPILER_CLANG
#pragma clang diagnostic push
+#if MPT_CLANG_AT_LEAST(3,3,0)
+#pragma clang diagnostic ignored "-Wswitch"
+#else
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
+#endif
// Read a sample from memory
size_t SampleIO::ReadSample(ModSample &sample, FileReader &file) const
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-02-28 23:46:56
|
Revision: 3800
http://sourceforge.net/p/modplug/code/3800
Author: saga-games
Date: 2014-02-28 23:46:47 +0000 (Fri, 28 Feb 2014)
Log Message:
-----------
[Fix] FT2 compatibility: Output period should be clamped to 1...31999 (very theoretical range that should only be exceeded with overflowing portamentos)
[Fix] Compatibility mode: Glissando should now behave more as one expects it to behave and not reset after portamentos.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/ModChannel.h
trunk/OpenMPT/soundlib/Sndmix.cpp
Modified: trunk/OpenMPT/soundlib/ModChannel.h
===================================================================
--- trunk/OpenMPT/soundlib/ModChannel.h 2014-02-28 23:45:24 UTC (rev 3799)
+++ trunk/OpenMPT/soundlib/ModChannel.h 2014-02-28 23:46:47 UTC (rev 3800)
@@ -68,6 +68,7 @@
int32 nRealVolume, nRealPan;
int32 nVolume, nPan, nFadeOutVol;
int32 nPeriod, nC5Speed, nPortamentoDest;
+ int32 cachedPeriod, glissandoPeriod;
int32 nCalcVolume; // Calculated channel volume, 14-Bit (without global volume, pre-amp etc applied) - for MIDI macros
EnvInfo VolEnv, PanEnv, PitchEnv; // Envelope playback info
int32 nGlobalVol; // Channel volume (CV in ITTECH.TXT)
Modified: trunk/OpenMPT/soundlib/Sndmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-28 23:45:24 UTC (rev 3799)
+++ trunk/OpenMPT/soundlib/Sndmix.cpp 2014-02-28 23:46:47 UTC (rev 3800)
@@ -1812,11 +1812,20 @@
pChn->nCalcVolume = vol; // Update calculated volume for MIDI macros
if (pChn->nPeriod < m_nMinPeriod) pChn->nPeriod = m_nMinPeriod;
+ if(IsCompatibleMode(TRK_FASTTRACKER2)) Clamp(pChn->nPeriod, 1, 31999);
period = pChn->nPeriod;
- // TODO Glissando effect is reset after portamento! What would this sound like without the CHN_PORTAMENTO flag?
- if((pChn->dwFlags & (CHN_GLISSANDO | CHN_PORTAMENTO)) == (CHN_GLISSANDO | CHN_PORTAMENTO))
+
+ // When glissando mode is set to semitones, clamp to the next halftone.
+ if((pChn->dwFlags[CHN_GLISSANDO] && IsCompatibleMode(TRK_ALLTRACKERS))
+ || ((pChn->dwFlags & (CHN_GLISSANDO | CHN_PORTAMENTO)) == (CHN_GLISSANDO | CHN_PORTAMENTO) && !IsCompatibleMode(TRK_ALLTRACKERS)))
{
- period = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC5Speed);
+ if(period != pChn->cachedPeriod)
+ {
+ // Only recompute this whole thing in case the base period has changed.
+ pChn->cachedPeriod = period;
+ pChn->glissandoPeriod = GetPeriodFromNote(GetNoteFromPeriod(period), pChn->nFineTune, pChn->nC5Speed);
+ }
+ period = pChn->glissandoPeriod;
}
ProcessArpeggio(nChn, period, arpeggioSteps);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-03-03 21:48:57
|
Revision: 3820
http://sourceforge.net/p/modplug/code/3820
Author: saga-games
Date: 2014-03-03 21:48:49 +0000 (Mon, 03 Mar 2014)
Log Message:
-----------
[Fix] Soundfont import: Loops were not pre-computed correctly.
[Fix] Sample sync on seek broke panning.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Dlsbank.cpp
trunk/OpenMPT/soundlib/Snd_fx.cpp
Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Dlsbank.cpp 2014-03-03 21:02:26 UTC (rev 3819)
+++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2014-03-03 21:48:49 UTC (rev 3820)
@@ -1560,7 +1560,6 @@
SampleIO::littleEndian,
SampleIO::signedPCM)
.ReadSample(sample, chunk);
- sample.PrecomputeLoops(sndFile, false);
}
bWaveForm = (sample.pSample) ? TRUE : FALSE;
} else
@@ -1654,6 +1653,7 @@
}
if (pDlsIns->szName[0]) memcpy(sndFile.m_szNames[nSample], pDlsIns->szName, MAX_SAMPLENAME - 1);
sample.Convert(MOD_TYPE_IT, sndFile.GetType());
+ sample.PrecomputeLoops(sndFile, false);
bOk = TRUE;
}
FreeWaveForm(pWaveForm);
Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-03-03 21:02:26 UTC (rev 3819)
+++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2014-03-03 21:48:49 UTC (rev 3820)
@@ -611,7 +611,7 @@
} else if(((p->command == CMD_MODCMDEX) || (p->command == CMD_S3MCMDEX)) && (p->param & 0xF0) == 0x80)
{
Panning(pChn, ((p->param & 0x0F) * 256 + 8) / 15);
- } else if(p->command == VOLCMD_PANNING)
+ } else if(p->volcmd == VOLCMD_PANNING)
{
pChn->nPan = p->vol * 4;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-03-04 19:14:10
|
Revision: 3826
http://sourceforge.net/p/modplug/code/3826
Author: manxorist
Date: 2014-03-04 19:14:01 +0000 (Tue, 04 Mar 2014)
Log Message:
-----------
[Ref] Add missing #ifndef MODPLUG_NO_FILESAVE in tuningCollection.* .
Modified Paths:
--------------
trunk/OpenMPT/soundlib/tuningCollection.cpp
trunk/OpenMPT/soundlib/tuningcollection.h
Modified: trunk/OpenMPT/soundlib/tuningCollection.cpp
===================================================================
--- trunk/OpenMPT/soundlib/tuningCollection.cpp 2014-03-04 16:20:21 UTC (rev 3825)
+++ trunk/OpenMPT/soundlib/tuningCollection.cpp 2014-03-04 19:14:01 UTC (rev 3826)
@@ -119,6 +119,8 @@
}
+#ifndef MODPLUG_NO_FILESAVE
+
CTuningCollection::SERIALIZATION_RETURN_TYPE CTuningCollection::Serialize() const
//-------------------------------------------------------------------------------
{
@@ -149,7 +151,9 @@
return SERIALIZATION_SUCCESS;
}
+#endif // MODPLUG_NO_FILESAVE
+
CTuningCollection::SERIALIZATION_RETURN_TYPE CTuningCollection::Deserialize(std::istream& iStrm)
//----------------------------------------------------------------------------------------------
{
Modified: trunk/OpenMPT/soundlib/tuningcollection.h
===================================================================
--- trunk/OpenMPT/soundlib/tuningcollection.h 2014-03-04 16:20:21 UTC (rev 3825)
+++ trunk/OpenMPT/soundlib/tuningcollection.h 2014-03-04 19:14:01 UTC (rev 3826)
@@ -95,8 +95,10 @@
std::string GetName() const {return m_Name;}
+#ifndef MODPLUG_NO_FILESAVE
void SetSavefilePath(const mpt::PathString &psz) {m_SavefilePath = psz;}
mpt::PathString GetSaveFilePath() const {return m_SavefilePath;}
+#endif // MODPLUG_NO_FILESAVE
std::string GetVersionString() const {return Stringify(static_cast<int>(s_SerializationVersion));}
@@ -104,9 +106,11 @@
//Serialization/unserialisation
bool Serialize(std::ostream&) const;
+ bool Deserialize(std::istream&);
+#ifndef MODPLUG_NO_FILESAVE
bool Serialize() const;
- bool Deserialize(std::istream&);
bool Deserialize();
+#endif // MODPLUG_NO_FILESAVE
//Transfer tuning pT from pTCsrc to pTCdest
static bool TransferTuning(CTuningCollection* pTCsrc, CTuningCollection* pTCdest, CTuning* pT);
@@ -125,7 +129,9 @@
//BEGIN: NONSERIALIZABLE DATA MEMBERS
TUNINGVECTOR m_DeletedTunings; //See Remove()-method for explanation of this.
+#ifndef MODPLUG_NO_FILESAVE
mpt::PathString m_SavefilePath;
+#endif // MODPLUG_NO_FILESAVE
//END: NONSERIALIZABLE DATA MEMBERS
//END: DATA MEMBERS
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <man...@us...> - 2014-03-07 12:47:03
|
Revision: 3841
http://sourceforge.net/p/modplug/code/3841
Author: manxorist
Date: 2014-03-07 12:46:56 +0000 (Fri, 07 Mar 2014)
Log Message:
-----------
[Ref] Replace WORD with uint16.
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Load_it.cpp
trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
Modified: trunk/OpenMPT/soundlib/Load_it.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Load_it.cpp 2014-03-07 12:45:14 UTC (rev 3840)
+++ trunk/OpenMPT/soundlib/Load_it.cpp 2014-03-07 12:46:56 UTC (rev 3841)
@@ -158,7 +158,7 @@
static void ReadTuningMap(std::istream& iStrm, CSoundFile& csf, const size_t = 0)
//-------------------------------------------------------------------------------
{
- typedef std::map<WORD, std::string> MAP;
+ typedef std::map<uint16, std::string> MAP;
typedef MAP::iterator MAP_ITER;
MAP shortToTNameMap;
ReadTuningMapTemplate<uint16, uint8>(iStrm, shortToTNameMap);
Modified: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp
===================================================================
--- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-03-07 12:45:14 UTC (rev 3840)
+++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2014-03-07 12:46:56 UTC (rev 3841)
@@ -495,7 +495,7 @@
{
CriticalSection cs;
- smp.nGlobalVol = MIN((WORD)(smp.nGlobalVol / dAmplify), 64);
+ smp.nGlobalVol = MIN((uint16)(smp.nGlobalVol / dAmplify), 64);
for (CHANNELINDEX i = 0; i < MAX_CHANNELS; i++)
{
if(sndFile.m_PlayState.Chn[i].pModSample == &smp)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sag...@us...> - 2014-03-07 21:26:42
|
Revision: 3846
http://sourceforge.net/p/modplug/code/3846
Author: saga-games
Date: 2014-03-07 21:26:33 +0000 (Fri, 07 Mar 2014)
Log Message:
-----------
[Fix] Mixer: Very small ping-pong loops were detuned sometimes, depending on the mixing frequency (http://schismtracker.org/scdev/read/1447/)
[Imp] XM: Auto-clamp envelope values when saving (to auto-fix old files with pan env value 64)
Modified Paths:
--------------
trunk/OpenMPT/soundlib/Fastmix.cpp
trunk/OpenMPT/soundlib/XMTools.cpp
Modified: trunk/OpenMPT/soundlib/Fastmix.cpp
===================================================================
--- trunk/OpenMPT/soundlib/Fastmix.cpp 2014-03-07 17:34:52 UTC (rev 3845)
+++ trunk/OpenMPT/soundlib/Fastmix.cpp 2014-03-07 21:26:33 UTC (rev 3846)
@@ -151,7 +151,7 @@
{
// Invert loop for bidi loops
int32 nDelta = ((nLoopStart - chn.nPos) << 16) - (chn.nPosLo & 0xffff);
- chn.nPos = nLoopStart | (nDelta >> 16);
+ chn.nPos = nLoopStart + (nDelta >> 16);
chn.nPosLo = nDelta & 0xffff;
if (((int32)chn.nPos < nLoopStart) || (chn.nPos >= (nLoopStart+chn.nLength)/2))
{
@@ -473,8 +473,10 @@
void CSoundFile::ProcessPlugins(UINT nCount)
//------------------------------------------
{
+#ifdef MPT_INTMIXER
const float IntToFloat = m_PlayConfig.getIntToFloat();
const float FloatToInt = m_PlayConfig.getFloatToInt();
+#endif // MPT_INTMIXER
// Setup float inputs
for(PLUGINDEX plug = 0; plug < MAX_MIXPLUGINS; plug++)
{
Modified: trunk/OpenMPT/soundlib/XMTools.cpp
===================================================================
--- trunk/OpenMPT/soundlib/XMTools.cpp 2014-03-07 17:34:52 UTC (rev 3845)
+++ trunk/OpenMPT/soundlib/XMTools.cpp 2014-03-07 21:26:33 UTC (rev 3846)
@@ -61,11 +61,11 @@
{
case EnvTypeVol:
volEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
- volEnv[i * 2 + 1] = mptEnv.Values[i];
+ volEnv[i * 2 + 1] = std::min(mptEnv.Values[i], uint8(64));
break;
case EnvTypePan:
panEnv[i * 2] = std::min(mptEnv.Ticks[i], uint16_max);
- panEnv[i * 2 + 1] = mptEnv.Values[i];
+ panEnv[i * 2 + 1] = std::min(mptEnv.Values[i], uint8(63));
break;
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|