22#ifndef TOWNS_PC98_FMSYNTH_H
23#define TOWNS_PC98_FMSYNTH_H
25#include "audio/audiostream.h"
26#include "audio/mixer.h"
27#include "common/mutex.h"
28#include "common/func.h"
29#include "common/array.h"
38#define DISABLE_PC98_RHYTHM_CHANNEL
53class TownsPC98_FmSynthOperator;
54class TownsPC98_FmSynthSquareWaveSource;
55#ifndef DISABLE_PC98_RHYTHM_CHANNEL
56class TownsPC98_FmSynthPercussionSource;
81 void writeReg(uint8 part, uint8 regAddress, uint8 value);
82 uint8 readReg(uint8 part, uint8 regAddress);
85 int readBuffer(int16 *buffer,
const int numSamples)
override;
95 virtual void nextTickEx(int32 *buffer, uint32 bufferSize) {}
97 virtual void timerCallbackA() = 0;
98 virtual void timerCallbackB() = 0;
105 void setVolumeIntern(
int volA,
int volB);
106 void setVolumeChannelMasks(
int channelMaskA,
int channelMaskB);
109 void setLevelSSG(
int vol);
113 const bool _hasPercussion;
116 int _mixerThreadLockCounter;
119 void generateTables();
120 void writeRegInternal(uint8 part, uint8 regAddress, uint8 value);
121 void nextTick(int32 *buffer, uint32 bufferSize);
123#ifdef ENABLE_SNDTOWNS98_WAITCYCLES
124 void startWaitCycle();
127 struct ChanInternal {
128 ChanInternal() =
default;
129 ChanInternal(
const ChanInternal &) =
delete;
130 ChanInternal(ChanInternal &&) =
delete;
131 ChanInternal &operator=(
const ChanInternal &) =
delete;
132 ChanInternal &operator=(ChanInternal &&) =
delete;
135 void ampModSensitivity(uint32 value) {
136 ampModSvty = (1 << (3 - value)) - (((value >> 1) & 1) | (value & 1));
138 void frqModSensitivity(uint32 value) {
139 frqModSvty = value << 5;
142 feedbuf[0] = feedbuf[1] = feedbuf[2] = 0;
145 bool enableLeft =
false;
146 bool enableRight =
false;
147 bool updateEnvelopeParameters =
false;
148 int32 feedbuf[3] = {};
149 uint8 algorithm = 0u;
151 uint32 ampModSvty = 0u;
152 uint32 frqModSvty = 0u;
154 TownsPC98_FmSynthOperator *opr[4] = {};
157 TownsPC98_FmSynthSquareWaveSource *_ssg;
158#ifndef DISABLE_PC98_RHYTHM_CHANNEL
159 TownsPC98_FmSynthPercussionSource *_prc;
161 ChanInternal *_chanInternal;
164 uint8 *_oprRateshift;
165 uint8 *_oprAttackDecay;
172 ChipTimerProc *_timerProcIdle;
173 ChipTimerProc *_timerProcA;
174 ChipTimerProc *_timerProcB;
175 void idleTimerCallback() {}
189 ChipTimer _timers[2];
191 int _volMaskA, _volMaskB;
192 uint16 _volumeA, _volumeB;
194 int32 *_renderBuffer;
195 int _renderBufferSize;
202 const int _internalRate;
203 const int _outputRate;
205#ifdef ENABLE_SNDTOWNS98_WAITCYCLES
206 int _waitCycleRemainder;
207 const int _samplesPerWaitCycle;
210 RegEntry(uint8 p, uint8 r, uint8 v) : part(p), reg(r), val(v) {}
219 uint8 _registers[255][2];
224#ifndef DISABLE_PC98_RHYTHM_CHANNEL
225 static const uint8 _percussionData[];
227 static const uint32 _adtStat[];
228 static const uint8 _detSrc[];
229 static const int _ssgTables[];
Definition: audiostream.h:50
Definition: towns_pc98_fmsynth.h:67
bool isStereo() const override
int getRate() const override
bool endOfData() const override
int readBuffer(int16 *buffer, const int numSamples) override