#pragma once
#include "BuildSettings.h"
#include "ModSample.h"
#include "ModInstrument.h"
#include "modcommand.h"
#include "Paula.h"
OPENMPT_NAMESPACE_BEGIN
class CSoundFile;
struct ModChannel
{
struct EnvInfo
{
FlagSet<EnvelopeFlags> flags;
uint32 nEnvPosition;
int32 nEnvValueAtReleaseJump;
void Reset()
{
nEnvPosition = 0;
nEnvValueAtReleaseJump = NOT_YET_RELEASED;
}
};
SamplePosition position; SamplePosition increment; const void *pCurrentSample; int32 leftVol; int32 rightVol; int32 leftRamp; int32 rightRamp; int32 rampLeftVol; int32 rampRightVol; mixsample_t nFilter_Y[2][2]; mixsample_t nFilter_A0, nFilter_B0, nFilter_B1; mixsample_t nFilter_HP;
SmpLength nLength;
SmpLength nLoopStart;
SmpLength nLoopEnd;
FlagSet<ChannelFlags> dwFlags;
mixsample_t nROfs, nLOfs;
uint32 nRampLength;
const ModSample *pModSample; Paula::State paulaState;
const ModInstrument *pModInstrument; SmpLength prevNoteOffset; SmpLength oldOffset;
FlagSet<ChannelFlags> dwOldFlags; int32 newLeftVol, newRightVol;
int32 nRealVolume, nRealPan;
int32 nVolume, nPan, nFadeOutVol;
int32 nPeriod, nC5Speed, nPortamentoDest;
int32 cachedPeriod, glissandoPeriod;
int32 nCalcVolume; EnvInfo VolEnv, PanEnv, PitchEnv; int32 nGlobalVol; int32 nInsVol; int32 nFineTune, nTranspose;
int32 nPortamentoSlide, nAutoVibDepth;
uint32 nEFxOffset; int16 nVolSwing, nPanSwing;
int16 nCutSwing, nResSwing;
int16 nRestorePanOnNewNote; int16 nRetrigCount, nRetrigParam;
ROWINDEX nPatternLoop;
CHANNELINDEX nMasterChn;
ModCommand rowCommand;
uint8 resamplingMode;
uint8 nRestoreResonanceOnNewNote; uint8 nRestoreCutoffOnNewNote; uint8 nNote;
NewNoteAction nNNA;
uint8 nLastNote; uint8 nArpeggioLastNote, nArpeggioBaseNote; uint8 nNewNote, nNewIns, nOldIns, nCommand, nArpeggio;
uint8 nOldVolumeSlide, nOldFineVolUpDown;
uint8 nOldPortaUp, nOldPortaDown, nOldFinePortaUpDown, nOldExtraFinePortaUpDown;
uint8 nOldPanSlide, nOldChnVolSlide;
uint8 nOldGlobalVolSlide;
uint8 nAutoVibPos, nVibratoPos, nTremoloPos, nPanbrelloPos;
uint8 nVibratoType, nVibratoSpeed, nVibratoDepth;
uint8 nTremoloType, nTremoloSpeed, nTremoloDepth;
uint8 nPanbrelloType, nPanbrelloSpeed, nPanbrelloDepth;
int8 nPanbrelloOffset, nPanbrelloRandomMemory;
uint8 nOldCmdEx, nOldVolParam, nOldTempo;
uint8 nOldHiOffset;
uint8 nCutOff, nResonance;
uint8 nTremorCount, nTremorParam;
uint8 nPatternLoopCount;
uint8 nLeftVU, nRightVU;
uint8 nActiveMacro, nFilterMode;
uint8 nEFxSpeed, nEFxDelay; uint8 nNoteSlideCounter, nNoteSlideSpeed, nNoteSlideStep; uint8 lastZxxParam; bool isFirstTick : 1;
bool isPreviewNote : 1;
bool m_ReCalculateFreqOnFirstTick : 1;
bool m_CalculateFreq : 1;
int32 m_PortamentoFineSteps, m_PortamentoTickSlide;
uint32 m_Freq;
float m_plugParamValueStep, m_plugParamTargetValue;
uint16 m_RowPlugParam;
PLUGINDEX m_RowPlug;
void ClearRowCmd() { rowCommand = ModCommand(); }
const EnvInfo &GetEnvelope(EnvelopeType envType) const
{
switch(envType)
{
case ENV_VOLUME:
default:
return VolEnv;
case ENV_PANNING:
return PanEnv;
case ENV_PITCH:
return PitchEnv;
}
}
EnvInfo &GetEnvelope(EnvelopeType envType)
{
return const_cast<EnvInfo &>(static_cast<const ModChannel *>(this)->GetEnvelope(envType));
}
void ResetEnvelopes()
{
VolEnv.Reset();
PanEnv.Reset();
PitchEnv.Reset();
}
enum ResetFlags
{
resetChannelSettings = 1, resetSetPosBasic = 2, resetSetPosAdvanced = 4, resetSetPosFull = resetSetPosBasic | resetSetPosAdvanced | resetChannelSettings, resetTotal = resetSetPosFull,
};
void Reset(ResetFlags resetMask, const CSoundFile &sndFile, CHANNELINDEX sourceChannel);
void Stop();
bool IsSamplePlaying() const { return !increment.IsZero(); }
uint32 GetVSTVolume() { return (pModInstrument) ? pModInstrument->nGlobalVol * 4 : nVolume; }
ModCommand::NOTE GetPluginNote(bool realNoteMapping) const;
bool HasMIDIOutput() const { return pModInstrument != nullptr && pModInstrument->HasValidMIDIChannel(); }
bool InSustainLoop() const { return (dwFlags & (CHN_LOOP | CHN_KEYOFF)) == CHN_LOOP && pModSample->uFlags[CHN_SUSTAINLOOP]; }
void UpdateInstrumentVolume(const ModSample *smp, const ModInstrument *ins);
};
struct ModChannelSettings
{
FlagSet<ChannelFlags> dwFlags; uint16 nPan; uint16 nVolume; PLUGINDEX nMixPlugin; char szName[MAX_CHANNELNAME];
ModChannelSettings()
{
Reset();
}
void Reset()
{
dwFlags.reset();
nPan = 128;
nVolume = 64;
nMixPlugin = 0;
szName[0] = '\0';
}
};
OPENMPT_NAMESPACE_END