AppleWin/source/SSI263.h
TomCh 71c67cf132
Refactor Mockingboard into a class (#1171)
Mockingboard or Phasor cards can be inserted into any slot.
Change Config->Sound to that slots 4+5 to be individually selected for the 3 soundcard types.
Add MockingboardCardManager class to manage multiple cards and mix the sound buffers.
2023-01-28 18:15:28 +00:00

149 lines
3.2 KiB
C++

#pragma once
#include "MockingboardDefs.h"
class SSI263
{
public:
SSI263(UINT slot) : m_slot(slot)
{
m_device = -1; // undefined
m_cardMode = PH_Mockingboard;
m_pPhonemeData00 = NULL;
ResetState();
}
~SSI263(void)
{
delete [] m_pPhonemeData00;
}
void ResetState(void)
{
m_currentActivePhoneme = -1;
m_isVotraxPhoneme = false;
m_cyclesThisAudioFrame = 0;
//
m_lastUpdateCycle = 0;
m_updateWasFullSpeed = false;
m_pPhonemeData = NULL;
m_phonemeLengthRemaining = 0;
m_phonemeAccurateLengthRemaining = 0;
m_phonemePlaybackAndDebugger = false;
m_phonemeCompleteByFullSpeed = false;
//
m_numSamplesError = 0;
m_byteOffset = (DWORD)-1;
m_currSampleSum = 0;
m_currNumSamples = 0;
m_currSampleMod4 = 0;
//
m_durationPhoneme = 0;
m_inflection = 0;
m_rateInflection = 0;
m_ctrlArtAmp = 0;
m_filterFreq = 0;
m_currentMode = 0;
//
m_dbgFirst = true;
m_dbgStartTime = 0;
}
void SetDevice(UINT device) { m_device = device; }
void SetCardMode(PHASOR_MODE mode) { m_cardMode = mode; }
bool DSInit(void);
void DSUninit(void);
void Reset(void);
bool IsPhonemeActive(void) { return m_currentActivePhoneme >= 0; }
BYTE Read(ULONG nExecutedCycles);
void Write(BYTE nReg, BYTE nValue);
void Mute(void);
void Unmute(void);
void SetVolume(DWORD dwVolume, DWORD dwVolumeMax);
void PeriodicUpdate(UINT executedCycles);
void Update(void);
void SetSpeechIRQ(void);
void Votrax_Write(BYTE nValue);
bool GetVotraxPhoneme(void) { return m_isVotraxPhoneme; }
void SetVotraxPhoneme(bool value) { m_isVotraxPhoneme = value; }
void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper);
void LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, PHASOR_MODE mode, UINT version);
private:
void Play(unsigned int nPhoneme);
void Stop(void);
void UpdateIRQ(void);
void UpdateAccurateLength(void);
UINT64 GetLastCumulativeCycles(void);
void UpdateIFR(BYTE nDevice, BYTE clr_mask, BYTE set_mask);
BYTE GetPCR(BYTE nDevice);
static const BYTE m_Votrax2SSI263[/*64*/];
static const unsigned short m_kNumChannels = 1;
static const DWORD m_kDSBufferByteSize = MAX_SAMPLES * sizeof(short) * m_kNumChannels;
short m_mixBufferSSI263[m_kDSBufferByteSize / sizeof(short)];
VOICE SSI263SingleVoice;
//
UINT m_slot;
BYTE m_device; // SSI263 device# which is generating phoneme-complete IRQ (and only required whilst Mockingboard isn't a class)
PHASOR_MODE m_cardMode;
short* m_pPhonemeData00;
int m_currentActivePhoneme;
bool m_isVotraxPhoneme;
UINT m_cyclesThisAudioFrame;
//
UINT64 m_lastUpdateCycle;
bool m_updateWasFullSpeed;
const short* m_pPhonemeData;
UINT m_phonemeLengthRemaining; // length in samples, decremented as space becomes available in the ring-buffer
UINT m_phonemeAccurateLengthRemaining; // length in samples, decremented by cycles executed
bool m_phonemePlaybackAndDebugger;
bool m_phonemeCompleteByFullSpeed;
//
int m_numSamplesError;
DWORD m_byteOffset;
int m_currSampleSum;
int m_currNumSamples;
UINT m_currSampleMod4;
// Regs:
BYTE m_durationPhoneme;
BYTE m_inflection; // I10..I3
BYTE m_rateInflection;
BYTE m_ctrlArtAmp;
BYTE m_filterFreq;
BYTE m_currentMode; // b7:6=Mode; b0=D7 pin (for IRQ)
// Debug
bool m_dbgFirst;
UINT64 m_dbgStartTime;
};