aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorFlorian Kagerer2008-08-18 17:42:32 +0000
committerFlorian Kagerer2008-08-18 17:42:32 +0000
commit92f545ba6624331f5d4a37ef9413097cb1d6ec30 (patch)
tree643dca15cefdb39632c1f8ceeaf7b7c5661120ad /engines/kyra
parentb809665671bd954faaa334677d877a37e961a0aa (diff)
downloadscummvm-rg350-92f545ba6624331f5d4a37ef9413097cb1d6ec30.tar.gz
scummvm-rg350-92f545ba6624331f5d4a37ef9413097cb1d6ec30.tar.bz2
scummvm-rg350-92f545ba6624331f5d4a37ef9413097cb1d6ec30.zip
KYRA: FM-Towns/PC-98 Audio:
- adpcm decoding for rhythm channel - cleanup svn-id: r33993
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/sound_towns.cpp367
1 files changed, 201 insertions, 166 deletions
diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp
index dd65fa644f..8678498855 100644
--- a/engines/kyra/sound_towns.cpp
+++ b/engines/kyra/sound_towns.cpp
@@ -1535,31 +1535,35 @@ public:
TownsPC98_OpnPercussionSource(const float rate);
~TownsPC98_OpnPercussionSource();
- void init(uint8 *pcmData);
+ void init(const void *pcmData = 0);
void reset();
void writeReg(uint8 address, uint8 value);
void nextTick(int32 *buffer, uint32 bufferSize);
private:
- void recalcLevel(int instrument);
+ struct PcmInstrument {
+ const uint8 *data;
- struct Pcm_Instrument {
- const int16 *data;
-
- const int16 *start;
- const int16 *end;
- const int16 *pos;
+ const uint8 *start;
+ const uint8 *end;
+ const uint8 *pos;
uint32 size;
-
bool active;
uint8 level;
+
+ int8 decState;
+ uint8 decStep;
+
+ int16 samples[2];
int out;
};
- Pcm_Instrument _pcmInstr[6];
+ void recalcOuput(PcmInstrument *ins);
+ void advanceInput(PcmInstrument *ins);
+
+ PcmInstrument _pcmInstr[6];
uint8 _regs[48];
- uint8 *_rsamples;
uint8 _totalLevel;
@@ -1583,7 +1587,7 @@ public:
TownsPC98_OpnDriver(Audio::Mixer *mixer, OpnType type);
~TownsPC98_OpnDriver();
- bool init(uint8 *pcmData = 0);
+ bool init();
void loadMusicData(uint8 *data, bool loadPaused = false);
void loadSoundEffectData(uint8 *data, uint8 trackNum);
@@ -2239,11 +2243,12 @@ bool TownsPC98_OpnChannel::control_f8_togglePitchWheel(uint8 para) {
_flags |= CHS_PITCHWHEELOFF;
}
} else {
- //uint8 skipChannels = para / 36;
- //uint8 entry = para % 36;
- //TownsPC98_OpnDriver::TownsPC98_OpnChannel *t = &chan[skipChannels];
- ////// NOT IMPLEMENTED
- //t->unnamedEntries[entry] = *_dataPtr++;
+ /* NOT IMPLEMENTED
+ uint8 skipChannels = para / 36;
+ uint8 entry = para % 36;
+ TownsPC98_OpnDriver::TownsPC98_OpnChannel *t = &chan[skipChannels];
+
+ t->unnamedEntries[entry] = *_dataPtr++;*/
}
return true;
}
@@ -2746,9 +2751,6 @@ void TownsPC98_OpnSquareSineSource::init(const int *rsTable, const int *rseTable
_tleTable[i] = (int32) v;
}
- //_mixer->playInputStream(Audio::Mixer::kMusicSoundType,
- // &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true);
-
_ready = true;
}
@@ -2806,34 +2808,33 @@ void TownsPC98_OpnSquareSineSource::updatesRegs() {
}
TownsPC98_OpnPercussionSource::TownsPC98_OpnPercussionSource(const float rate) :
- _tickLength((int)(rate * 65536.0)), _rsamples(0), _timer(0), _ready(false) {
- memset(_pcmInstr, 0, sizeof(Pcm_Instrument) * 6);
+ _tickLength((int)(rate * 65536.0)), _timer(0), _ready(false) {
+ memset(_pcmInstr, 0, sizeof(PcmInstrument) * 6);
}
TownsPC98_OpnPercussionSource::~TownsPC98_OpnPercussionSource() {
- delete [] _rsamples;
}
-void TownsPC98_OpnPercussionSource::init(uint8 *pcmData) {
+void TownsPC98_OpnPercussionSource::init(const void *pcmData) {
if (_ready) {
reset();
return;
}
- _rsamples = pcmData;
- if (_rsamples) {
+ const uint8 *start = (const uint8*) pcmData;
+ const uint8 *pos = start;
+
+ if (pcmData) {
for (int i = 0; i < 6; i++) {
- _pcmInstr[i].data = (const int16*) (_rsamples + READ_BE_UINT16(pcmData));
- pcmData += 2;
- _pcmInstr[i].size = READ_BE_UINT16(pcmData) >> 1;
- pcmData += 2;
+ _pcmInstr[i].data = start + READ_BE_UINT16(pos);
+ pos += 2;
+ _pcmInstr[i].size = READ_BE_UINT16(pos);
+ pos += 2;
}
-
reset();
-
_ready = true;
} else {
- memset(_pcmInstr, 0, sizeof(Pcm_Instrument) * 6);
+ memset(_pcmInstr, 0, sizeof(PcmInstrument) * 6);
_ready = false;
}
}
@@ -2845,12 +2846,15 @@ void TownsPC98_OpnPercussionSource::reset() {
memset(_regs, 0, 48);
for (int i = 0; i < 6; i++) {
- Pcm_Instrument *s = &_pcmInstr[i];
+ PcmInstrument *s = &_pcmInstr[i];
s->pos = s->start = s->data;
s->end = s->data + s->size;
s->active = false;
s->level = 0;
s->out = 0;
+ s->decStep = 1;
+ s->decState = 0;
+ s->samples[0] = s->samples[1] = 0;
}
}
@@ -2874,9 +2878,13 @@ void TownsPC98_OpnPercussionSource::writeReg(uint8 address, uint8 value) {
//key on
for (int i = 0; i < 6; i++) {
if ((value >> i) & 1) {
- _pcmInstr[i].pos = (const int16*) _pcmInstr[i].start;
- _pcmInstr[i].active = true;
- _pcmInstr[i].out = 0;
+ PcmInstrument *s = &_pcmInstr[i];
+ s->pos = s->start;
+ s->active = true;
+ s->out = 0;
+ s->samples[0] = s->samples[1] = 0;
+ s->decStep = 1;
+ s->decState = 0;
}
}
}
@@ -2884,12 +2892,12 @@ void TownsPC98_OpnPercussionSource::writeReg(uint8 address, uint8 value) {
// total level
_totalLevel = (value & 63) ^ 63;
for (int i = 0; i < 6; i++)
- recalcLevel(i);
+ recalcOuput(&_pcmInstr[i]);
} else if (!h && l & 8) {
// instrument level
l &= 7;
_pcmInstr[l].level = (value & 0x1f) ^ 0x1f;
- recalcLevel(l);
+ recalcOuput(&_pcmInstr[l]);
} else if (h & 3) {
l &= 7;
if (h == 1) {
@@ -2912,10 +2920,15 @@ void TownsPC98_OpnPercussionSource::nextTick(int32 *buffer, uint32 bufferSize) {
_timer -= 0x30000;
for (int ii = 0; ii < 6; ii++) {
- if (_pcmInstr[ii].active) {
- recalcLevel(ii);
- if (++_pcmInstr[ii].pos == _pcmInstr[ii].end)
- _pcmInstr[ii].active = false;
+ PcmInstrument *s = &_pcmInstr[ii];
+ if (s->active) {
+ recalcOuput(s);
+ if (s->decStep) {
+ advanceInput(s);
+ if (s->pos == s->end)
+ s->active = false;
+ }
+ s->decStep ^= 1;
}
}
}
@@ -2934,12 +2947,34 @@ void TownsPC98_OpnPercussionSource::nextTick(int32 *buffer, uint32 bufferSize) {
}
}
-void TownsPC98_OpnPercussionSource::recalcLevel(int instrument) {
- Pcm_Instrument *i = &_pcmInstr[instrument];
- uint32 s = _totalLevel + i->level;
+void TownsPC98_OpnPercussionSource::recalcOuput(PcmInstrument *ins) {
+ uint32 s = _totalLevel + ins->level;
uint32 x = s > 62 ? 0 : (1 + (s >> 3));
int32 y = s > 62 ? 0 : (15 - (s & 7));
- i->out = (((int16)READ_LE_UINT16(i->pos) * y) >> x) & ~3;
+ ins->out = ((ins->samples[ins->decStep] * y) >> x) & ~3;
+}
+
+void TownsPC98_OpnPercussionSource::advanceInput(PcmInstrument *ins) {
+ static const int8 adjustIndex[] = {-1, -1, -1, -1, 2, 5, 7, 9 };
+
+ static const int16 stepTable[] = { 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55,
+ 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337,
+ 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552
+ };
+
+ int d = ins->samples[1];
+ uint8 cur = (int8) *ins->pos++;
+
+ for (int i = 0; i < 2; i++) {
+ int b = (2 * (cur & 7) + 1) * stepTable[ins->decState] / 8;
+ if (cur & 8)
+ b = -b;
+ d += b;
+ d = CLIP<int16>(d, -2048, 2047);
+ ins->samples[i] = d;
+ ins->decState = CLIP<int8>(ins->decState + adjustIndex[cur & 7], 0, 48);
+ cur >>= 4;
+ }
}
void TownsPC98_OpnSquareSineSource::nextTick(int32 *buffer, uint32 bufferSize) {
@@ -3051,7 +3086,7 @@ TownsPC98_OpnDriver::~TownsPC98_OpnDriver() {
delete [] _ssgPatches;
}
-bool TownsPC98_OpnDriver::init(uint8 *pcmData) {
+bool TownsPC98_OpnDriver::init() {
if (_ready) {
reset();
return true;
@@ -3114,10 +3149,8 @@ bool TownsPC98_OpnDriver::init(uint8 *pcmData) {
}
if (_hasPCM) {
- if (pcmData) {
- _pcm = new TownsPC98_OpnPercussionSource(_baserate);
- _pcm->init(pcmData);
- }
+ _pcm = new TownsPC98_OpnPercussionSource(_baserate);
+ _pcm->init();
delete _pcmChannel;
_pcmChannel = new TownsPC98_OpnChannelPCM(this, 0, 0, 0, 0, 0, 1);
@@ -3480,119 +3513,6 @@ void TownsPC98_OpnDriver::setTempo(uint8 tempo) {
_samplesPerCallbackRemainder = _tempo ? (getRate() % _tempo) : 0;
}
-const uint8 TownsPC98_OpnDriver::_drvTables[] = {
- // channel presets
- 0x00, 0x80, 0x00, 0x00, 0x00, 0x01,
- 0x01, 0x80, 0x01, 0x01, 0x00, 0x02,
- 0x02, 0x80, 0x02, 0x02, 0x00, 0x04,
- 0x00, 0x80, 0x03, 0x04, 0x01, 0x08,
- 0x01, 0x80, 0x04, 0x05, 0x01, 0x10,
- 0x02, 0x80, 0x05, 0x06, 0x01, 0x20,
-
- // control event size
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05,
- 0x02, 0x06, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02,
-
- // fmt level presets
- 0x54, 0x50, 0x4C, 0x48, 0x44, 0x40, 0x3C, 0x38,
- 0x34, 0x30, 0x2C, 0x28, 0x24, 0x20, 0x1C, 0x18,
- 0x14, 0x10, 0x0C, 0x08, 0x04, 0x90, 0x90, 0x90,
-
- // carriers
- 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0E, 0x0E, 0x0F,
-
- // frequencies
- 0x6A, 0x02, 0x8F, 0x02, 0xB6, 0x02, 0xDF, 0x02,
- 0x0B, 0x03, 0x39, 0x03, 0x6A, 0x03, 0x9E, 0x03,
- 0xD5, 0x03, 0x10, 0x04, 0x4E, 0x04, 0x8F, 0x04,
- 0x00, 0x00, 0x00, 0x00,
-
- // unused
- 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
-
- // detune
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
- 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
- 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
- 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
- 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05,
- 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a,
- 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14,
- 0x16, 0x16, 0x16, 0x16,
-
- // pc98 level presets
- 0x40, 0x3B, 0x38, 0x34, 0x30, 0x2A, 0x28, 0x25,
- 0x22, 0x20, 0x1D, 0x1A, 0x18, 0x15, 0x12, 0x10,
- 0x0D, 0x0A, 0x08, 0x05, 0x02, 0x90, 0x90, 0x90,
-
- // ssg frequencies
- 0xE8, 0x0E, 0x12, 0x0E, 0x48, 0x0D, 0x89, 0x0C,
- 0xD5, 0x0B, 0x2B, 0x0B, 0x8A, 0x0A, 0xF3, 0x09,
- 0x64, 0x09, 0xDD, 0x08, 0x5E, 0x08, 0xE6, 0x07,
-
- // ssg patch data
- 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00,
- 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
- 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
- 0x04, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
- 0x0A, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0x01, 0x00,
- 0xFF, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
- 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0x00,
- 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x64, 0x01, 0xFF, 0x64, 0xFF, 0x81, 0xFF, 0x00,
- 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
-
- 0x02, 0x01, 0xFF, 0x28, 0xFF, 0x81, 0xF0, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xC8, 0x00,
- 0x01, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0x78, 0x5F, 0x81, 0xA0, 0x00,
- 0x05, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
- 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
- 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00
-};
-
-const uint32 TownsPC98_OpnDriver::_adtStat[] = {
- 0x00010001, 0x00010001, 0x00010001, 0x01010001,
- 0x00010101, 0x00010101, 0x00010101, 0x01010101,
- 0x01010101, 0x01010101, 0x01010102, 0x01010102,
- 0x01020102, 0x01020102, 0x01020202, 0x01020202,
- 0x02020202, 0x02020202, 0x02020204, 0x02020204,
- 0x02040204, 0x02040204, 0x02040404, 0x02040404,
- 0x04040404, 0x04040404, 0x04040408, 0x04040408,
- 0x04080408, 0x04080408, 0x04080808, 0x04080808,
- 0x08080808, 0x08080808, 0x10101010, 0x10101010
-};
-
-const int TownsPC98_OpnDriver::_ssgTables[] = {
- 0x01202A, 0x0092D2, 0x006B42, 0x0053CB, 0x003DF8, 0x003053, 0x0022DA, 0x001A8C,
- 0x00129B, 0x000DC1, 0x000963, 0x0006C9, 0x000463, 0x0002FA, 0x0001B6, 0x0000FB,
- 0x0193B6, 0x01202A, 0x00CDB1, 0x0092D2, 0x007D7D, 0x006B42, 0x005ECD, 0x0053CB,
- 0x00480F, 0x003DF8, 0x0036B9, 0x003053, 0x00290A, 0x0022DA, 0x001E6B, 0x001A8C,
- 0x001639, 0x00129B, 0x000FFF, 0x000DC1, 0x000B5D, 0x000963, 0x0007FB, 0x0006C9,
- 0x000575, 0x000463, 0x00039D, 0x0002FA, 0x000242, 0x0001B6, 0x00014C, 0x0000FB
-};
-
SoundTowns::SoundTowns(KyraEngine_v1 *vm, Audio::Mixer *mixer)
: Sound(vm, mixer), _lastTrack(-1), _currentSFX(0), _sfxFileData(0),
_sfxFileIndex((uint)-1), _sfxWDTable(0), _sfxBTTable(0), _parser(0) {
@@ -3954,7 +3874,7 @@ bool SoundTownsPC98_v2::init() {
(Common::File::exists("track1.mp3") || Common::File::exists("track1.ogg") ||
Common::File::exists("track1.flac") || Common::File::exists("track1.fla")))
_musicEnabled = 2;
-
+
return _driver->init();
}
@@ -4089,6 +4009,121 @@ void SoundTownsPC98_v2::playSoundEffect(uint8 track) {
_driver->loadSoundEffectData(_sfxTrackData, track);
}
+// static resources
+
+const uint8 TownsPC98_OpnDriver::_drvTables[] = {
+ // channel presets
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x01,
+ 0x01, 0x80, 0x01, 0x01, 0x00, 0x02,
+ 0x02, 0x80, 0x02, 0x02, 0x00, 0x04,
+ 0x00, 0x80, 0x03, 0x04, 0x01, 0x08,
+ 0x01, 0x80, 0x04, 0x05, 0x01, 0x10,
+ 0x02, 0x80, 0x05, 0x06, 0x01, 0x20,
+
+ // control event size
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x05,
+ 0x02, 0x06, 0x02, 0x00, 0x00, 0x02, 0x00, 0x02,
+
+ // fmt level presets
+ 0x54, 0x50, 0x4C, 0x48, 0x44, 0x40, 0x3C, 0x38,
+ 0x34, 0x30, 0x2C, 0x28, 0x24, 0x20, 0x1C, 0x18,
+ 0x14, 0x10, 0x0C, 0x08, 0x04, 0x90, 0x90, 0x90,
+
+ // carriers
+ 0x08, 0x08, 0x08, 0x08, 0x0C, 0x0E, 0x0E, 0x0F,
+
+ // frequencies
+ 0x6A, 0x02, 0x8F, 0x02, 0xB6, 0x02, 0xDF, 0x02,
+ 0x0B, 0x03, 0x39, 0x03, 0x6A, 0x03, 0x9E, 0x03,
+ 0xD5, 0x03, 0x10, 0x04, 0x4E, 0x04, 0x8F, 0x04,
+ 0x00, 0x00, 0x00, 0x00,
+
+ // unused
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+
+ // detune
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
+ 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
+ 0x08, 0x08, 0x08, 0x08, 0x01, 0x01, 0x01, 0x01,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03,
+ 0x04, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07,
+ 0x08, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
+ 0x10, 0x10, 0x10, 0x10, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x05,
+ 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a,
+ 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x13, 0x14,
+ 0x16, 0x16, 0x16, 0x16,
+
+ // pc98 level presets
+ 0x40, 0x3B, 0x38, 0x34, 0x30, 0x2A, 0x28, 0x25,
+ 0x22, 0x20, 0x1D, 0x1A, 0x18, 0x15, 0x12, 0x10,
+ 0x0D, 0x0A, 0x08, 0x05, 0x02, 0x90, 0x90, 0x90,
+
+ // ssg frequencies
+ 0xE8, 0x0E, 0x12, 0x0E, 0x48, 0x0D, 0x89, 0x0C,
+ 0xD5, 0x0B, 0x2B, 0x0B, 0x8A, 0x0A, 0xF3, 0x09,
+ 0x64, 0x09, 0xDD, 0x08, 0x5E, 0x08, 0xE6, 0x07,
+
+ // ssg patch data
+ 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0x37, 0x81, 0xC8, 0x00,
+ 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
+ 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
+ 0x04, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xBE, 0x00,
+ 0x0A, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0x01, 0x00,
+ 0xFF, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
+ 0xFF, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xFF, 0x00,
+ 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x64, 0x01, 0xFF, 0x64, 0xFF, 0x81, 0xFF, 0x00,
+ 0x01, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+
+ 0x02, 0x01, 0xFF, 0x28, 0xFF, 0x81, 0xF0, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0x0A, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x81, 0xC8, 0x00,
+ 0x01, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0x78, 0x5F, 0x81, 0xA0, 0x00,
+ 0x05, 0x81, 0x00, 0x00, 0x28, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00,
+ 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x81, 0x00, 0x00,
+ 0x00, 0x81, 0x00, 0x00, 0xFF, 0x81, 0x00, 0x00
+};
+
+const uint32 TownsPC98_OpnDriver::_adtStat[] = {
+ 0x00010001, 0x00010001, 0x00010001, 0x01010001,
+ 0x00010101, 0x00010101, 0x00010101, 0x01010101,
+ 0x01010101, 0x01010101, 0x01010102, 0x01010102,
+ 0x01020102, 0x01020102, 0x01020202, 0x01020202,
+ 0x02020202, 0x02020202, 0x02020204, 0x02020204,
+ 0x02040204, 0x02040204, 0x02040404, 0x02040404,
+ 0x04040404, 0x04040404, 0x04040408, 0x04040408,
+ 0x04080408, 0x04080408, 0x04080808, 0x04080808,
+ 0x08080808, 0x08080808, 0x10101010, 0x10101010
+};
+
+const int TownsPC98_OpnDriver::_ssgTables[] = {
+ 0x01202A, 0x0092D2, 0x006B42, 0x0053CB, 0x003DF8, 0x003053, 0x0022DA, 0x001A8C,
+ 0x00129B, 0x000DC1, 0x000963, 0x0006C9, 0x000463, 0x0002FA, 0x0001B6, 0x0000FB,
+ 0x0193B6, 0x01202A, 0x00CDB1, 0x0092D2, 0x007D7D, 0x006B42, 0x005ECD, 0x0053CB,
+ 0x00480F, 0x003DF8, 0x0036B9, 0x003053, 0x00290A, 0x0022DA, 0x001E6B, 0x001A8C,
+ 0x001639, 0x00129B, 0x000FFF, 0x000DC1, 0x000B5D, 0x000963, 0x0007FB, 0x0006C9,
+ 0x000575, 0x000463, 0x00039D, 0x0002FA, 0x000242, 0x0001B6, 0x00014C, 0x0000FB
+};
+
} // end of namespace Kyra
#undef EUPHONY_FADEOUT_TICKS