diff --git a/Source/Channels6581.cpp b/Source/Channels6581.cpp index c125fe7..dac5cac 100644 --- a/Source/Channels6581.cpp +++ b/Source/Channels6581.cpp @@ -38,6 +38,10 @@ // Static member variables, for the shared stuff in 6581 unsigned char CChannelHandler6581::s_iGlobalVolume = 15; +unsigned char CChannelHandler6581::s_iFilterResonance = 0; +unsigned int CChannelHandler6581::s_iFilterCutoff = 0; +unsigned char CChannelHandler6581::s_iFilterMode = 0; +unsigned char CChannelHandler6581::s_iFilterEnable = 0; // Class functions @@ -82,6 +86,26 @@ bool CChannelHandler6581::HandleEffect(effect_t EffNum, unsigned char EffParam) m_iPulseWidth = EffParam * 16; break; } + case EF_SID_FILTER_RESONANCE: { + s_iFilterResonance = EffParam & 0xF; + break; + } + case EF_SID_FILTER_CUTOFF_HI: { + s_iFilterCutoff = (s_iFilterCutoff & 0xFF) | ((EffParam & 0xF) << 8); + break; + } + case EF_SID_FILTER_CUTOFF_LO: { + s_iFilterCutoff = (s_iFilterCutoff & 0xF00) | (EffParam & 0xFF); + break; + } + case EF_SID_FILTER_MODE: { + s_iFilterMode = EffParam & 0xF; + if (EffParam == 0) + s_iFilterEnable &= ~(1U << (m_iChannelID - CHANID_6581_CH1)); + else + s_iFilterEnable |= (1U << (m_iChannelID - CHANID_6581_CH1)); + break; + } default: return CChannelHandler::HandleEffect(EffNum, EffParam); } @@ -116,6 +140,7 @@ void CChannelHandler6581::HandleNoteData(stChanNote* pNoteData, int EffColumns) void CChannelHandler6581::HandleEmptyNote() { + } void CChannelHandler6581::HandleCut() @@ -166,6 +191,10 @@ void CChannelHandler6581::ResetChannel() m_iTestBit = 0; m_iGateCounter = 0; s_iGlobalVolume = 15; + s_iFilterResonance = 0; + s_iFilterCutoff = 0; + s_iFilterMode = 0; + s_iFilterEnable = 0; m_iEnvAD = 0; m_iEnvSR = 0; SetLinearPitch(true); @@ -248,7 +277,10 @@ void CChannelHandler6581::RefreshChannel() WriteReg(0x02 + Offset, LoPW); WriteReg(0x03 + Offset, HiPW); WriteReg(0x04 + Offset, Waveform); - WriteReg(0x18, s_iGlobalVolume); + WriteReg(0x15, (s_iFilterCutoff & 0xF00) >> 8); + WriteReg(0x16, s_iFilterCutoff & 0x0FF); + WriteReg(0x17, (s_iFilterResonance << 4) | s_iFilterEnable); + WriteReg(0x18, (s_iFilterMode << 4) | s_iGlobalVolume); } diff --git a/Source/Channels6581.h b/Source/Channels6581.h index 5e911db..b1169af 100644 --- a/Source/Channels6581.h +++ b/Source/Channels6581.h @@ -60,6 +60,10 @@ class CChannelHandler6581 : public CChannelHandler, public CChannelHandlerInterf // Static memebers protected: static unsigned char s_iGlobalVolume; + static unsigned char s_iFilterResonance; + static unsigned int s_iFilterCutoff; + static unsigned char s_iFilterMode; + static unsigned char s_iFilterEnable; // Instance members protected: diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index 44e8799..e5f4a4c 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -5041,6 +5041,7 @@ stFullState *CFamiTrackerDoc::RetrieveSoundState(unsigned int Track, unsigned in case EF_N163_WAVE_BUFFER: case EF_VRC7_PORT: case EF_SAA_NOISE_MODE: + case EF_SID_FILTER_RESONANCE: case EF_SID_FILTER_CUTOFF_HI: case EF_SID_FILTER_CUTOFF_LO: case EF_SID_FILTER_MODE: if (!ch->IsEffectCompatible(fx, xy)) continue; case EF_DUTY_CYCLE: if (ch->GetChip() == SNDCHIP_VRC7) continue; // // // 050B diff --git a/Source/FamiTrackerTypes.h b/Source/FamiTrackerTypes.h index ef2cb38..caf1338 100644 --- a/Source/FamiTrackerTypes.h +++ b/Source/FamiTrackerTypes.h @@ -178,6 +178,10 @@ enum effect_t : unsigned char { EF_PWM, // // // Pulse width modulation effect EF_VOLUME_OFFSET, // // // Relative volume change EF_SAA_NOISE_MODE, // // // SAA1099 noise mode + EF_SID_FILTER_RESONANCE, // // // SID filter resonance + EF_SID_FILTER_CUTOFF_HI, // // // SID filter cutoff hi + EF_SID_FILTER_CUTOFF_LO, // // // SID filter cutoff lo + EF_SID_FILTER_MODE, // // // SID filter mode EF_COUNT }; @@ -194,7 +198,7 @@ const effect_t N163_EFFECTS[] = {EF_N163_WAVE_BUFFER}; const effect_t S5B_EFFECTS[] = { EF_SUNSOFT_ENV_TYPE, EF_SUNSOFT_ENV_HI, EF_SUNSOFT_ENV_LO, EF_SUNSOFT_NOISE }; const effect_t AY8930_EFFECTS[] = {EF_SUNSOFT_ENV_TYPE, EF_SUNSOFT_ENV_HI, EF_SUNSOFT_ENV_LO, EF_SUNSOFT_NOISE, EF_AY8930_PULSE_WIDTH, EF_AY8930_AND_MASK, EF_AY8930_OR_MASK, EF_AY8930_VOL}; const effect_t SAA1099_EFFECTS[] = {EF_SUNSOFT_ENV_TYPE, EF_SAA_NOISE_MODE}; -const effect_t SID_EFFECTS[] = { EF_AY8930_PULSE_WIDTH }; +const effect_t SID_EFFECTS[] = { EF_AY8930_PULSE_WIDTH, EF_SID_FILTER_RESONANCE, EF_SID_FILTER_CUTOFF_HI, EF_SID_FILTER_CUTOFF_LO, EF_SID_FILTER_MODE }; // Effect checking = bool CTrackerChannel::IsEffectCompatible @@ -251,6 +255,10 @@ const char EFF_CHAR[] = { 'N', // EF_PWM, '9', // EF_VOLUME_OFFSET 'W', // EF_SAA_NOISE_MODE + 'W', // EF_SID_FILTER_RESONANCE + 'I', // EF_SID_FILTER_CUTOFF_HI + 'J', // EF_SID_FILTER_CUTOFF_LO + 'H', // EF_SID_FILTER_MODE }; struct Effect { diff --git a/Source/FamiTrackerView.cpp b/Source/FamiTrackerView.cpp index 909a71a..01294df 100644 --- a/Source/FamiTrackerView.cpp +++ b/Source/FamiTrackerView.cpp @@ -125,6 +125,10 @@ const CString EFFECT_TEXTS[] = { // // // _T("Nxx - PWM (incomplete)"), _T("9xy - Volume shift, X = amount to increase, Y = amount to decrease"), _T("Wxx - SAA1099 noise mode, 00-02 = pitch, 03 = frequency generator"), + _T("W0x - SID filter resonance"), + _T("I0x - SID filter cutoff, high byte"), + _T("Jxx - SID filter cutoff, low byte"), + _T("H0x - SID filter mode"), }; // OLE copy and mix diff --git a/Source/InstrumentEditDlg.cpp b/Source/InstrumentEditDlg.cpp index 06dfaf2..41e80b2 100644 --- a/Source/InstrumentEditDlg.cpp +++ b/Source/InstrumentEditDlg.cpp @@ -61,7 +61,7 @@ const TCHAR *CInstrumentEditDlg::CHIP_NAMES[] = { _T("FDS"), _T("Namco"), _T("S5B"), - _T("AY8930"), + _T("SID"), _T("SAA1099"), _T("5E01") }; diff --git a/Source/PatternCompiler.cpp b/Source/PatternCompiler.cpp index 4fde6a7..97bdcdd 100644 --- a/Source/PatternCompiler.cpp +++ b/Source/PatternCompiler.cpp @@ -116,6 +116,11 @@ enum command_t { CMD_EFF_SAA_NOISE_MODE, + CMD_EFF_SID_FILTER_RESONANCE, + CMD_EFF_SID_FILTER_CUTOFF_HI, + CMD_EFF_SID_FILTER_CUTOFF_LO, + CMD_EFF_SID_FILTER_MODE, + CMD_EFF_PWM, CMD_EFF_VOLUME_OFFSET, }; @@ -672,6 +677,30 @@ void CPatternCompiler::CompileData(int Track, int Pattern, int Channel) WriteData(EffParam & 0x03); } break; + case EF_SID_FILTER_RESONANCE: // // // 050B + if (ChipID == SNDCHIP_6581) { + WriteData(Command(CMD_EFF_SID_FILTER_RESONANCE)); + WriteData(EffParam & 0x0F); + } + break; + case EF_SID_FILTER_CUTOFF_HI: // // // 050B + if (ChipID == SNDCHIP_6581) { + WriteData(Command(CMD_EFF_SID_FILTER_CUTOFF_HI)); + WriteData(EffParam & 0x0F); + } + break; + case EF_SID_FILTER_CUTOFF_LO: // // // 050B + if (ChipID == SNDCHIP_6581) { + WriteData(Command(CMD_EFF_SID_FILTER_CUTOFF_LO)); + WriteData(EffParam & 0xFF); + } + break; + case EF_SID_FILTER_MODE: // // // 050B + if (ChipID == SNDCHIP_6581) { + WriteData(Command(CMD_EFF_SID_FILTER_MODE)); + WriteData(EffParam & 0x0F); + } + break; // // // N163 case EF_N163_WAVE_BUFFER: if (ChipID == SNDCHIP_N163 && EffParam <= 0x7F) { diff --git a/Source/TrackerChannel.cpp b/Source/TrackerChannel.cpp index d940290..5d7a1f5 100644 --- a/Source/TrackerChannel.cpp +++ b/Source/TrackerChannel.cpp @@ -247,6 +247,10 @@ bool CTrackerChannel::IsEffectCompatible(effect_t EffNumber, int EffParam) const return m_iChip == SNDCHIP_AY8930 && EffParam <= 0x01; case EF_SAA_NOISE_MODE: return m_iChip == SNDCHIP_SAA1099 && EffParam <= 0x03; + case EF_SID_FILTER_RESONANCE: case EF_SID_FILTER_CUTOFF_HI: case EF_SID_FILTER_MODE: + return (m_iChip == SNDCHIP_6581 && EffParam <= 0x0F); + case EF_SID_FILTER_CUTOFF_LO: + return m_iChip == SNDCHIP_6581; case EF_N163_WAVE_BUFFER: return m_iChip == SNDCHIP_N163 && EffParam <= 0x7F; case EF_FDS_VOLUME: