mirror of
https://github.com/AppleWin/AppleWin.git
synced 2024-12-22 09:30:15 +00:00
71c67cf132
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.
149 lines
3.2 KiB
C++
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;
|
|
};
|