From: <sv...@op...> - 2024-06-08 00:17:14
|
Author: sagamusix Date: Sat Jun 8 02:16:59 2024 New Revision: 20950 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20950 Log: [Ref] Remove CSoundFile::m_nChannels and turn CSoundFile::ChnSettings into a vector. The latter is now the source of truth for the channel count. Modified: trunk/OpenMPT/doc/module_formats.md trunk/OpenMPT/mptrack/CleanupSong.cpp trunk/OpenMPT/mptrack/Draw_pat.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/soundlib/Load_667.cpp trunk/OpenMPT/soundlib/Load_amf.cpp trunk/OpenMPT/soundlib/Load_dbm.cpp trunk/OpenMPT/soundlib/Load_digi.cpp trunk/OpenMPT/soundlib/Load_dsm.cpp trunk/OpenMPT/soundlib/Load_dsym.cpp trunk/OpenMPT/soundlib/Load_ftm.cpp trunk/OpenMPT/soundlib/Load_gdm.cpp trunk/OpenMPT/soundlib/Load_gt2.cpp trunk/OpenMPT/soundlib/Load_imf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_itp.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mo3.cpp trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_okt.cpp trunk/OpenMPT/soundlib/Load_plm.cpp trunk/OpenMPT/soundlib/Load_psm.cpp trunk/OpenMPT/soundlib/Load_ptm.cpp trunk/OpenMPT/soundlib/Load_puma.cpp trunk/OpenMPT/soundlib/Load_rtm.cpp trunk/OpenMPT/soundlib/Load_s3m.cpp trunk/OpenMPT/soundlib/Load_stk.cpp trunk/OpenMPT/soundlib/Load_stp.cpp trunk/OpenMPT/soundlib/Load_symmod.cpp trunk/OpenMPT/soundlib/Load_ult.cpp trunk/OpenMPT/soundlib/Load_wav.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Load_xmf.cpp trunk/OpenMPT/soundlib/MODTools.cpp trunk/OpenMPT/soundlib/MODTools.h trunk/OpenMPT/soundlib/ModSequence.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/load_j2b.cpp trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/doc/module_formats.md ============================================================================== --- trunk/OpenMPT/doc/module_formats.md Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/doc/module_formats.md Sat Jun 8 02:16:59 2024 (r20950) @@ -23,7 +23,7 @@ Entire structs containing integers with defined endianness can be read in one go if they are tagged with `MPT_BINARY_STRUCT` (see existing loaders for an example). -* `CSoundFile::m_nChannels` **MUST NOT** be changed after a pattern has been +* `CSoundFile::ChnSettings` **MUST NOT** be resized after a pattern has been created, as existing patterns will be interpreted incorrectly. For module formats that support per-pattern channel amounts, the maximum number of channels must be determined beforehand. Modified: trunk/OpenMPT/mptrack/CleanupSong.cpp ============================================================================== --- trunk/OpenMPT/mptrack/CleanupSong.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/CleanupSong.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1041,7 +1041,8 @@ for(CHANNELINDEX chn = 0; chn < sndFile.GetNumChannels(); chn++) { - sndFile.InitChannel(chn); + mpt::reconstruct(sndFile.ChnSettings[chn]); + modDoc.InitChannel(chn); } // reset samples Modified: trunk/OpenMPT/mptrack/Draw_pat.cpp ============================================================================== --- trunk/OpenMPT/mptrack/Draw_pat.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/Draw_pat.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1265,7 +1265,7 @@ x2 += dx; y1 += dy; y2 += dy; - nChannels = pSndFile->m_nChannels; + nChannels = pSndFile->GetNumChannels(); nRows = pSndFile->Patterns[m_nPattern].GetNumRows(); if (x1 < GetXScrollPos()) drawLeft = false; if (x1 >= nChannels) x1 = nChannels - 1; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp ============================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/MainFrm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1686,7 +1686,7 @@ m_WaveFile.Order().SetDefaultTempoInt(125); m_WaveFile.Order().SetDefaultSpeed(6); m_WaveFile.m_nType = MOD_TYPE_MPT; - m_WaveFile.m_nChannels = 2; + m_WaveFile.ChnSettings.resize(2); m_WaveFile.m_nInstruments = 1; m_WaveFile.m_nTempoMode = TempoMode::Classic; m_WaveFile.Order().assign(1, 0); Modified: trunk/OpenMPT/mptrack/Moddoc.cpp ============================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/Moddoc.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -602,18 +602,18 @@ void CModDoc::InitializeMod() { // New module ? - if (!m_SndFile.m_nChannels) + if (!m_SndFile.GetNumChannels()) { switch(GetModType()) { case MOD_TYPE_MOD: - m_SndFile.m_nChannels = 4; + m_SndFile.ChnSettings.resize(4); break; case MOD_TYPE_S3M: - m_SndFile.m_nChannels = 16; + m_SndFile.ChnSettings.resize(16); break; default: - m_SndFile.m_nChannels = 32; + m_SndFile.ChnSettings.resize(32); break; } @@ -673,6 +673,17 @@ } +void CModDoc::InitChannel(CHANNELINDEX chn) +{ + if(chn >= GetNumChannels()) + return; + + SetChannelRecordGroup(chn, RecordGroup::NoGroup); + m_SndFile.m_PlayState.Chn[chn].Reset(ModChannel::resetTotal, m_SndFile, chn, CSoundFile::GetChannelMuteFlag()); + m_SndFile.m_bChannelMuteTogglePending[chn] = false; +} + + bool CModDoc::SetDefaultChannelColors(CHANNELINDEX minChannel, CHANNELINDEX maxChannel) { LimitMax(minChannel, GetNumChannels()); @@ -1187,7 +1198,7 @@ } const FlagSet<ChannelFlags> mask = (fade ? CHN_NOTEFADE : (CHN_NOTEFADE | CHN_KEYOFF)); - const CHANNELINDEX startChn = currentChn != CHANNELINDEX_INVALID ? currentChn : m_SndFile.m_nChannels; + const CHANNELINDEX startChn = currentChn != CHANNELINDEX_INVALID ? currentChn : m_SndFile.GetNumChannels(); const CHANNELINDEX endChn = currentChn != CHANNELINDEX_INVALID ? currentChn + 1 : MAX_CHANNELS; ModChannel *pChn = &m_SndFile.m_PlayState.Chn[startChn]; for(CHANNELINDEX i = startChn; i < endChn; i++, pChn++) @@ -1348,14 +1359,14 @@ bool CModDoc::IsChannelNoFx(CHANNELINDEX nChn) const { - if (nChn >= m_SndFile.m_nChannels) return true; + if (nChn >= m_SndFile.GetNumChannels()) return true; return m_SndFile.ChnSettings[nChn].dwFlags[CHN_NOFX]; } bool CModDoc::NoFxChannel(CHANNELINDEX nChn, bool bNoFx, bool updateMix) { - if (nChn >= m_SndFile.m_nChannels) return false; + if (nChn >= m_SndFile.GetNumChannels()) return false; m_SndFile.ChnSettings[nChn].dwFlags.set(CHN_NOFX, bNoFx); if(updateMix) m_SndFile.m_PlayState.Chn[nChn].dwFlags.set(CHN_NOFX, bNoFx); return true; Modified: trunk/OpenMPT/mptrack/Moddoc.h ============================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/Moddoc.h Sat Jun 8 02:16:59 2024 (r20950) @@ -285,7 +285,7 @@ void ToggleChannelRecordGroup(CHANNELINDEX channel, RecordGroup recordGroup); void ReinitRecordState(bool unselect = true); - CHANNELINDEX GetNumChannels() const { return m_SndFile.m_nChannels; } + CHANNELINDEX GetNumChannels() const noexcept { return m_SndFile.GetNumChannels(); } UINT GetPatternSize(PATTERNINDEX nPat) const; bool IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const; INSTRUMENTINDEX FindSampleParent(SAMPLEINDEX sample) const; @@ -346,7 +346,9 @@ // Check whether an instrument is used (only for instrument mode). bool IsInstrumentUsed(INSTRUMENTINDEX instr, bool searchInMutedChannels = true) const; -// protected members + void InitChannel(CHANNELINDEX chn); + + // protected members protected: void InitializeMod(); Modified: trunk/OpenMPT/mptrack/Modedit.cpp ============================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/Modedit.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -172,6 +172,7 @@ } CriticalSection cs; + const std::vector<ModChannelSettings> settings = m_SndFile.ChnSettings; if(oldNumChannels == newNumChannels) { // Optimization with no pattern re-allocation @@ -197,6 +198,7 @@ std::vector<std::vector<ModCommand>> newPatterns; try { + m_SndFile.ChnSettings.reserve(newNumChannels); newPatterns.resize(m_SndFile.Patterns.Size()); for(PATTERNINDEX i = 0; i < m_SndFile.Patterns.Size(); i++) { @@ -209,7 +211,7 @@ return oldNumChannels; } - m_SndFile.m_nChannels = newNumChannels; + m_SndFile.ChnSettings.resize(newNumChannels); for(PATTERNINDEX i = 0; i < m_SndFile.Patterns.Size(); i++) { CPattern &pat = m_SndFile.Patterns[i]; @@ -252,7 +254,6 @@ } std::vector<ModChannel> chns(m_SndFile.m_PlayState.Chn.begin(), m_SndFile.m_PlayState.Chn.begin() + oldNumChannels); - std::vector<ModChannelSettings> settings(std::begin(m_SndFile.ChnSettings), std::begin(m_SndFile.ChnSettings) + oldNumChannels); std::vector<RecordGroup> recordStates(oldNumChannels); auto chnMutePendings = m_SndFile.m_bChannelMuteTogglePending; for(CHANNELINDEX chn = 0; chn < oldNumChannels; chn++) @@ -274,7 +275,8 @@ m_SndFile.m_opl->MoveChannel(srcChn, chn); } else { - m_SndFile.InitChannel(chn); + mpt::reconstruct(m_SndFile.ChnSettings[chn]); + InitChannel(chn); SetDefaultChannelColors(chn); } } Modified: trunk/OpenMPT/mptrack/View_gen.cpp ============================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/mptrack/View_gen.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -336,7 +336,7 @@ return; CString s; - nTabCount = (sndFile.m_nChannels + (CHANNELS_IN_TAB - 1)) / CHANNELS_IN_TAB; + nTabCount = (sndFile.GetNumChannels() + (CHANNELS_IN_TAB - 1)) / CHANNELS_IN_TAB; if (nTabCount != m_TabCtrl.GetItemCount()) { UINT nOldSel = m_TabCtrl.GetCurSel(); Modified: trunk/OpenMPT/soundlib/Load_667.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_667.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_667.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -137,14 +137,14 @@ { // Instrument auto instr = patData.ReadArray<uint8, 2>(); - if(instr[0] >= m_nChannels || instr[1] > 63) + if(instr[0] >= GetNumChannels() || instr[1] > 63) return false; rowData[instr[0]].instr = instr[1] + 1; } else if(b == 0xFD) { // Volume auto vol = patData.ReadArray<uint8, 2>(); - if(vol[0] >= m_nChannels || vol[1] > 63) + if(vol[0] >= GetNumChannels() || vol[1] > 63) return false; rowData[vol[0]].SetVolumeCommand(VOLCMD_VOLUME, 63u - vol[1]); } else if(b == 0xFC) @@ -156,7 +156,7 @@ { // Pattern break rowData[0].SetEffectCommand(CMD_PATTERNBREAK, 0); - } else if(b < m_nChannels) + } else if(b < GetNumChannels()) { // Note data uint8 note = patData.ReadUint8(); @@ -175,7 +175,7 @@ } if(leftChn && rightChn) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = (chn % 2u) ? 256 : 0; } Modified: trunk/OpenMPT/soundlib/Load_amf.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_amf.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_amf.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -653,7 +653,7 @@ patternLength[ord] = file.ReadUint16LE(); } // Track positions will be read as needed. - file.Skip(m_nChannels * 2); + file.Skip(GetNumChannels() * 2); } // Read Sample Headers Modified: trunk/OpenMPT/soundlib/Load_dbm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_dbm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_dbm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -563,7 +563,7 @@ if(hasEchoEnable) { // If there are any Vxx effects to dynamically enable / disable echo, use the CHN_NOFX flag. - for(CHANNELINDEX i = 0; i < m_nChannels; i++) + for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { ChnSettings[i].nMixPlugin = 1; ChnSettings[i].dwFlags.set(CHN_NOFX); @@ -580,7 +580,7 @@ for(uint16 i = 0; i < maskLen; i++) { bool enabled = (dspChunk.ReadUint8() == 0); - if(i < m_nChannels) + if(i < GetNumChannels()) { if(hasEchoEnable) { Modified: trunk/OpenMPT/soundlib/Load_digi.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_digi.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_digi.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -121,7 +121,7 @@ // Globals InitializeGlobals(MOD_TYPE_DIGI, fileHeader.numChannels); m_nSamples = 31; - m_nSamplePreAmp = 256 / m_nChannels; + m_nSamplePreAmp = 256 / GetNumChannels(); m_modFormat.formatName = U_("DigiBooster"); m_modFormat.type = U_("digi"); Modified: trunk/OpenMPT/soundlib/Load_dsm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_dsm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_dsm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -218,7 +218,7 @@ m_nDefaultGlobalVolume = std::min(songHeader.globalVol.get(), uint8(64)) * 4u; if(!m_nDefaultGlobalVolume) m_nDefaultGlobalVolume = MAX_GLOBAL_VOLUME; if(songHeader.mastervol == 0x80) - m_nSamplePreAmp = std::min(256u / m_nChannels, 128u); + m_nSamplePreAmp = std::min(256u / GetNumChannels(), 128u); else m_nSamplePreAmp = songHeader.mastervol & 0x7F; @@ -407,7 +407,7 @@ m_songName = mpt::String::ReadBuf(mpt::String::spacePadded, fileHeader.title); m_songArtist = mpt::ToUnicode(mpt::Charset::CP437, mpt::String::ReadBuf(mpt::String::spacePadded, fileHeader.artist)); - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = (file.ReadUint8() & 0x0F) * 0x11; } @@ -420,15 +420,15 @@ } numPatterns++; - if(!file.CanRead((numPatterns * m_nChannels * 8) + (m_nSamples * sizeof(DSmSampleHeader)) + (numPatterns * m_nChannels * 64 * 4))) + if(!file.CanRead((numPatterns * GetNumChannels() * 8) + (m_nSamples * sizeof(DSmSampleHeader)) + (numPatterns * GetNumChannels() * 64 * 4))) return false; // Track names for each pattern - we only read the track names of the first pattern - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].szName = mpt::String::ReadBuf(mpt::String::spacePadded, file.ReadArray<char, 8>()); } - file.Skip((numPatterns - 1) * m_nChannels * 8); + file.Skip((numPatterns - 1) * GetNumChannels() * 8); for(SAMPLEINDEX smp = 1; smp <= m_nSamples; smp++) { @@ -443,7 +443,7 @@ { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { - file.Skip(m_nChannels * 64 * 4); + file.Skip(GetNumChannels() * 64 * 4); continue; } for(ModCommand &m : Patterns[pat]) Modified: trunk/OpenMPT/soundlib/Load_dsym.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_dsym.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_dsym.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -240,7 +240,7 @@ m_SongFlags.reset(SONG_ISAMIGA); m_nSamples = 63; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 64 : 192; } @@ -289,14 +289,14 @@ if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) continue; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { - const uint16 track = sequence[pat * m_nChannels + chn]; + const uint16 track = sequence[pat * GetNumChannels() + chn]; if(track >= fileHeader.numTracks) continue; ModCommand *m = Patterns[pat].GetpModCommand(0, chn); - for(ROWINDEX row = 0; row < 64; row++, m += m_nChannels) + for(ROWINDEX row = 0; row < 64; row++, m += GetNumChannels()) { const auto data = tracks.subspan(track * 256 + row * 4, 4); m->note = data[0] & 0x3F; @@ -423,7 +423,7 @@ break; case 0x2B: // 2B xyy Line Jump m->command = CMD_PATTERNBREAK; - for(CHANNELINDEX brkChn = 0; brkChn < m_nChannels; brkChn++) + for(CHANNELINDEX brkChn = 0; brkChn < GetNumChannels(); brkChn++) { ModCommand &cmd = *(m - chn + brkChn); if(cmd.command != CMD_NONE) Modified: trunk/OpenMPT/soundlib/Load_ftm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_ftm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_ftm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -364,7 +364,7 @@ bool operator<(const PatternLoopPoint other) const noexcept { return std::tie(order, row, channel) < std::tie(other.order, other.row, other.channel); } }; std::vector<PatternLoopPoint> loopPoints; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { const uint16 defaultSpacing = file.ReadUint16BE(); FileReader channelChunk = file.ReadChunk(file.ReadUint32BE()); Modified: trunk/OpenMPT/soundlib/Load_gdm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_gdm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_gdm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -344,7 +344,7 @@ while((channelByte = chunk.ReadUint8()) != rowDone) { CHANNELINDEX channel = channelByte & channelMask; - if(channel >= m_nChannels) break; // Better safe than sorry! + if(channel >= GetNumChannels()) break; // Better safe than sorry! ModCommand &m = rowBase[channel]; Modified: trunk/OpenMPT/soundlib/Load_gt2.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_gt2.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_gt2.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1217,14 +1217,14 @@ m_songName = mpt::String::ReadBuf(mpt::String::spacePadded, fileHeader.songName); m_nSamplePreAmp = 256; - m_nDefaultGlobalVolume = 384 / (3 + m_nChannels); // See documentation on command 5xxx: Default linear master volume is 12288 / (3 + number of channels) + m_nDefaultGlobalVolume = 384 / (3 + GetNumChannels()); // See documentation on command 5xxx: Default linear master volume is 12288 / (3 + number of channels) if(fileHeader.fileVersion <= 5) { Order().SetDefaultSpeed(std::max(fileHeader.speed.get(), uint16(1))); Order().SetDefaultTempoInt(std::max(fileHeader.tempo.get(), uint16(1))); m_nDefaultGlobalVolume = std::min(Util::muldivr_unsigned(fileHeader.masterVol, MAX_GLOBAL_VOLUME, 4095), uint32(MAX_GLOBAL_VOLUME)); - const CHANNELINDEX tracks = std::min(static_cast<CHANNELINDEX>(pannedTracks.size()), m_nChannels); + const CHANNELINDEX tracks = std::min(static_cast<CHANNELINDEX>(pannedTracks.size()), GetNumChannels()); for(CHANNELINDEX chn = 0; chn < tracks; chn++) { ChnSettings[chn].nPan = std::min(static_cast<uint16>(Util::muldivr_unsigned(pannedTracks[chn], 256, 4095)), uint16(256)); @@ -1550,7 +1550,7 @@ { GT2TrackName trackName; chunk.ReadStruct(trackName); - if(trackName.type == 0 && trackName.trackNumber < m_nChannels) + if(trackName.type == 0 && trackName.trackNumber < GetNumChannels()) { ChnSettings[trackName.trackNumber].szName = mpt::String::ReadBuf(mpt::String::spacePadded, trackName.name); } Modified: trunk/OpenMPT/soundlib/Load_imf.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_imf.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_imf.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -437,8 +437,8 @@ // Read channel configuration std::bitset<32> ignoreChannels; // bit set for each channel that's completely disabled - uint64 channelMuteStatus = 0xAAAA'AAAA << (m_nChannels * 2); - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + uint64 channelMuteStatus = 0xAAAA'AAAA << (GetNumChannels() * 2); + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = static_cast<uint16>(fileHeader.channels[chn].panning * 256 / 255); ChnSettings[chn].szName = mpt::String::ReadBuf(mpt::String::nullTerminated, fileHeader.channels[chn].name); @@ -461,7 +461,7 @@ // mikmod refers to this as an Orpheus bug, but I haven't seen any other files like this, so maybe it's just an incorrectly saved file? if(channelMuteStatus == 0xAAAA'AAAA'5555'5554) { - for(CHANNELINDEX chn = 1; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 1; chn < GetNumChannels(); chn++) ChnSettings[chn].dwFlags.reset(CHN_MUTE); } Modified: trunk/OpenMPT/soundlib/Load_it.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_it.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -690,11 +690,11 @@ if(file.ReadMagic("CNAM")) { FileReader chnNames = file.ReadChunk(file.ReadUint32LE()); - m_nChannels = std::min(MAX_BASECHANNELS, static_cast<CHANNELINDEX>(chnNames.GetLength() / MAX_CHANNELNAME)); + ChnSettings.resize(std::min(MAX_BASECHANNELS, static_cast<CHANNELINDEX>(chnNames.GetLength() / MAX_CHANNELNAME))); hasModPlugExtensions = true; - for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) + for(auto &chn : ChnSettings) { - chnNames.ReadString<mpt::String::maybeNullTerminated>(ChnSettings[chn].szName, MAX_CHANNELNAME); + chnNames.ReadString<mpt::String::maybeNullTerminated>(chn.szName, MAX_CHANNELNAME); } } @@ -876,6 +876,7 @@ } // Checking for number of used channels, which is not explicitely specified in the file. + CHANNELINDEX numChannels = GetNumChannels(); for(PATTERNINDEX pat = 0; pat < numPats; pat++) { if(patPos[pat] == 0 || !file.Seek(patPos[pat])) @@ -891,7 +892,7 @@ FileReader patternData = file.ReadChunk(len); ROWINDEX row = 0; - std::vector<uint8> chnMask(GetNumChannels()); + std::vector<uint8> chnMask(numChannels); while(row < numRows && patternData.CanRead(1)) { @@ -920,9 +921,9 @@ // Channel used if(chnMask[ch] & 0x0F) // if this channel is used set m_nChannels { - if(ch >= GetNumChannels() && ch < MAX_BASECHANNELS) + if(ch >= numChannels && ch < MAX_BASECHANNELS) { - m_nChannels = ch + 1; + numChannels = ch + 1; } // Skip a number of bytes depending on note, instrument, volume, effect being present. @@ -932,6 +933,7 @@ } lastSampleOffset = std::max(lastSampleOffset, file.GetPosition()); } + ChnSettings.resize(numChannels); // Compute extra instruments settings position if(lastSampleOffset > 0) @@ -1051,7 +1053,7 @@ // Now we grab the data for this particular row/channel. ModCommand dummy{}; - ModCommand &m = ch < m_nChannels ? patData[ch] : dummy; + ModCommand &m = ch < GetNumChannels() ? patData[ch] : dummy; if(chnMask[ch] & 0x10) { @@ -1548,7 +1550,7 @@ memset(itHeader.chnpan, 0xA0, 64); memset(itHeader.chnvol, 64, 64); - for(CHANNELINDEX ich = 0; ich < std::min(m_nChannels, CHANNELINDEX(64)); ich++) // Header only has room for settings for 64 chans... + for(CHANNELINDEX ich = 0; ich < std::min(GetNumChannels(), CHANNELINDEX(64)); ich++) // Header only has room for settings for 64 chans... { itHeader.chnpan[ich] = (uint8)(ChnSettings[ich].nPan >> 2); if (ChnSettings[ich].dwFlags[CHN_SURROUND]) itHeader.chnpan[ich] = 100; @@ -1562,7 +1564,7 @@ // Channel names if(!compatibilityExport) { - for(CHANNELINDEX i = 0; i < m_nChannels; i++) + for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { if(ChnSettings[i].szName[0]) { @@ -2250,7 +2252,7 @@ if(GetType() != MOD_TYPE_XM) { - WRITEMODULAR(MagicBE("C..."), m_nChannels); + WRITEMODULAR(MagicBE("C..."), GetNumChannels()); } if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && GetNumChannels() > 64) @@ -2378,7 +2380,7 @@ // Channel colors { CHANNELINDEX numChannels = 0; - for(CHANNELINDEX i = 0; i < m_nChannels; i++) + for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { if(ChnSettings[i].color != ModChannelSettings::INVALID_COLOR) { @@ -2460,7 +2462,7 @@ case MagicBE("RPB."): ReadField(chunk, size, m_nDefaultRowsPerBeat); break; case MagicBE("RPM."): ReadField(chunk, size, m_nDefaultRowsPerMeasure); break; // FIXME: If there are only PC events on the last few channels in an MPTM MO3, they won't be imported! - case MagicBE("C..."): if(!ignoreChannelCount) { CHANNELINDEX chn = 0; ReadField(chunk, size, chn); m_nChannels = Clamp(chn, m_nChannels, MAX_BASECHANNELS); } break; + case MagicBE("C..."): if(!ignoreChannelCount) { CHANNELINDEX chn = 0; ReadField(chunk, size, chn); ChnSettings.resize(Clamp(chn, GetNumChannels(), MAX_BASECHANNELS)); } break; case MagicBE("TM.."): ReadFieldCast(chunk, size, m_nTempoMode); break; case MagicBE("PMM."): ReadFieldCast(chunk, size, m_nMixLevels); break; case MagicBE("CWV."): { uint32 ver = 0; ReadField(chunk, size, ver); m_dwCreatedWithVersion = Version(ver); break; } @@ -2500,11 +2502,12 @@ break; case MagicBE("ChnS"): // Channel settings for channels 65+ + static_assert(MAX_BASECHANNELS >= 64); if(size <= (MAX_BASECHANNELS - 64) * 2 && (size % 2u) == 0) { - static_assert(mpt::array_size<decltype(ChnSettings)>::size >= 64); - const CHANNELINDEX loopLimit = std::min(uint16(64 + size / 2), uint16(std::size(ChnSettings))); - + const CHANNELINDEX channelsInFile = mpt::saturate_cast<CHANNELINDEX>(64 + size / 2); + ChnSettings.resize(std::clamp(GetNumChannels(), channelsInFile, MAX_BASECHANNELS)); + const CHANNELINDEX loopLimit = std::min(channelsInFile, GetNumChannels()); for(CHANNELINDEX chn = 64; chn < loopLimit; chn++) { auto [pan, vol] = chunk.ReadArray<uint8, 2>(); Modified: trunk/OpenMPT/soundlib/Load_itp.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_itp.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_itp.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -200,15 +200,15 @@ // Channels' data uint32 size = songHeader.channelNameLength; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(auto &chn : ChnSettings) { - ChnSettings[chn].nPan = std::min(static_cast<uint16>(file.ReadUint32LE()), uint16(256)); - ChnSettings[chn].dwFlags.reset(); + chn.nPan = std::min(static_cast<uint16>(file.ReadUint32LE()), uint16(256)); + chn.dwFlags.reset(); uint32 flags = file.ReadUint32LE(); - if(flags & 0x100) ChnSettings[chn].dwFlags.set(CHN_MUTE); - if(flags & 0x800) ChnSettings[chn].dwFlags.set(CHN_SURROUND); - ChnSettings[chn].nVolume = std::min(static_cast<uint8>(file.ReadUint32LE()), uint8(64)); - file.ReadString<mpt::String::maybeNullTerminated>(ChnSettings[chn].szName, size); + if(flags & 0x100) chn.dwFlags.set(CHN_MUTE); + if(flags & 0x800) chn.dwFlags.set(CHN_SURROUND); + chn.nVolume = std::min(static_cast<uint8>(file.ReadUint32LE()), uint8(64)); + file.ReadString<mpt::String::maybeNullTerminated>(chn.szName, size); } // Song mix plugins Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -736,7 +736,7 @@ for(CHANNELINDEX chn = 0; chn < numChans; chn++) { uint16 trkNum = chunk.ReadUint16LE(); - if(!trkNum || trkNum >= tracks.size() || chn >= m_nChannels) + if(!trkNum || trkNum >= tracks.size() || chn >= GetNumChannels()) continue; FileReader &track = tracks[trkNum]; @@ -761,7 +761,7 @@ do { *m = orig; - m += m_nChannels; + m += GetNumChannels(); row++; } while (row < numRows && x--); } Modified: trunk/OpenMPT/soundlib/Load_med.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_med.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1309,7 +1309,7 @@ SetupMODPanning(true); // With MED SoundStudio 1.03 it's possible to create MMD1 files with more than 16 channels. - const CHANNELINDEX numChannelVols = std::min(m_nChannels, CHANNELINDEX(16)); + const CHANNELINDEX numChannelVols = std::min(GetNumChannels(), CHANNELINDEX(16)); for(CHANNELINDEX chn = 0; chn < numChannelVols; chn++) { ChnSettings[chn].nVolume = std::min<uint8>(songHeader.trackVol[chn], 64); @@ -1317,7 +1317,7 @@ } else { const MMD2Song header = songHeader.GetMMD2Song(); - if(header.numTracks < 1 || header.numTracks > 64 || m_nChannels > 64) + if(header.numTracks < 1 || header.numTracks > 64 || GetNumChannels() > 64) return false; const bool freePan = (header.flags3 & MMD2Song::FLAG3_FREEPAN); @@ -1328,14 +1328,14 @@ if(file.Seek(header.trackVolsOffset)) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nVolume = std::min<uint8>(file.ReadUint8(), 64); } } if(header.trackPanOffset && file.Seek(header.trackPanOffset)) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = static_cast<uint16>((Clamp<int8, int8>(file.ReadInt8(), -16, 16) + 16) * 8); } @@ -1516,7 +1516,7 @@ // Track Names if(version >= 2 && expData.trackInfoOffset) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { if(file.Seek(expData.trackInfoOffset + chn * 4) && file.Seek(file.ReadUint32BE())) @@ -1613,7 +1613,7 @@ CPattern &pattern = Patterns[basePattern + pat]; pattern.SetName(patName); - LimitMax(numTracks, m_nChannels); + LimitMax(numTracks, GetNumChannels()); TranslateMEDPatternContext context{transpose, numTracks, version, rowsPerBeat, hardwareMixSamples, is8Ch, bpmMode, volHex}; needInstruments |= TranslateMEDPattern(file, cmdExt, pattern, context, false); @@ -1653,7 +1653,7 @@ PATTERNINDEX firstPat = order.EnsureUnique(order.GetFirstValidIndex()); if(firstPat != PATTERNINDEX_INVALID) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { Patterns[firstPat].WriteEffect(EffectWriter(CMD_CHANNELVOLUME, static_cast<ModCommand::PARAM>(ChnSettings[chn].nVolume)).Channel(chn).RetryNextRow()); Patterns[firstPat].WriteEffect(EffectWriter(CMD_PANNING8, mpt::saturate_cast<ModCommand::PARAM>(ChnSettings[chn].nPan)).Channel(chn).RetryNextRow()); @@ -1683,7 +1683,7 @@ const mpt::uchar *madeWithTracker = MPT_ULITERAL(""); switch(version) { - case 0: madeWithTracker = m_nChannels > 4 ? MPT_ULITERAL("OctaMED v2.10 (MMD0)") : MPT_ULITERAL("MED v2 (MMD0)"); break; + case 0: madeWithTracker = GetNumChannels() > 4 ? MPT_ULITERAL("OctaMED v2.10 (MMD0)") : MPT_ULITERAL("MED v2 (MMD0)"); break; case 1: madeWithTracker = MPT_ULITERAL("OctaMED v4 (MMD1)"); break; case 2: madeWithTracker = MPT_ULITERAL("OctaMED v5 (MMD2)"); break; case 3: madeWithTracker = MPT_ULITERAL("OctaMED Soundstudio (MMD3)"); break; Modified: trunk/OpenMPT/soundlib/Load_mid.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_mid.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -666,10 +666,10 @@ Order().clear(); MidiChannelState midiChnStatus[16]; - const CHANNELINDEX tempoChannel = m_nChannels - 2, globalVolChannel = m_nChannels - 1; + const CHANNELINDEX tempoChannel = GetNumChannels() - 2, globalVolChannel = GetNumChannels() - 1; const uint16 numTracks = fileHeader.numTracks; std::vector<TrackState> tracks(numTracks); - std::vector<ModChannelState> modChnStatus(m_nChannels); + std::vector<ModChannelState> modChnStatus(GetNumChannels()); std::bitset<16> drumChns; drumChns.set(MIDI_DRUMCHANNEL - 1); @@ -1267,8 +1267,8 @@ Order.SetSequence(0); std::vector<CHANNELINDEX> channels; - channels.reserve(m_nChannels); - for(CHANNELINDEX i = 0; i < m_nChannels; i++) + channels.reserve(GetNumChannels()); + for(CHANNELINDEX i = 0; i < GetNumChannels(); i++) { if(modChnStatus[i].midiCh != ModChannelState::NOMIDI #ifdef MODPLUG_TRACKER Modified: trunk/OpenMPT/soundlib/Load_mo3.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mo3.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_mo3.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -933,7 +933,7 @@ m_nSamplePreAmp = static_cast<uint32>(std::exp(fileHeader.sampleVolume * 3.1 / 20.0)) + 51; // Header only has room for 64 channels, like in IT - const CHANNELINDEX headerChannels = std::min(m_nChannels, CHANNELINDEX(64)); + const CHANNELINDEX headerChannels = std::min(GetNumChannels(), CHANNELINDEX(64)); for(CHANNELINDEX i = 0; i < headerChannels; i++) { if(m_nType == MOD_TYPE_IT) @@ -1381,9 +1381,9 @@ if(pluginFlags & 1) { // Channel plugins - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(auto &chn : ChnSettings) { - ChnSettings[chn].nMixPlugin = static_cast<PLUGINDEX>(musicChunk.ReadUint32LE()); + chn.nMixPlugin = static_cast<PLUGINDEX>(musicChunk.ReadUint32LE()); } } while(musicChunk.CanRead(1)) Modified: trunk/OpenMPT/soundlib/Load_mod.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_mod.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -313,7 +313,7 @@ } // Startrekker 8 channel mod (needs special treatment, see below) - const bool isFLT8 = isStartrekker && m_nChannels == 8; + const bool isFLT8 = isStartrekker && GetNumChannels() == 8; const bool isMdKd = IsMagic(magic, "M.K."); // Adjust finetune values for modules saved with "His Master's Noisetracker" const bool isHMNT = IsMagic(magic, "M&K!") || IsMagic(magic, "FEST"); @@ -332,7 +332,7 @@ for(SAMPLEINDEX smp = 1; smp <= 31; smp++) { MODSampleHeader sampleHeader = ReadAndSwap<MODSampleHeader>(file, modMagicResult.swapBytes); - invalidBytes += ReadMODSample(sampleHeader, Samples[smp], m_szNames[smp], m_nChannels == 4); + invalidBytes += ReadMODSample(sampleHeader, Samples[smp], m_szNames[smp], GetNumChannels() == 4); totalSampleLen += Samples[smp].nLength; if(isHMNT) @@ -390,7 +390,7 @@ } // Get number of patterns (including some order list sanity checks) - PATTERNINDEX numPatterns = GetNumPatterns(file, Order(), realOrders, totalSampleLen, m_nChannels, wowSampleLen, false); + PATTERNINDEX numPatterns = GetNumPatterns(file, *this, realOrders, totalSampleLen, wowSampleLen, false); if(maybeWOW && GetNumChannels() == 8) { // M.K. with 8 channels = Mod's Grave @@ -418,7 +418,7 @@ // Files that have an order list longer than 0x78 with restart pos = 0x78: my_shoe_is_barking.mod, papermix.mod // - in both cases it does not appear like the restart position should be used. MPT_ASSERT(fileHeader.restartPos != 0x78 || fileHeader.restartPos + 1u >= realOrders); - if(fileHeader.restartPos > realOrders || (fileHeader.restartPos == 0x78 && m_nChannels == 4)) + if(fileHeader.restartPos > realOrders || (fileHeader.restartPos == 0x78 && GetNumChannels() == 4)) { Order().SetRestartPos(0); } @@ -430,7 +430,7 @@ // Prevent clipping based on number of channels... If all channels are playing at full volume, "256 / #channels" // is the maximum possible sample pre-amp without getting distortion (Compatible mix levels given). // The more channels we have, the less likely it is that all of them are used at the same time, though, so cap at 32... - m_nSamplePreAmp = Clamp(256 / m_nChannels, 32, 128); + m_nSamplePreAmp = Clamp(256 / GetNumChannels(), 32, 128); m_SongFlags.reset(); // SONG_ISAMIGA will be set conditionally // Setup channel pan positions and volume @@ -447,7 +447,7 @@ const uint8 ENABLE_MOD_PANNING_THRESHOLD = 0x30; if(!isNoiseTracker) { - const uint32 patternLength = m_nChannels * 64; + const uint32 patternLength = GetNumChannels() * 64; bool leftPanning = false, extendedPanning = false; // For detecting 800-880 panning isNoiseTracker = isMdKd && !hasEmptySampleWithVolume && !hasLongSamples; for(PATTERNINDEX pat = 0; pat < numPatterns; pat++) @@ -488,7 +488,7 @@ } file.Seek(modMagicResult.patternDataOffset); - const CHANNELINDEX readChannels = (isFLT8 ? 4 : m_nChannels); // 4 channels per pattern in FLT8 format. + const CHANNELINDEX readChannels = (isFLT8 ? 4 : GetNumChannels()); // 4 channels per pattern in FLT8 format. if(isFLT8) numPatterns++; // as one logical pattern consists of two real patterns in FLT8 format, the highest pattern number has to be increased by one. bool hasTempoCommands = false, definitelyCIA = hasLongSamples; // for detecting VBlank MODs @@ -529,7 +529,7 @@ std::vector<ModCommand::INSTR> lastInstrument(GetNumChannels(), 0); std::vector<uint8> instrWithoutNoteCount(GetNumChannels(), 0); - for(ROWINDEX row = 0; row < 64; row++, rowBase += m_nChannels) + for(ROWINDEX row = 0; row < 64; row++, rowBase += GetNumChannels()) { // If we have more than one Fxx command on this row and one can be interpreted as speed // and the other as tempo, we can be rather sure that it is not a VBlank mod. @@ -875,7 +875,7 @@ bool CSoundFile::SaveMod(std::ostream &f) const { - if(m_nChannels == 0) + if(GetNumChannels() == 0) { return false; } Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -476,11 +476,11 @@ FileReader drumData = file.ReadChunk(hasDrumChannels ? sizeof(MT2DrumsData) : 0); FileReader extraData = file.ReadChunk(file.ReadUint32LE()); - const CHANNELINDEX channelsWithoutDrums = m_nChannels; + const CHANNELINDEX channelsWithoutDrums = GetNumChannels(); static_assert(MAX_BASECHANNELS >= 64 + 8); if(hasDrumChannels) { - m_nChannels += 8; + ChnSettings.resize(GetNumChannels() + 8); } bool hasLegacyTempo = false; @@ -616,7 +616,7 @@ break; case MagicLE("TRKL"): - for(CHANNELINDEX i = 0; i < m_nChannels && chunk.CanRead(1); i++) + for(CHANNELINDEX i = 0; i < GetNumChannels() && chunk.CanRead(1); i++) { std::string name; chunk.ReadNullString(name); @@ -688,7 +688,7 @@ mixPlug.Info.szLibraryName = libraryName; mixPlug.Info.dwPluginId1 = Vst::kEffectMagic; mixPlug.Info.dwPluginId2 = vstHeader.fxID; - if(vstHeader.track >= m_nChannels) + if(vstHeader.track >= GetNumChannels()) { mixPlug.SetMasterEffect(true); } else @@ -841,7 +841,7 @@ const ROWINDEX numRows = static_cast<ROWINDEX>(chunk.GetLength() / 32u); for(ROWINDEX row = 0; row < Patterns[writePat].GetNumRows(); row++) { - ModCommand *m = Patterns[writePat].GetpModCommand(row, m_nChannels - 8); + ModCommand *m = Patterns[writePat].GetpModCommand(row, GetNumChannels() - 8); for(CHANNELINDEX chn = 0; chn < 8; chn++, m++) { *m = ModCommand{}; @@ -873,7 +873,7 @@ // Read automation envelopes if(fileHeader.flags & MT2FileHeader::automation) { - const uint32 numEnvelopes = ((fileHeader.flags & MT2FileHeader::drumsAutomation) ? m_nChannels : channelsWithoutDrums) + const uint32 numEnvelopes = ((fileHeader.flags & MT2FileHeader::drumsAutomation) ? GetNumChannels() : channelsWithoutDrums) + ((fileHeader.version >= 0x0250) ? numVST : 0) + ((fileHeader.flags & MT2FileHeader::masterAutomation) ? 1 : 0); Modified: trunk/OpenMPT/soundlib/Load_okt.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_okt.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_okt.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -367,20 +367,21 @@ { case OktIffChunk::idCMOD: // Channel setup table - if(m_nChannels == 0 && chunk.CanRead(8)) + if(GetNumChannels() == 0 && chunk.CanRead(8)) { const auto chnTable = chunk.ReadArray<uint16be, 4>(); + ChnSettings.reserve(8); + CHANNELINDEX realChn = 0; for(CHANNELINDEX chn = 0; chn < 4; chn++) { if(chnTable[chn]) { - pairedChn[m_nChannels] = 1; - pairedChn[m_nChannels + 1] = -1; - mpt::reconstruct(ChnSettings[m_nChannels]); - ChnSettings[m_nChannels++].nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; + pairedChn[realChn++] = 1; + pairedChn[realChn] = -1; + ChnSettings.emplace_back().nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; } - mpt::reconstruct(ChnSettings[m_nChannels]); - ChnSettings[m_nChannels++].nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; + realChn++; + ChnSettings.emplace_back().nPan = (((chn & 3) == 1) || ((chn & 3) == 2)) ? 0xC0 : 0x40; } if(loadFlags == onlyVerifyHeader) @@ -443,7 +444,7 @@ } // If there wasn't even a CMOD chunk, we can't really load this. - if(m_nChannels == 0) + if(GetNumChannels() == 0) return false; Order().SetDefaultTempoInt(125); Modified: trunk/OpenMPT/soundlib/Load_plm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_plm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_plm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -323,7 +323,7 @@ { uint16 target = order[m->param].x; m->param = static_cast<ModCommand::PARAM>(target / rowsPerPat); - ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, m_nChannels - 1); + ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, GetNumChannels() - 1); mBreak->command = CMD_PATTERNBREAK; mBreak->param = static_cast<ModCommand::PARAM>(target % rowsPerPat); } @@ -331,7 +331,7 @@ case 0x0C: // Jump to end of order { m->param = static_cast<ModCommand::PARAM>(patternEnd / rowsPerPat); - ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, m_nChannels - 1); + ModCommand *mBreak = Patterns[pat].GetpModCommand(curRow, GetNumChannels() - 1); mBreak->command = CMD_PATTERNBREAK; mBreak->param = static_cast<ModCommand::PARAM>(patternEnd % rowsPerPat); } Modified: trunk/OpenMPT/soundlib/Load_psm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_psm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_psm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -500,8 +500,8 @@ case PSMChunk::idPPAN: // PPAN - Channel panning table (used in Sinaria) // In some Sinaria tunes, this is actually longer than 2 * channels... - MPT_ASSERT(subChunkHead.GetLength() >= m_nChannels * 2u); - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + MPT_ASSERT(subChunkHead.GetLength() >= GetNumChannels() * 2u); + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { if(!subChunk.CanRead(2)) break; @@ -583,7 +583,7 @@ } // Make the default variables of the first subsong global - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nVolume = subsongs[0].channelVolume[chn]; ChnSettings[chn].nPan = subsongs[0].channelPanning[chn]; @@ -643,7 +643,7 @@ { const auto [flags, channel] = rowChunk.ReadArray<uint8, 2>(); // Point to the correct channel - ModCommand &m = rowBase[std::min(static_cast<CHANNELINDEX>(m_nChannels - 1), static_cast<CHANNELINDEX>(channel))]; + ModCommand &m = rowBase[std::min(static_cast<CHANNELINDEX>(GetNumChannels() - 1), static_cast<CHANNELINDEX>(channel))]; if(flags & noteFlag) { @@ -854,7 +854,7 @@ // Don't write channel volume for now, as there is no real-world module which needs it. if(subsongPanningDiffers) { - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { if(subsong.channelSurround[chn]) Patterns[startPattern].WriteEffect(EffectWriter(CMD_S3MCMDEX, 0x91).Row(0).Channel(chn).RetryNextRow()); @@ -1155,7 +1155,7 @@ continue; } - ModCommand &m = *Patterns[pat].GetpModCommand(curRow, std::min(static_cast<CHANNELINDEX>(chnFlag & channelMask), static_cast<CHANNELINDEX>(m_nChannels - 1))); + ModCommand &m = *Patterns[pat].GetpModCommand(curRow, std::min(static_cast<CHANNELINDEX>(chnFlag & channelMask), static_cast<CHANNELINDEX>(GetNumChannels() - 1))); if(chnFlag & noteFlag) { Modified: trunk/OpenMPT/soundlib/Load_ptm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_ptm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_ptm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -180,7 +180,7 @@ ReadOrderFromArray(Order(), fileHeader.orders, fileHeader.numOrders, 0xFF, 0xFE); // Reading channel panning - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = ((fileHeader.chnPan[chn] & 0x0F) << 4) + 4; } @@ -227,7 +227,7 @@ if(b == 0) { row++; - rowBase += m_nChannels; + rowBase += GetNumChannels(); continue; } CHANNELINDEX chn = (b & 0x1F); Modified: trunk/OpenMPT/soundlib/Load_puma.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_puma.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_puma.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -265,7 +265,7 @@ else if(autoPorta != VOLCMD_NONE) m->volcmd = autoPorta; } - m += m_nChannels; + m += GetNumChannels(); } } if(orderData[ord].speed) Modified: trunk/OpenMPT/soundlib/Load_rtm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_rtm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_rtm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -329,7 +329,7 @@ FileReader extraData = file.ReadChunk(songHeader.extraDataSize); ReadOrderFromFile<uint16le>(Order(), extraData, songHeader.numOrders); - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = static_cast<uint16>((songHeader.panning[chn] + 64) * 2); if(songHeader.flags & RTMMHeader::songTrackNames) Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -497,7 +497,7 @@ hasChannelsWithoutPanning = true; } } - if(m_nChannels < 32 && m_dwLastSavedWithVersion == MPT_V("1.16")) + if(GetNumChannels() < 32 && m_dwLastSavedWithVersion == MPT_V("1.16")) { // MPT 1.0 alpha 6 up to 1.16.203 set ths panning bit for all channels, regardless of whether they are used or not. if(hasChannelsWithoutPanning) @@ -686,7 +686,7 @@ } } - if(pixPlayPanning && zxxCountLeft + zxxCountRight >= m_nChannels && (-zxxCountLeft + zxxCountRight) < static_cast<int>(m_nChannels)) + if(pixPlayPanning && zxxCountLeft + zxxCountRight >= GetNumChannels() && (-zxxCountLeft + zxxCountRight) < static_cast<int>(GetNumChannels())) { // There are enough Zxx commands, so let's assume this was made to be played with PixPlay Patterns.ForEachModCommand([](ModCommand &m) @@ -713,7 +713,7 @@ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, }; - if(m_nChannels == 0) + if(GetNumChannels() == 0) { return false; } Modified: trunk/OpenMPT/soundlib/Load_stk.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_stk.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_stk.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -185,7 +185,7 @@ MODFileHeader &fileHeader = fileHeaders.fileHeader; ReadOrderFromArray(Order(), fileHeader.orderList); - PATTERNINDEX numPatterns = GetNumPatterns(file, Order(), fileHeader.numOrders, totalSampleLen, m_nChannels, 0, true); + PATTERNINDEX numPatterns = GetNumPatterns(file, *this, fileHeader.numOrders, totalSampleLen, 0, true); // Most likely just a file with lots of NULs at the start if(fileHeader.restartPos == 0 && fileHeader.numOrders == 0 && numPatterns <= 1) Modified: trunk/OpenMPT/soundlib/Load_stp.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_stp.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_stp.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -376,7 +376,7 @@ channels = file.ReadUint16BE(); if(channels > MAX_BASECHANNELS) return false; - m_nChannels = std::max(m_nChannels, channels); + ChnSettings.resize(std::max(GetNumChannels(), channels)); file.Skip(channels * patternLength * 4u); } @@ -628,7 +628,7 @@ } // after we know how many channels there really are... - m_nSamplePreAmp = 256 / m_nChannels; + m_nSamplePreAmp = 256 / GetNumChannels(); // Setup channel pan positions and volume SetupMODPanning(true); Modified: trunk/OpenMPT/soundlib/Load_symmod.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_symmod.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_symmod.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1011,7 +1011,7 @@ m_SongFlags.set(SONG_LINEARSLIDES | SONG_EXFILTERRANGE | SONG_IMPORTED); m_playBehaviour = GetDefaultPlaybackBehaviour(MOD_TYPE_IT); m_playBehaviour.reset(kITShortSampleRetrig); - m_nSamplePreAmp = Clamp(512 / m_nChannels, 16, 128); + m_nSamplePreAmp = Clamp(512 / GetNumChannels(), 16, 128); enum class ChunkType : int32 { @@ -1307,7 +1307,7 @@ std::map<SymEvent, uint8> macroMap; bool useDSP = false; - const uint32 patternSize = m_nChannels * trackLen; + const uint32 patternSize = GetNumChannels() * trackLen; const PATTERNINDEX numPatterns = mpt::saturate_cast<PATTERNINDEX>(patternData.size() / patternSize); Patterns.ResizeArray(numPatterns); @@ -1335,7 +1335,7 @@ uint16 retriggerRemain = 0; uint16 tonePortaRemain = 0; }; - std::vector<ChnState> chnStates(m_nChannels); + std::vector<ChnState> chnStates(GetNumChannels()); // In Symphonie, sequences represent the structure of a song, and not separate songs like in OpenMPT. Hence they will all be loaded into the same ModSequence. for(SymSequence &seq : sequences) @@ -1382,14 +1382,14 @@ uint8 patternSpeed = static_cast<uint8>(pos.speed); // This may intentionally read into the next pattern - auto srcEvent = patternData.cbegin() + (pos.pattern * patternSize) + (pos.start * m_nChannels); + auto srcEvent = patternData.cbegin() + (pos.pattern * patternSize) + (pos.start * GetNumChannels()); const SymEvent emptyEvent{}; ModCommand syncPlayCommand; for(ROWINDEX row = 0; row < pos.length; row++) { ModCommand *rowBase = Patterns[patternIndex].GetpModCommand(row, 0); bool applySyncPlay = false; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ModCommand &m = rowBase[chn]; const SymEvent &event = (srcEvent != patternData.cend()) ? *srcEvent : emptyEvent; @@ -1539,7 +1539,7 @@ } // Key-On commands with stereo instruments are played on both channels - unless there's already some sort of event - if(event.note > 0 && (chn < m_nChannels - 1) && !(chn % 2u) + if(event.note > 0 && (chn < GetNumChannels() - 1) && !(chn % 2u) && origInst < instruments.size() && instruments[origInst].channel == SymInstrument::StereoL) { ModCommand &next = rowBase[chn + 1]; @@ -1689,7 +1689,7 @@ m.command = CMD_CHANNELVOLUME; m.param = chnState.calculatedVol = static_cast<uint8>(Util::muldivr_unsigned(chnState.lastVol, chnState.channelVol, 100)); } - if(event.note == 4 && chn < (m_nChannels - 1) && chnStates[chn + 1].channelVol != volR) + if(event.note == 4 && chn < (GetNumChannels() - 1) && chnStates[chn + 1].channelVol != volR) { chnStates[chn + 1].channelVol = volR; @@ -1902,7 +1902,7 @@ if(useDSP) { SNDMIXPLUGIN &plugin = m_MixPlugins[0]; - plugin.Destroy(); + mpt::reconstruct(plugin); memcpy(&plugin.Info.dwPluginId1, "SymM", 4); memcpy(&plugin.Info.dwPluginId2, "Echo", 4); plugin.Info.routingFlags = SNDMIXPLUGININFO::irAutoSuspend; Modified: trunk/OpenMPT/soundlib/Load_ult.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_ult.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_ult.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -347,7 +347,7 @@ ReadOrderFromFile<uint8>(Order(), file, 256, 0xFF, 0xFE); if(CHANNELINDEX numChannels = file.ReadUint8() + 1u; numChannels <= MAX_BASECHANNELS) - m_nChannels = numChannels; + ChnSettings.resize(numChannels); else return false; @@ -355,7 +355,6 @@ for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { - mpt::reconstruct(ChnSettings[chn]); if(fileHeader.version >= '3') ChnSettings[chn].nPan = ((file.ReadUint8() & 0x0F) << 4) + 8; else @@ -370,7 +369,7 @@ } bool postFixSpeedCommands = false; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ModCommand evnote; for(PATTERNINDEX pat = 0; pat < numPats && file.CanRead(5); pat++) Modified: trunk/OpenMPT/soundlib/Load_wav.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_wav.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_wav.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -114,7 +114,7 @@ Order().SetDefaultTempoInt(125); m_SongFlags = SONG_LINEARSLIDES; - for(CHANNELINDEX channel = 0; channel < m_nChannels; channel++) + for(CHANNELINDEX channel = 0; channel < GetNumChannels(); channel++) { ChnSettings[channel].nPan = (channel % 2u) ? 256 : 0; } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_xm.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -1152,8 +1152,8 @@ fileHeader.size = sizeof(XMFileHeader) - 60; // minus everything before this field fileHeader.restartPos = Order().GetRestartPos(); - fileHeader.channels = m_nChannels; - if((m_nChannels % 2u) && m_nChannels < 32) + fileHeader.channels = GetNumChannels(); + if((GetNumChannels() % 2u) && GetNumChannels() < 32) { // Avoid odd channel count for FT2 compatibility fileHeader.channels++; @@ -1243,10 +1243,10 @@ // Empty patterns are always loaded as 64-row patterns in FT2, regardless of their real size... bool emptyPattern = true; - for(size_t j = m_nChannels * numRows; j > 0; j--, p++) + for(size_t j = GetNumChannels() * numRows; j > 0; j--, p++) { // Don't write more than 32 channels - if(compatibilityExport && m_nChannels - ((j - 1) % m_nChannels) > 32) continue; + if(compatibilityExport && GetNumChannels() - ((j - 1) % GetNumChannels()) > 32) continue; uint8 note = p->note, command = 0, param = 0; ModSaveCommand(*p, command, param, true, compatibilityExport); @@ -1325,7 +1325,7 @@ if (b & 16) s[len++] = param; } - if(addChannel && (j % m_nChannels == 1 || m_nChannels == 1)) + if(addChannel && (j % GetNumChannels() == 1 || GetNumChannels() == 1)) { ASSERT_CAN_WRITE(1); s[len++] = 0x80; @@ -1489,7 +1489,7 @@ // Writing Channel Names { CHANNELINDEX numNamedChannels = 0; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { if (ChnSettings[chn].szName[0]) numNamedChannels = chn + 1; } Modified: trunk/OpenMPT/soundlib/Load_xmf.cpp ============================================================================== --- trunk/OpenMPT/soundlib/Load_xmf.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/Load_xmf.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -189,10 +189,10 @@ file.Skip(1); // Channel count already read const PATTERNINDEX numPatterns = file.ReadUint8() + 1u; - if(!file.CanRead(m_nChannels + numPatterns * m_nChannels * 64 * 6)) + if(!file.CanRead(GetNumChannels() + numPatterns * GetNumChannels() * 64 * 6)) return false; - for(CHANNELINDEX chn = 0; chn < m_nChannels; chn++) + for(CHANNELINDEX chn = 0; chn < GetNumChannels(); chn++) { ChnSettings[chn].nPan = file.ReadUint8() * 0x11; } @@ -202,7 +202,7 @@ { if(!(loadFlags & loadPatternData) || !Patterns.Insert(pat, 64)) { - file.Skip(m_nChannels * 64 * 6); + file.Skip(GetNumChannels() * 64 * 6); continue; } ModCommand dummy; Modified: trunk/OpenMPT/soundlib/MODTools.cpp ============================================================================== --- trunk/OpenMPT/soundlib/MODTools.cpp Sat Jun 8 01:19:39 2024 (r20949) +++ trunk/OpenMPT/soundlib/MODTools.cpp Sat Jun 8 02:16:59 2024 (r20950) @@ -381,8 +381,9 @@ // Parse the order list to determine how many patterns are used in the file. -PATTERNINDEX GetNumPatterns(FileReader &file, ModSequence &Order, ORDERINDEX numOrders, SmpLength totalSampleLen, CHANNELINDEX &numChannels, SmpLength wowSampleLen, bool validateHiddenPatterns) +PATTERNINDEX GetNumPatterns(FileReader &file, CSoundFile &sndFile, ORDERINDEX numOrders, SmpLength totalSampleLen, SmpLength wowSampleLen, bool validateHiddenPatterns) { + ModSequence &Order = sndFile.Order(); PATTERNINDEX numPatterns = 0; // Total number of patterns in file (determined by going through the whole order list) with pattern number < 128 PATTERNINDEX officialPatterns = 0; // Number of patterns only found in the "official" part of the order list (i.e. order positions < claimed order length) PATTERNINDEX numPatternsIllegal = 0; // Total number of patterns in file, also counting in "invalid" pattern indexes >= 128 @@ -409,7 +410,7 @@ const size_t patternStartOffset = file.GetPosition(); const size_t sizeWithoutPatterns = totalSampleLen + patternStartOffset; - const size_t sizeWithOfficialPatterns = sizeWithoutPatterns + officialPatterns * numChannels * 256; + const size_t sizeWithOfficialPatterns = sizeWithoutPatterns + officialPatterns * sndFile.GetNumChannels() * 256; if(wowSampleLen && (wowSampleLen + patternStartOffset) + numPatterns * 8 * 256 == (file.GetLength() & ~1)) { @@ -418,7 +419,7 @@ // (e.g. ponylips.mod, MD5 c039af363b1d99a492dafc5b5f9dd949, SHA1 1bee1941c47bc6f913735ce0cf1880b248b8fc93) file.Seek(patternStartOffset + numPatterns * 4 * 256); ... [truncated message content] |