#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; };