1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "audio/softsynth/fmtowns_pc98/towns_audio.h"
24 #include "audio/softsynth/fmtowns_pc98/towns_pc98_fmsynth.h"
25 
26 #include "common/debug.h"
27 #include "common/endian.h"
28 #include "common/util.h"
29 #include "common/textconsole.h"
30 #include "backends/audiocd/audiocd.h"
31 
32 class TownsAudio_WaveTable {
33 friend class TownsAudioInterfaceInternal;
34 friend class TownsAudio_PcmChannel;
35 public:
36 	TownsAudio_WaveTable();
37 	~TownsAudio_WaveTable();
38 
39 private:
40 	void readHeader(const uint8 *buffer);
41 	void readData(const uint8 *buffer);
42 	void clear();
43 
44 	char name[9];
45 	int32 id;
46 	uint32 size;
47 	uint32 loopStart;
48 	uint32 loopLen;
49 	uint16 rate;
50 	uint16 rateOffs;
51 	uint16 baseNote;
52 	int8 *data;
53 };
54 
55 class TownsAudio_PcmChannel {
56 public:
57 	TownsAudio_PcmChannel();
58 	~TownsAudio_PcmChannel();
59 
60 	void clear();
61 
62 	void loadData(TownsAudio_WaveTable *w);
63 	void loadData(uint8 *buffer, uint32 size);
64 
65 	int initInstrument(uint8 &note, TownsAudio_WaveTable *&tables, int numTables);
66 	void keyOn(uint8 note, uint8 velo, TownsAudio_WaveTable *w);
67 	void keyOff();
68 
69 	void updateEnvelopeGenerator();
70 
71 	void setInstrument(uint8 *instr);
72 	void setLevel(uint8 lvl);
73 	void setPitch(uint32 pt);
74 	void setBalance(uint8 blc);
75 
76 	void updateOutput();
77 	int32 currentSampleLeft();
78 	int32 currentSampleRight();
79 
80 	bool _keyPressed;
81 	bool _reserved;
82 	bool _activeKey;
83 	bool _activeEffect;
84 	bool _activeOutput;
85 
86 private:
87 	void setupLoop(uint32 loopStart, uint32 loopLen);
88 	void setNote(uint8 note, TownsAudio_WaveTable *w, bool stepLimit = false);
89 	void setVelo(uint8 velo);
90 
91 	void envAttack();
92 	void envDecay();
93 	void envSustain();
94 	void envRelease();
95 
96 	uint8 *_curInstrument;
97 
98 	uint8 _note;
99 
100 	uint8 _velo;
101 	uint8 _level;
102 	uint8 _tl;
103 
104 	uint8 _panLeft;
105 	uint8 _panRight;
106 
107 	int8 *_data;
108 
109 	uint32 _loopStart;
110 	uint32 _loopLen;
111 	uint32 _dataEnd;
112 
113 	uint16 _stepNote;
114 	uint16 _stepPitch;
115 	uint16 _step;
116 
117 	uint32 _pos;
118 
119 	uint8 _envTotalLevel;
120 	uint8 _envAttackRate;
121 	uint8 _envDecayRate;
122 	uint8 _envSustainLevel;
123 	uint8 _envSustainRate;
124 	uint8 _envReleaseRate;
125 	int16 _envStep;
126 	int16 _envCurrentLevel;
127 
128 	EnvelopeState _envState;
129 
130 	int8 *_extData;
131 
132 	static const uint16 _pcmPhase1[];
133 	static const uint16 _pcmPhase2[];
134 };
135 
136 class TownsAudioInterfaceInternal : public TownsPC98_FmSynth {
137 private:
138 	TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutex);
139 public:
140 	~TownsAudioInterfaceInternal();
141 
142 	static TownsAudioInterfaceInternal *addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutex);
143 	static void releaseRef(TownsAudioInterface *owner);
144 
145 	bool init();
146 
147 	int callback(int command, ...);
148 	int processCommand(int command, va_list &args);
149 
150 	void setMusicVolume(int volume);
151 	void setSoundEffectVolume(int volume);
152 	// Defines the channels used as sound effect channels for the purpose of ScummVM GUI volume control.
153 	// The first 6 bits are the 6 fm channels. The next 8 bits are pcm channels.
154 	void setSoundEffectChanMask(int mask);
155 
156 private:
157 	bool assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver);
158 	void removePluginDriver(TownsAudioInterface *owner);
159 
160 	void nextTickEx(int32 *buffer, uint32 bufferSize);
161 
162 	void timerCallbackA();
163 	void timerCallbackB();
164 
165 	typedef int (TownsAudioInterfaceInternal::*TownsAudioIntfCallback)(va_list &);
166 	const TownsAudioIntfCallback *_intfOpcodes;
167 
168 	int intf_reset(va_list &args);
169 	int intf_keyOn(va_list &args);
170 	int intf_keyOff(va_list &args);
171 	int intf_setPanPos(va_list &args);
172 	int intf_setInstrument(va_list &args);
173 	int intf_loadInstrument(va_list &args);
174 	int intf_setPitch(va_list &args);
175 	int intf_setLevel(va_list &args);
176 	int intf_chanOff(va_list &args);
177 	int intf_writeReg(va_list &args);
178 	int intf_writeRegBuffer(va_list &args);
179 	int intf_readRegBuffer(va_list &args);
180 	int intf_setTimerA(va_list &args);
181 	int intf_setTimerB(va_list &args);
182 	int intf_enableTimerA(va_list &args);
183 	int intf_enableTimerB(va_list &args);
184 	int intf_loadSamples(va_list &args);
185 	int intf_reserveEffectChannels(va_list &args);
186 	int intf_loadWaveTable(va_list &args);
187 	int intf_unloadWaveTable(va_list &args);
188 	int intf_pcmPlayEffect(va_list &args);
189 	int intf_pcmChanOff(va_list &args);
190 	int intf_pcmEffectPlaying(va_list &args);
191 	int intf_pcmDisableAllChannels(va_list &args);
192 	int intf_fmKeyOn(va_list &args);
193 	int intf_fmKeyOff(va_list &args);
194 	int intf_fmSetPanPos(va_list &args);
195 	int intf_fmSetInstrument(va_list &args);
196 	int intf_fmLoadInstrument(va_list &args);
197 	int intf_fmSetPitch(va_list &args);
198 	int intf_fmSetLevel(va_list &args);
199 	int intf_fmReset(va_list &args);
200 	int intf_setOutputVolume(va_list &args);
201 	int intf_resetOutputVolume(va_list &args);
202 	int intf_getOutputVolume(va_list &args);
203 	int intf_setOutputMute(va_list &args);
204 	int intf_cdaToggle(va_list &args);
205 	int intf_getOutputVolume2(va_list &args);
206 	int intf_getOutputMute(va_list &args);
207 	int intf_pcmUpdateEnvelopeGenerator(va_list &args);
208 
209 	int intf_notImpl(va_list &args);
210 
211 	void fmReset();
212 	int fmKeyOn(int chan, int note, int velo);
213 	int fmKeyOff(int chan);
214 	int fmChanOff(int chan);
215 	int fmSetPanPos(int chan, int mode);
216 	int fmSetInstrument(int chan, int instrId);
217 	int fmLoadInstrument(int instrId, const uint8 *data);
218 	int fmSetPitch(int chan, int pitch);
219 	int fmSetLevel(int chan, int lvl);
220 
221 	void bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value);
222 
223 	uint8 _fmChanPlaying;
224 	uint8 _fmChanNote[6];
225 	int16 _fmChanPitch[6];
226 
227 	uint8 *_fmSaveReg[2];
228 	uint8 *_fmInstruments;
229 
230 	void pcmReset();
231 	int pcmKeyOn(int chan, int note, int velo);
232 	int pcmKeyOff(int chan);
233 	int pcmChanOff(int chan);
234 	int pcmSetPanPos(int chan, int mode);
235 	int pcmSetInstrument(int chan, int instrId);
236 	int pcmLoadInstrument(int instrId, const uint8 *data);
237 	int pcmSetPitch(int chan, int pitch);
238 	int pcmSetLevel(int chan, int lvl);
239 
240 	TownsAudio_PcmChannel *_pcmChan;
241 
242 	uint8 _numReservedChannels;
243 	uint8 *_pcmInstruments;
244 
245 	TownsAudio_WaveTable *_waveTables;
246 	uint8 _numWaveTables;
247 	uint32 _waveTablesTotalDataSize;
248 
249 	void updateOutputVolume();
250 	void updateOutputVolumeInternal();
251 	uint8 _outputVolumeFlags;
252 	uint8 _outputLevel[16];
253 	uint8 _outputMute[16];
254 	bool _updateOutputVol;
255 
256 	const uint32 _tickLength;
257 	const uint32 _envDuration;
258 	uint32 _timer;
259 
260 	uint16 _musicVolume;
261 	uint16 _sfxVolume;
262 	int _pcmSfxChanMask;
263 
264 	TownsAudioInterfacePluginDriver *_drv;
265 	void *_drvOwner;
266 	bool _externalMutex;
267 	bool _ready;
268 
269 	static TownsAudioInterfaceInternal *_refInstance;
270 	static int _refCount;
271 
272 	static const uint8 _chanFlags[];
273 	static const uint16 _frequency[];
274 	static const uint8 _carrier[];
275 	static const uint8 _fmDefaultInstrument[];
276 };
277 
TownsAudioInterfaceInternal(Audio::Mixer * mixer,TownsAudioInterface * owner,TownsAudioInterfacePluginDriver * driver,bool externalMutex)278 TownsAudioInterfaceInternal::TownsAudioInterfaceInternal(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutex) :
279 	TownsPC98_FmSynth(mixer, kTypeTowns), _fmInstruments(0), _pcmInstruments(0), _pcmChan(0), _waveTables(0), _waveTablesTotalDataSize(0),
280 	_tickLength(0x08), _envDuration(0x30), _timer(0), _drv(driver), _drvOwner(owner), _externalMutex(externalMutex), _pcmSfxChanMask(0), _outputVolumeFlags(0),
281 	_fmChanPlaying(0), _musicVolume(Audio::Mixer::kMaxMixerVolume), _sfxVolume(Audio::Mixer::kMaxMixerVolume),
282 	_numReservedChannels(0), _numWaveTables(0), _updateOutputVol(false), _ready(false) {
283 
284 #define INTCB(x) &TownsAudioInterfaceInternal::intf_##x
285 	static const TownsAudioIntfCallback intfCb[] = {
286 		// 0
287 		INTCB(reset),
288 		INTCB(keyOn),
289 		INTCB(keyOff),
290 		INTCB(setPanPos),
291 		// 4
292 		INTCB(setInstrument),
293 		INTCB(loadInstrument),
294 		INTCB(notImpl),
295 		INTCB(setPitch),
296 		// 8
297 		INTCB(setLevel),
298 		INTCB(chanOff),
299 		INTCB(notImpl),
300 		INTCB(notImpl),
301 		// 12
302 		INTCB(notImpl),
303 		INTCB(notImpl),
304 		INTCB(notImpl),
305 		INTCB(notImpl),
306 		// 16
307 		INTCB(notImpl),
308 		INTCB(writeReg),
309 		INTCB(notImpl),
310 		INTCB(writeRegBuffer),
311 		// 20
312 		INTCB(readRegBuffer),
313 		INTCB(setTimerA),
314 		INTCB(setTimerB),
315 		INTCB(enableTimerA),
316 		// 24
317 		INTCB(enableTimerB),
318 		INTCB(notImpl),
319 		INTCB(notImpl),
320 		INTCB(notImpl),
321 		// 28
322 		INTCB(notImpl),
323 		INTCB(notImpl),
324 		INTCB(notImpl),
325 		INTCB(notImpl),
326 		// 32
327 		INTCB(loadSamples),
328 		INTCB(reserveEffectChannels),
329 		INTCB(loadWaveTable),
330 		INTCB(unloadWaveTable),
331 		// 36
332 		INTCB(notImpl),
333 		INTCB(pcmPlayEffect),
334 		INTCB(notImpl),
335 		INTCB(pcmChanOff),
336 		// 40
337 		INTCB(pcmEffectPlaying),
338 		INTCB(pcmDisableAllChannels),
339 		INTCB(notImpl),
340 		INTCB(notImpl),
341 		// 44
342 		INTCB(notImpl),
343 		INTCB(notImpl),
344 		INTCB(notImpl),
345 		INTCB(notImpl),
346 		// 48
347 		INTCB(notImpl),
348 		INTCB(notImpl),
349 		INTCB(fmKeyOn),
350 		INTCB(fmKeyOff),
351 		// 52
352 		INTCB(fmSetPanPos),
353 		INTCB(fmSetInstrument),
354 		INTCB(fmLoadInstrument),
355 		INTCB(notImpl),
356 		// 56
357 		INTCB(fmSetPitch),
358 		INTCB(fmSetLevel),
359 		INTCB(fmReset),
360 		INTCB(notImpl),
361 		// 60
362 		INTCB(notImpl),
363 		INTCB(notImpl),
364 		INTCB(notImpl),
365 		INTCB(notImpl),
366 		// 64
367 		INTCB(notImpl),
368 		INTCB(notImpl),
369 		INTCB(notImpl),
370 		INTCB(setOutputVolume),
371 		// 68
372 		INTCB(resetOutputVolume),
373 		INTCB(getOutputVolume),
374 		INTCB(setOutputMute),
375 		INTCB(notImpl),
376 		// 72
377 		INTCB(notImpl),
378 		INTCB(cdaToggle),
379 		INTCB(getOutputVolume2),
380 		INTCB(getOutputMute),
381 		// 76
382 		INTCB(notImpl),
383 		INTCB(notImpl),
384 		INTCB(notImpl),
385 		INTCB(notImpl),
386 		// 80
387 		INTCB(pcmUpdateEnvelopeGenerator),
388 		INTCB(notImpl)
389 	};
390 #undef INTCB
391 
392 	_intfOpcodes = intfCb;
393 
394 	memset(_fmSaveReg, 0, sizeof(_fmSaveReg));
395 	memset(_fmChanNote, 0, sizeof(_fmChanNote));
396 	memset(_fmChanPitch, 0, sizeof(_fmChanPitch));
397 	memset(_outputLevel, 0, sizeof(_outputLevel));
398 	memset(_outputMute, 0, sizeof(_outputMute));
399 }
400 
~TownsAudioInterfaceInternal()401 TownsAudioInterfaceInternal::~TownsAudioInterfaceInternal() {
402 	deinit();
403 	Common::StackLock lock(_mutex);
404 	_ready = false;
405 
406 	delete[] _fmSaveReg[0];
407 	delete[] _fmSaveReg[1];
408 	delete[] _fmInstruments;
409 	delete[] _pcmInstruments;
410 	delete[] _waveTables;
411 	delete[] _pcmChan;
412 }
413 
addNewRef(Audio::Mixer * mixer,TownsAudioInterface * owner,TownsAudioInterfacePluginDriver * driver,bool externalMutex)414 TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::addNewRef(Audio::Mixer *mixer, TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver, bool externalMutex) {
415 	_refCount++;
416 	if (_refCount == 1 && _refInstance == 0)
417 		_refInstance = new TownsAudioInterfaceInternal(mixer, owner, driver, externalMutex);
418 	else if (_refCount < 2 || _refInstance == 0)
419 		error("TownsAudioInterfaceInternal::addNewRef(): Internal reference management failure");
420 	else if (!_refInstance->assignPluginDriver(owner, driver))
421 		error("TownsAudioInterfaceInternal::addNewRef(): Plugin driver conflict");
422 
423 	return _refInstance;
424 }
425 
releaseRef(TownsAudioInterface * owner)426 void TownsAudioInterfaceInternal::releaseRef(TownsAudioInterface *owner) {
427 	if (!_refCount)
428 		return;
429 
430 	_refCount--;
431 
432 	if (_refCount) {
433 		if (_refInstance)
434 			_refInstance->removePluginDriver(owner);
435 	} else {
436 		delete _refInstance;
437 		_refInstance = 0;
438 	}
439 }
440 
init()441 bool TownsAudioInterfaceInternal::init() {
442 	if (_ready)
443 		return true;
444 
445 	_fmSaveReg[0] = new uint8[256];
446 	_fmSaveReg[1] = new uint8[256];
447 	_fmInstruments = new uint8[128 * 48];
448 	_pcmInstruments = new uint8[32 * 128];
449 	_waveTables = new TownsAudio_WaveTable[128];
450 	_pcmChan = new TownsAudio_PcmChannel[8];
451 
452 	_timer = 0;
453 
454 	if (!TownsPC98_FmSynth::init())
455 		return false;
456 
457 
458 	setVolumeChannelMasks(-1, 0);
459 
460 	_ready = true;
461 	callback(0);
462 
463 	return true;
464 }
465 
callback(int command,...)466 int TownsAudioInterfaceInternal::callback(int command, ...) {
467 	Common::StackLock lock(_mutex);
468 	if (!_ready)
469 		return 1;
470 
471 	va_list args;
472 	va_start(args, command);
473 
474 	int res = processCommand(command, args);
475 
476 	va_end(args);
477 	return res;
478 }
479 
processCommand(int command,va_list & args)480 int TownsAudioInterfaceInternal::processCommand(int command, va_list &args) {
481 	Common::StackLock lock(_mutex);
482 	if (!_ready)
483 		return 1;
484 
485 	if (command < 0 || command > 81)
486 		return 4;
487 
488 	int res = (this->*_intfOpcodes[command])(args);
489 
490 	return res;
491 }
492 
setMusicVolume(int volume)493 void TownsAudioInterfaceInternal::setMusicVolume(int volume) {
494 	Common::StackLock lock(_mutex);
495 	_musicVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
496 	setVolumeIntern(_musicVolume, _sfxVolume);
497 }
498 
setSoundEffectVolume(int volume)499 void TownsAudioInterfaceInternal::setSoundEffectVolume(int volume) {
500 	Common::StackLock lock(_mutex);
501 	_sfxVolume = CLIP<uint16>(volume, 0, Audio::Mixer::kMaxMixerVolume);
502 	setVolumeIntern(_musicVolume, _sfxVolume);
503 }
504 
setSoundEffectChanMask(int mask)505 void TownsAudioInterfaceInternal::setSoundEffectChanMask(int mask) {
506 	Common::StackLock lock(_mutex);
507 	_pcmSfxChanMask = mask >> 6;
508 	mask &= 0x3f;
509 	setVolumeChannelMasks(~mask, mask);
510 }
511 
assignPluginDriver(TownsAudioInterface * owner,TownsAudioInterfacePluginDriver * driver)512 bool TownsAudioInterfaceInternal::assignPluginDriver(TownsAudioInterface *owner, TownsAudioInterfacePluginDriver *driver) {
513 	Common::StackLock lock(_mutex);
514 	if (_refCount <= 1)
515 		return true;
516 
517 	if (_drv) {
518 		if (driver && driver != _drv)
519 			return false;
520 	} else {
521 		_drv = driver;
522 		_drvOwner = owner;
523 	}
524 
525 	return true;
526 }
527 
removePluginDriver(TownsAudioInterface * owner)528 void TownsAudioInterfaceInternal::removePluginDriver(TownsAudioInterface *owner) {
529 	Common::StackLock lock(_mutex);
530 	if (_drvOwner == owner)
531 		_drv = 0;
532 }
533 
nextTickEx(int32 * buffer,uint32 bufferSize)534 void TownsAudioInterfaceInternal::nextTickEx(int32 *buffer, uint32 bufferSize) {
535 	Common::StackLock lock(_mutex);
536 	if (!_ready)
537 		return;
538 
539 	if (_updateOutputVol)
540 		updateOutputVolumeInternal();
541 
542 	for (uint32 i = 0; i < bufferSize; i++) {
543 		_timer += _tickLength;
544 		while (_timer >= _envDuration) {
545 			_timer -= _envDuration;
546 
547 			for (int ii = 0; ii < 8; ii++)
548 				_pcmChan[ii].updateOutput();
549 		}
550 
551 		int32 finOutL = 0;
552 		int32 finOutR = 0;
553 
554 		for (int ii = 0; ii < 8; ii++) {
555 			if (_pcmChan[ii]._activeOutput) {
556 				int32 oL = _pcmChan[ii].currentSampleLeft();
557 				int32 oR = _pcmChan[ii].currentSampleRight();
558 				if ((1 << ii) & (~_pcmSfxChanMask)) {
559 					oL = (oR * _musicVolume) / Audio::Mixer::kMaxMixerVolume;
560 					oR = (oR * _musicVolume) / Audio::Mixer::kMaxMixerVolume;
561 				}
562 				if ((1 << ii) & _pcmSfxChanMask) {
563 					oL = (oL * _sfxVolume) / Audio::Mixer::kMaxMixerVolume;
564 					oR = (oR * _sfxVolume) / Audio::Mixer::kMaxMixerVolume;
565 				}
566 				finOutL += oL;
567 				finOutR += oR;
568 
569 				if (!(_pcmChan[ii]._activeKey || _pcmChan[ii]._activeEffect))
570 					_pcmChan[ii]._activeOutput = false;
571 			}
572 		}
573 
574 		buffer[i << 1] += finOutL;
575 		buffer[(i << 1) + 1] += finOutR;
576 	}
577 }
578 
timerCallbackA()579 void TownsAudioInterfaceInternal::timerCallbackA() {
580 	if (_drv && _ready) {
581 		int restore = 0;
582 		if (_externalMutex) {
583 			for (; restore < _mixerThreadLockCounter; ++restore)
584 				_mutex.unlock();
585 		}
586 		_drv->timerCallback(0);
587 		while (restore--)
588 			_mutex.lock();
589 	}
590 }
591 
timerCallbackB()592 void TownsAudioInterfaceInternal::timerCallbackB() {
593 	if (_ready) {
594 		if (_drv) {
595 			int restore = 0;
596 			if (_externalMutex) {
597 				for (; restore < _mixerThreadLockCounter; ++restore)
598 					_mutex.unlock();
599 			}
600 			_drv->timerCallback(1);
601 			while (restore--)
602 				_mutex.lock();
603 		}
604 		callback(80);
605 	}
606 }
607 
intf_reset(va_list & args)608 int TownsAudioInterfaceInternal::intf_reset(va_list &args) {
609 	fmReset();
610 	pcmReset();
611 	callback(68);
612 	return 0;
613 }
614 
intf_keyOn(va_list & args)615 int TownsAudioInterfaceInternal::intf_keyOn(va_list &args) {
616 	int chan = va_arg(args, int);
617 	int note = va_arg(args, int);
618 	int velo = va_arg(args, int);
619 	return (chan & 0x40) ? pcmKeyOn(chan, note, velo) : fmKeyOn(chan, note, velo);
620 }
621 
intf_keyOff(va_list & args)622 int TownsAudioInterfaceInternal::intf_keyOff(va_list &args) {
623 	int chan = va_arg(args, int);
624 	return (chan & 0x40) ? pcmKeyOff(chan) : fmKeyOff(chan);
625 }
626 
intf_setPanPos(va_list & args)627 int TownsAudioInterfaceInternal::intf_setPanPos(va_list &args) {
628 	int chan = va_arg(args, int);
629 	int mode = va_arg(args, int);
630 	return (chan & 0x40) ? pcmSetPanPos(chan, mode) : fmSetPanPos(chan, mode);
631 }
632 
intf_setInstrument(va_list & args)633 int TownsAudioInterfaceInternal::intf_setInstrument(va_list &args) {
634 	int chan = va_arg(args, int);
635 	int instrId = va_arg(args, int);
636 	return (chan & 0x40) ? pcmSetInstrument(chan, instrId) : fmSetInstrument(chan, instrId);
637 }
638 
intf_loadInstrument(va_list & args)639 int TownsAudioInterfaceInternal::intf_loadInstrument(va_list &args) {
640 	int chanType = va_arg(args, int);
641 	int instrId = va_arg(args, int);
642 	uint8 *instrData = va_arg(args, uint8 *);
643 	return (chanType & 0x40) ? pcmLoadInstrument(instrId, instrData) : fmLoadInstrument(instrId, instrData);
644 }
645 
intf_setPitch(va_list & args)646 int TownsAudioInterfaceInternal::intf_setPitch(va_list &args) {
647 	int chan = va_arg(args, int);
648 	int16 pitch = (int16)(va_arg(args, int) & 0xffff);
649 	return (chan & 0x40) ? pcmSetPitch(chan, pitch) : fmSetPitch(chan, pitch);
650 }
651 
intf_setLevel(va_list & args)652 int TownsAudioInterfaceInternal::intf_setLevel(va_list &args) {
653 	int chan = va_arg(args, int);
654 	int lvl = va_arg(args, int);
655 	return (chan & 0x40) ? pcmSetLevel(chan, lvl) : fmSetLevel(chan, lvl);
656 }
657 
intf_chanOff(va_list & args)658 int TownsAudioInterfaceInternal::intf_chanOff(va_list &args) {
659 	int chan = va_arg(args, int);
660 	return (chan & 0x40) ? pcmChanOff(chan) : fmChanOff(chan);
661 }
662 
intf_writeReg(va_list & args)663 int TownsAudioInterfaceInternal::intf_writeReg(va_list &args) {
664 	int part = va_arg(args, int) ? 1 : 0;
665 	int reg = va_arg(args, int);
666 	int val = va_arg(args, int);
667 	if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xb6))
668 		return 3;
669 
670 	bufferedWriteReg(part, reg, val);
671 	return 0;
672 }
673 
intf_writeRegBuffer(va_list & args)674 int TownsAudioInterfaceInternal::intf_writeRegBuffer(va_list &args) {
675 	int part = va_arg(args, int) ? 1 : 0;
676 	int reg = va_arg(args, int);
677 	int val = va_arg(args, int);
678 
679 	if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xef))
680 		return 3;
681 
682 	_fmSaveReg[part][reg] = val;
683 	return 0;
684 }
685 
intf_readRegBuffer(va_list & args)686 int TownsAudioInterfaceInternal::intf_readRegBuffer(va_list &args) {
687 	int part = va_arg(args, int) ? 1 : 0;
688 	int reg = va_arg(args, int);
689 	uint8 *dst = va_arg(args, uint8 *);
690 	*dst = 0;
691 
692 	if ((!part && reg < 0x20) || (part && reg < 0x30) || (reg > 0xef))
693 		return 3;
694 
695 	*dst = _fmSaveReg[part][reg];
696 	return 0;
697 }
698 
intf_setTimerA(va_list & args)699 int TownsAudioInterfaceInternal::intf_setTimerA(va_list &args) {
700 	int enable = va_arg(args, int);
701 	int tempo = va_arg(args, int);
702 
703 	if (enable) {
704 		bufferedWriteReg(0, 0x25, tempo & 3);
705 		bufferedWriteReg(0, 0x24, (tempo >> 2) & 0xff);
706 		bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x05);
707 	} else {
708 		bufferedWriteReg(0, 0x27, (_fmSaveReg[0][0x27] & 0xfa) | 0x10);
709 	}
710 
711 	return 0;
712 }
713 
intf_setTimerB(va_list & args)714 int TownsAudioInterfaceInternal::intf_setTimerB(va_list &args) {
715 	int enable = va_arg(args, int);
716 	int tempo = va_arg(args, int);
717 
718 	if (enable) {
719 		bufferedWriteReg(0, 0x26, tempo & 0xff);
720 		bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x0A);
721 	} else {
722 		bufferedWriteReg(0, 0x27, (_fmSaveReg[0][0x27] & 0xf5) | 0x20);
723 	}
724 
725 	return 0;
726 }
727 
intf_enableTimerA(va_list & args)728 int TownsAudioInterfaceInternal::intf_enableTimerA(va_list &args) {
729 	bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x15);
730 	return 0;
731 }
732 
intf_enableTimerB(va_list & args)733 int TownsAudioInterfaceInternal::intf_enableTimerB(va_list &args) {
734 	bufferedWriteReg(0, 0x27, _fmSaveReg[0][0x27] | 0x2a);
735 	return 0;
736 }
737 
intf_loadSamples(va_list & args)738 int TownsAudioInterfaceInternal::intf_loadSamples(va_list &args) {
739 	uint32 dest = va_arg(args, uint32);
740 	int size = va_arg(args, int);
741 	uint8 *src = va_arg(args, uint8*);
742 
743 	if (dest >= 65536 || size == 0 || size > 65536)
744 		return 3;
745 	if (size + dest > 65536)
746 		// EOB II FM-TOWNS tries to load more than 65536 bytes of wave sounds for the outro sequence.
747 		// This means that some sfx would not play. Since we don't really need the memory limit,
748 		// I have commented out the error return and added a debug message instead.
749 		debugN(9, "FM-TOWNS AUDIO: exceeding wave memory size by %d bytes", size + dest - 65536);
750 		// return 5;
751 
752 	int dwIndex = _numWaveTables - 1;
753 	for (uint32 t = _waveTablesTotalDataSize; dwIndex && (dest < t); dwIndex--)
754 		t -= _waveTables[dwIndex].size;
755 
756 	TownsAudio_WaveTable *s = &_waveTables[dwIndex];
757 	_waveTablesTotalDataSize -= s->size;
758 	s->size = size;
759 	s->readData(src);
760 	_waveTablesTotalDataSize += s->size;
761 
762 	return 0;
763 }
764 
intf_reserveEffectChannels(va_list & args)765 int TownsAudioInterfaceInternal::intf_reserveEffectChannels(va_list &args) {
766 	int numChan = va_arg(args, int);
767 	if (numChan > 8)
768 		return 3;
769 	if ((numChan << 13) + _waveTablesTotalDataSize > 65536)
770 		return 5;
771 
772 	if (numChan == _numReservedChannels)
773 		return 0;
774 
775 	if (numChan < _numReservedChannels) {
776 		int c = 8 - _numReservedChannels;
777 		for (int i = numChan; i; i--)
778 			_pcmChan[c--]._activeEffect = false;
779 	} else {
780 		int c = 7 - _numReservedChannels;
781 		for (int i = numChan - _numReservedChannels; i; i--) {
782 			_pcmChan[c]._keyPressed = false;
783 			_pcmChan[c--]._activeKey = false;
784 		}
785 	}
786 
787 	_numReservedChannels = numChan;
788 	for (int i = 0; i < 8; i++)
789 		_pcmChan[i]._reserved = i >= (8 - _numReservedChannels) ? true : false;
790 
791 	return 0;
792 }
793 
intf_loadWaveTable(va_list & args)794 int TownsAudioInterfaceInternal::intf_loadWaveTable(va_list &args) {
795 	uint8 *data = va_arg(args, uint8 *);
796 	if (_numWaveTables > 127)
797 		return 3;
798 
799 	TownsAudio_WaveTable w;
800 	w.readHeader(data);
801 	if (!w.size)
802 		return 6;
803 
804 	if (_waveTablesTotalDataSize + w.size > 65504)
805 		return 5;
806 
807 	callback(41);
808 
809 	for (int i = 0; i < _numWaveTables; i++) {
810 		if (_waveTables[i].id == w.id)
811 			return 10;
812 	}
813 
814 	TownsAudio_WaveTable *s = &_waveTables[_numWaveTables++];
815 	s->readHeader(data);
816 
817 	_waveTablesTotalDataSize += s->size;
818 	int res = callback(32, _waveTablesTotalDataSize, s->size, data + 32);
819 	if (res) {
820 		_waveTablesTotalDataSize -= s->size;
821 		_numWaveTables--;
822 	}
823 
824 	return res;
825 }
826 
intf_unloadWaveTable(va_list & args)827 int TownsAudioInterfaceInternal::intf_unloadWaveTable(va_list &args) {
828 	int id = va_arg(args, int);
829 	callback(41);
830 
831 	if (id == -1) {
832 		for (int i = 0; i < 128; i++)
833 			_waveTables[i].clear();
834 		_numWaveTables = 0;
835 		_waveTablesTotalDataSize = 0;
836 	} else {
837 		if (_waveTables) {
838 			for (int i = 0; i < _numWaveTables; i++) {
839 				if (_waveTables[i].id == id) {
840 					_numWaveTables--;
841 					_waveTablesTotalDataSize -= _waveTables[i].size;
842 					_waveTables[i].clear();
843 					for (; i < _numWaveTables; i++)
844 						_waveTables[i] = _waveTables[i + 1];
845 					return 0;
846 				}
847 			}
848 			return 9;
849 		}
850 	}
851 
852 	return 0;
853 }
854 
intf_pcmPlayEffect(va_list & args)855 int TownsAudioInterfaceInternal::intf_pcmPlayEffect(va_list &args) {
856 	int chan = va_arg(args, int);
857 	int note = va_arg(args, int);
858 	int velo = va_arg(args, int);
859 	uint8 *data = va_arg(args, uint8 *);
860 
861 	if (chan < 0x40 || chan > 0x47)
862 		return 1;
863 
864 	if (note & 0x80 || velo & 0x80)
865 		return 3;
866 
867 	chan -= 0x40;
868 
869 	if (!_pcmChan[chan]._reserved)
870 		return 7;
871 
872 	if (_pcmChan[chan]._activeEffect)
873 		return 2;
874 
875 	TownsAudio_WaveTable w;
876 	w.readHeader(data);
877 
878 	if (w.size < (w.loopStart + w.loopLen))
879 		return 13;
880 
881 	if (!w.size)
882 		return 6;
883 
884 	TownsAudio_PcmChannel *p = &_pcmChan[chan];
885 
886 	p->loadData(data + 32, w.size);
887 	p->keyOn(note, velo, &w);
888 
889 	return 0;
890 }
891 
intf_pcmChanOff(va_list & args)892 int TownsAudioInterfaceInternal::intf_pcmChanOff(va_list &args) {
893 	int chan = va_arg(args, int);
894 	pcmChanOff(chan);
895 	return 0;
896 }
897 
intf_pcmEffectPlaying(va_list & args)898 int TownsAudioInterfaceInternal::intf_pcmEffectPlaying(va_list &args) {
899 	int chan = va_arg(args, int);
900 	if (chan < 0x40 || chan > 0x47)
901 		return 1;
902 	chan -= 0x40;
903 	return _pcmChan[chan]._activeEffect ? 1 : 0;
904 }
905 
intf_pcmDisableAllChannels(va_list & args)906 int TownsAudioInterfaceInternal::intf_pcmDisableAllChannels(va_list &args) {
907 	for (int i = 0; i < 8; ++i)
908 		_pcmChan[i]._activeOutput = false;
909 	return 0;
910 }
911 
intf_fmKeyOn(va_list & args)912 int TownsAudioInterfaceInternal::intf_fmKeyOn(va_list &args) {
913 	int chan = va_arg(args, int);
914 	int note = va_arg(args, int);
915 	int velo = va_arg(args, int);
916 	return fmKeyOn(chan, note, velo);
917 }
918 
intf_fmKeyOff(va_list & args)919 int TownsAudioInterfaceInternal::intf_fmKeyOff(va_list &args) {
920 	int chan = va_arg(args, int);
921 	return fmKeyOff(chan);
922 }
923 
intf_fmSetPanPos(va_list & args)924 int TownsAudioInterfaceInternal::intf_fmSetPanPos(va_list &args) {
925 	int chan = va_arg(args, int);
926 	int mode = va_arg(args, int);
927 	return fmSetPanPos(chan, mode);
928 }
929 
intf_fmSetInstrument(va_list & args)930 int TownsAudioInterfaceInternal::intf_fmSetInstrument(va_list &args) {
931 	int chan = va_arg(args, int);
932 	int instrId = va_arg(args, int);
933 	return fmSetInstrument(chan, instrId);
934 }
935 
intf_fmLoadInstrument(va_list & args)936 int TownsAudioInterfaceInternal::intf_fmLoadInstrument(va_list &args) {
937 	int instrId = va_arg(args, int);
938 	uint8 *instrData = va_arg(args, uint8 *);
939 	return fmLoadInstrument(instrId, instrData);
940 }
941 
intf_fmSetPitch(va_list & args)942 int TownsAudioInterfaceInternal::intf_fmSetPitch(va_list &args) {
943 	int chan = va_arg(args, int);
944 	uint16 freq = va_arg(args, int) & 0xffff;
945 	return fmSetPitch(chan, freq);
946 }
947 
intf_fmSetLevel(va_list & args)948 int TownsAudioInterfaceInternal::intf_fmSetLevel(va_list &args) {
949 	int chan = va_arg(args, int);
950 	int lvl = va_arg(args, int);
951 	return fmSetLevel(chan, lvl);
952 }
953 
intf_fmReset(va_list & args)954 int TownsAudioInterfaceInternal::intf_fmReset(va_list &args) {
955 	fmReset();
956 	return 0;
957 }
958 
intf_setOutputVolume(va_list & args)959 int TownsAudioInterfaceInternal::intf_setOutputVolume(va_list &args) {
960 	int chanType = va_arg(args, int);
961 	int left = va_arg(args, int);
962 	int right = va_arg(args, int);
963 
964 	if (left & 0xff80 || right & 0xff80)
965 		return 3;
966 
967 	static const uint8 flags[] = { 0x0C, 0x30, 0x40, 0x80 };
968 
969 	uint8 chan = (chanType & 0x40) ? 8 : 12;
970 
971 	chanType &= 3;
972 	left = (left & 0x7e) >> 1;
973 	right = (right & 0x7e) >> 1;
974 
975 	if (chan == 12)
976 		_outputVolumeFlags |= flags[chanType];
977 	else
978 		_outputVolumeFlags &= ~flags[chanType];
979 
980 	if (chanType > 1) {
981 		_outputLevel[chan + chanType] = left;
982 		_outputMute[chan + chanType] = 0;
983 	} else {
984 		if (chanType == 0)
985 			chan -= 8;
986 		_outputLevel[chan] = left;
987 		_outputLevel[chan + 1] = right;
988 		_outputMute[chan] = _outputMute[chan + 1] = 0;
989 	}
990 
991 	updateOutputVolume();
992 
993 	return 0;
994 }
995 
intf_resetOutputVolume(va_list & args)996 int TownsAudioInterfaceInternal::intf_resetOutputVolume(va_list &args) {
997 	memset(_outputLevel, 0, sizeof(_outputLevel));
998 	_outputVolumeFlags = 0;
999 	updateOutputVolume();
1000 	return 0;
1001 }
1002 
intf_getOutputVolume(va_list & args)1003 int TownsAudioInterfaceInternal::intf_getOutputVolume(va_list &args) {
1004 	int chanType = va_arg(args, int);
1005 	int *left = va_arg(args, int*);
1006 	int *right = va_arg(args, int*);
1007 
1008 	uint8 chan = (chanType & 0x40) ? 8 : 12;
1009 	chanType &= 3;
1010 
1011 	if (chanType > 1) {
1012 		*left = _outputLevel[chan + chanType] & 0x3f;
1013 	} else {
1014 		if (chanType == 0)
1015 			chan -= 8;
1016 		*left = _outputLevel[chan] & 0x3f;
1017 		*right = _outputLevel[chan + 1] & 0x3f;
1018 	}
1019 
1020 	return 0;
1021 }
1022 
intf_setOutputMute(va_list & args)1023 int TownsAudioInterfaceInternal::intf_setOutputMute(va_list &args) {
1024 	int flags = va_arg(args, int);
1025 	_outputVolumeFlags = flags;
1026 	uint8 mute = flags & 3;
1027 	uint8 f = flags & 0xff;
1028 
1029 	memset(_outputMute, 1, 8);
1030 	if (mute & 2)
1031 		memset(&_outputMute[12], 1, 4);
1032 	if (mute & 1)
1033 		memset(&_outputMute[8], 1, 4);
1034 
1035 	_outputMute[(f < 0x80) ? 11 : 15] = 0;
1036 	f += f;
1037 	_outputMute[(f < 0x80) ? 10 : 14] = 0;
1038 	f += f;
1039 	_outputMute[(f < 0x80) ? 8 : 12] = 0;
1040 	f += f;
1041 	_outputMute[(f < 0x80) ? 9 : 13] = 0;
1042 	f += f;
1043 	_outputMute[(f < 0x80) ? 0 : 4] = 0;
1044 	f += f;
1045 	_outputMute[(f < 0x80) ? 1 : 5] = 0;
1046 	f += f;
1047 
1048 	updateOutputVolume();
1049 	return 0;
1050 }
1051 
intf_cdaToggle(va_list & args)1052 int TownsAudioInterfaceInternal::intf_cdaToggle(va_list &args) {
1053 	//int mode = va_arg(args, int);
1054 	//_unkMask = mode ? 0x7f : 0x3f;
1055 	return 0;
1056 }
1057 
intf_getOutputVolume2(va_list & args)1058 int TownsAudioInterfaceInternal::intf_getOutputVolume2(va_list &args) {
1059 	return 0;
1060 }
1061 
intf_getOutputMute(va_list & args)1062 int TownsAudioInterfaceInternal::intf_getOutputMute (va_list &args) {
1063 	return 0;
1064 }
1065 
intf_pcmUpdateEnvelopeGenerator(va_list & args)1066 int TownsAudioInterfaceInternal::intf_pcmUpdateEnvelopeGenerator(va_list &args) {
1067 	for (int i = 0; i < 8; i++)
1068 		_pcmChan[i].updateEnvelopeGenerator();
1069 	return 0;
1070 }
1071 
intf_notImpl(va_list & args)1072 int TownsAudioInterfaceInternal::intf_notImpl(va_list &args) {
1073 	return 4;
1074 }
1075 
fmReset()1076 void TownsAudioInterfaceInternal::fmReset() {
1077 	TownsPC98_FmSynth::reset();
1078 
1079 	_fmChanPlaying = 0;
1080 	memset(_fmChanNote, 0, sizeof(_fmChanNote));
1081 	memset(_fmChanPitch, 0, sizeof(_fmChanPitch));
1082 
1083 	memset(_fmSaveReg[0], 0, 240);
1084 	memset(&_fmSaveReg[0][240], 0x7f, 16);
1085 	memset(_fmSaveReg[1], 0, 256);
1086 	memset(&_fmSaveReg[1][240], 0x7f, 16);
1087 	_fmSaveReg[0][243] = _fmSaveReg[0][247] = _fmSaveReg[0][251] = _fmSaveReg[0][255] = _fmSaveReg[1][243] = _fmSaveReg[1][247] = _fmSaveReg[1][251] = _fmSaveReg[1][255] = 0xff;
1088 
1089 	for (int i = 0; i < 128; i++)
1090 		fmLoadInstrument(i, _fmDefaultInstrument);
1091 
1092 	bufferedWriteReg(0, 0x21, 0);
1093 	bufferedWriteReg(0, 0x2C, 0x80);
1094 	bufferedWriteReg(0, 0x2B, 0);
1095 	bufferedWriteReg(0, 0x27, 0x30);
1096 
1097 	for (int i = 0; i < 6; i++) {
1098 		fmKeyOff(i);
1099 		fmSetInstrument(i, 0);
1100 		fmSetLevel(i, 127);
1101 	}
1102 }
1103 
fmKeyOn(int chan,int note,int velo)1104 int TownsAudioInterfaceInternal::fmKeyOn(int chan, int note, int velo) {
1105 	if (chan > 5)
1106 		return 1;
1107 	if (note < 12 || note > 107 || (velo & 0x80))
1108 		return 3;
1109 	if (_fmChanPlaying & _chanFlags[chan])
1110 		return 2;
1111 
1112 	_fmChanPlaying |= _chanFlags[chan];
1113 	note -= 12;
1114 
1115 	_fmChanNote[chan] = note;
1116 	int16 pitch = _fmChanPitch[chan];
1117 
1118 	uint8 part = chan > 2 ? 1 : 0;
1119 	if (chan > 2)
1120 		chan -= 3;
1121 
1122 	int frq = 0;
1123 	uint8 bl = 0;
1124 
1125 	if (note) {
1126 		frq = _frequency[(note - 1) % 12];
1127 		bl = (note - 1) / 12;
1128 	} else {
1129 		frq = 616;
1130 	}
1131 
1132 	frq += pitch;
1133 
1134 	if (frq < 616) {
1135 		if (!bl) {
1136 			frq = 616;
1137 		} else {
1138 			frq += 616;
1139 			--bl;
1140 		}
1141 	} else if (frq > 1232) {
1142 		if (bl == 7) {
1143 			frq = 15500;
1144 		} else {
1145 			frq -= 616;
1146 			++bl;
1147 		}
1148 	}
1149 
1150 	frq |= (bl << 11);
1151 
1152 	bufferedWriteReg(part, chan + 0xa4, (frq >> 8) & 0xff);
1153 	bufferedWriteReg(part, chan + 0xa0, frq & 0xff);
1154 
1155 	velo = (velo >> 2) + 96;
1156 	uint16 c = _carrier[_fmSaveReg[part][0xb0 + chan] & 7];
1157 	_fmSaveReg[part][0xe0 + chan] = velo;
1158 
1159 	for (uint8 reg = 0x40 + chan; reg < 0x50; reg += 4) {
1160 		c += c;
1161 		if (c & 0x100) {
1162 			c &= 0xff;
1163 			bufferedWriteReg(part, reg, (((((((_fmSaveReg[part][0x80 + reg] ^ 0x7f) * velo) >> 7) + 1) * _fmSaveReg[part][0xd0 + chan]) >> 7) + 1) ^ 0x7f);
1164 		}
1165 	}
1166 
1167 	uint8 v = chan;
1168 	if (part)
1169 		v |= 4;
1170 
1171 	for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4)
1172 		writeReg(part, reg, _fmSaveReg[part][reg] | 0x0f);
1173 
1174 	writeReg(0, 0x28, v);
1175 
1176 	for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4)
1177 		writeReg(part, reg, _fmSaveReg[part][reg]);
1178 
1179 	bufferedWriteReg(0, 0x28, v | 0xf0);
1180 
1181 	return 0;
1182 }
1183 
fmKeyOff(int chan)1184 int TownsAudioInterfaceInternal::fmKeyOff(int chan) {
1185 	if (chan > 5)
1186 		return 1;
1187 	_fmChanPlaying &= ~_chanFlags[chan];
1188 	if (chan > 2)
1189 		chan++;
1190 	bufferedWriteReg(0, 0x28, chan);
1191 	return 0;
1192 }
1193 
fmChanOff(int chan)1194 int TownsAudioInterfaceInternal::fmChanOff(int chan) {
1195 	if (chan > 5)
1196 		return 1;
1197 	_fmChanPlaying &= ~_chanFlags[chan];
1198 
1199 	uint8 part = chan > 2 ? 1 : 0;
1200 	if (chan > 2)
1201 		chan -= 3;
1202 
1203 	for (uint8 reg = 0x80 + chan; reg < 0x90; reg += 4)
1204 		writeReg(part, reg, _fmSaveReg[part][reg] | 0x0f);
1205 
1206 	if (part)
1207 		chan += 4;
1208 	writeReg(0, 0x28, chan);
1209 	return 0;
1210 }
1211 
fmSetPanPos(int chan,int value)1212 int TownsAudioInterfaceInternal::fmSetPanPos(int chan, int value) {
1213 	if (chan > 5)
1214 		return 1;
1215 
1216 	uint8 part = chan > 2 ? 1 : 0;
1217 	if (chan > 2)
1218 		chan -= 3;
1219 
1220 	if (value > 0x40)
1221 		value = 0x40;
1222 	else if (value < 0x40)
1223 		value = 0x80;
1224 	else
1225 		value = 0xC0;
1226 
1227 	bufferedWriteReg(part, 0xb4 + chan, (_fmSaveReg[part][0xb4 + chan] & 0x3f) | value);
1228 	return 0;
1229 }
1230 
fmSetInstrument(int chan,int instrId)1231 int TownsAudioInterfaceInternal::fmSetInstrument(int chan, int instrId) {
1232 	if (chan > 5)
1233 		return 1;
1234 	if (instrId > 127)
1235 		return 3;
1236 
1237 	uint8 part = chan > 2 ? 1 : 0;
1238 	if (chan > 2)
1239 		chan -= 3;
1240 
1241 	uint8 *src = &_fmInstruments[instrId * 48 + 8];
1242 
1243 	uint16 c = _carrier[src[24] & 7];
1244 	uint8 reg = 0x30 + chan;
1245 
1246 	for (; reg < 0x40; reg += 4)
1247 		bufferedWriteReg(part, reg, *src++);
1248 
1249 	for (; reg < 0x50; reg += 4) {
1250 		uint8 v = *src++;
1251 		_fmSaveReg[part][0x80 + reg] = _fmSaveReg[part][reg] = v;
1252 		c += c;
1253 		if (c & 0x100) {
1254 			c &= 0xff;
1255 			v = 127;
1256 		}
1257 		writeReg(part, reg, v);
1258 	}
1259 
1260 	for (; reg < 0x90; reg += 4)
1261 		bufferedWriteReg(part, reg, *src++);
1262 
1263 	reg += 0x20;
1264 	bufferedWriteReg(part, reg, *src++);
1265 
1266 	uint8 v = *src++;
1267 	reg += 4;
1268 	if (v < 64)
1269 		v |= (_fmSaveReg[part][reg] & 0xc0);
1270 	bufferedWriteReg(part, reg, v);
1271 
1272 	return 0;
1273 }
1274 
fmLoadInstrument(int instrId,const uint8 * data)1275 int TownsAudioInterfaceInternal::fmLoadInstrument(int instrId, const uint8 *data) {
1276 	if (instrId > 127)
1277 		return 3;
1278 	assert(data);
1279 	memcpy(&_fmInstruments[instrId * 48], data, 48);
1280 	return 0;
1281 }
1282 
fmSetPitch(int chan,int pitch)1283 int TownsAudioInterfaceInternal::fmSetPitch(int chan, int pitch) {
1284 	if (chan > 5)
1285 		return 1;
1286 
1287 	uint8 bl = _fmChanNote[chan];
1288 	int frq = 0;
1289 
1290 	if (pitch < 0) {
1291 		if (bl) {
1292 			if (pitch < -8008)
1293 				pitch = -8008;
1294 			pitch *= -1;
1295 			pitch /= 13;
1296 			frq = _frequency[(bl - 1) % 12] - pitch;
1297 			bl = (bl - 1) / 12;
1298 			_fmChanPitch[chan] = -pitch;
1299 
1300 			if (frq < 616) {
1301 				if (bl) {
1302 					frq += 616;
1303 					bl--;
1304 				} else {
1305 					frq = 616;
1306 					bl = 0;
1307 				}
1308 			}
1309 		} else {
1310 			frq = 616;
1311 			bl = 0;
1312 		}
1313 
1314 	} else if (pitch > 0) {
1315 		if (bl < 96) {
1316 			if (pitch > 8008)
1317 				pitch = 8008;
1318 			pitch /= 13;
1319 
1320 			if (bl) {
1321 				frq = _frequency[(bl - 1) % 12] + pitch;
1322 				bl = (bl - 1) / 12;
1323 			} else {
1324 				frq = 616;
1325 				bl = 0;
1326 			}
1327 
1328 			_fmChanPitch[chan] = pitch;
1329 
1330 			if (frq > 1232) {
1331 				if (bl < 7) {
1332 					frq -= 616;
1333 					bl++;
1334 				} else {
1335 					frq = 1164;
1336 					bl = 7;
1337 				}
1338 			} else {
1339 				if (bl >= 7 && frq > 1164)
1340 					frq = 1164;
1341 			}
1342 
1343 		} else {
1344 			frq = 1164;
1345 			bl = 7;
1346 		}
1347 	} else {
1348 		_fmChanPitch[chan] = 0;
1349 		if (bl) {
1350 			frq = _frequency[(bl - 1) % 12];
1351 			bl = (bl - 1) / 12;
1352 		} else {
1353 			frq = 616;
1354 			bl = 0;
1355 		}
1356 	}
1357 
1358 	uint8 part = chan > 2 ? 1 : 0;
1359 	if (chan > 2)
1360 		chan -= 3;
1361 
1362 	frq |= (bl << 11);
1363 
1364 	bufferedWriteReg(part, chan + 0xa4, (frq >> 8));
1365 	bufferedWriteReg(part, chan + 0xa0, (frq & 0xff));
1366 
1367 	return 0;
1368 }
1369 
fmSetLevel(int chan,int lvl)1370 int TownsAudioInterfaceInternal::fmSetLevel(int chan, int lvl) {
1371 	if (chan > 5)
1372 		return 1;
1373 	if (lvl > 127)
1374 		return 3;
1375 
1376 	uint8 part = chan > 2 ? 1 : 0;
1377 	if (chan > 2)
1378 		chan -= 3;
1379 
1380 	uint16 c = _carrier[_fmSaveReg[part][0xb0 + chan] & 7];
1381 	_fmSaveReg[part][0xd0 + chan] = lvl;
1382 
1383 	for (uint8 reg = 0x40 + chan; reg < 0x50; reg += 4) {
1384 		c += c;
1385 		if (c & 0x100) {
1386 			c &= 0xff;
1387 			bufferedWriteReg(part, reg, (((((((_fmSaveReg[part][0x80 + reg] ^ 0x7f) * lvl) >> 7) + 1) * _fmSaveReg[part][0xe0 + chan]) >> 7) + 1) ^ 0x7f);
1388 		}
1389 	}
1390 	return 0;
1391 }
1392 
bufferedWriteReg(uint8 part,uint8 regAddress,uint8 value)1393 void TownsAudioInterfaceInternal::bufferedWriteReg(uint8 part, uint8 regAddress, uint8 value) {
1394 	_fmSaveReg[part][regAddress] = value;
1395 	writeReg(part, regAddress, value);
1396 }
1397 
pcmReset()1398 void TownsAudioInterfaceInternal::pcmReset() {
1399 	_numReservedChannels = 0;
1400 
1401 	for (int i = 0; i < 8; i++)
1402 		_pcmChan[i].clear();
1403 
1404 	memset(_pcmInstruments, 0, 128 * 32);
1405 	static uint8 name[] = { 0x4E, 0x6F, 0x20, 0x44, 0x61, 0x74, 0x61, 0x21 };
1406 	for (int i = 0; i < 32; i++)
1407 		memcpy(_pcmInstruments + i * 128, name, 8);
1408 
1409 	for (int i = 0; i < 128; i++)
1410 		_waveTables[i].clear();
1411 	_numWaveTables = 0;
1412 	_waveTablesTotalDataSize = 0;
1413 
1414 	for (int i = 0x40; i < 0x48; i++) {
1415 		pcmSetInstrument(i, 0);
1416 		pcmSetLevel(i, 127);
1417 	}
1418 }
1419 
pcmKeyOn(int chan,int note,int velo)1420 int TownsAudioInterfaceInternal::pcmKeyOn(int chan, int note, int velo) {
1421 	if (chan < 0x40 || chan > 0x47)
1422 		return 1;
1423 
1424 	if (note & 0x80 || velo & 0x80)
1425 		return 3;
1426 
1427 	chan -= 0x40;
1428 	uint8 noteT = note;
1429 	TownsAudio_PcmChannel *p = &_pcmChan[chan];
1430 
1431 	if (p->_reserved || p->_keyPressed)
1432 		return 2;
1433 
1434 	TownsAudio_WaveTable *w = _waveTables;
1435 	int res = p->initInstrument(noteT, w, _numWaveTables);
1436 	if (res)
1437 		return res;
1438 
1439 	p->loadData(w);
1440 	p->keyOn(noteT, velo, w);
1441 
1442 	return 0;
1443 }
1444 
pcmKeyOff(int chan)1445 int TownsAudioInterfaceInternal::pcmKeyOff(int chan) {
1446 	if (chan < 0x40 || chan > 0x47)
1447 		return 1;
1448 
1449 	chan -= 0x40;
1450 	_pcmChan[chan].keyOff();
1451 	return 0;
1452 }
1453 
pcmChanOff(int chan)1454 int TownsAudioInterfaceInternal::pcmChanOff(int chan) {
1455 	if (chan < 0x40 || chan > 0x47)
1456 		return 1;
1457 
1458 	chan -= 0x40;
1459 	_pcmChan[chan]._keyPressed = _pcmChan[chan]._activeEffect = _pcmChan[chan]._activeKey = _pcmChan[chan]._activeOutput = false;
1460 
1461 	return 0;
1462 }
1463 
pcmSetPanPos(int chan,int mode)1464 int TownsAudioInterfaceInternal::pcmSetPanPos(int chan, int mode) {
1465 	if (chan > 0x47)
1466 		return 1;
1467 	if (mode & 0x80)
1468 		return 3;
1469 
1470 	chan -= 0x40;
1471 	uint8 blc = 0x77;
1472 
1473 	if (mode > 64) {
1474 		mode -= 64;
1475 		blc = ((blc ^ (mode >> 3)) + (mode << 4)) & 0xff;
1476 	} else if (mode < 64) {
1477 		mode = (mode >> 3) ^ 7;
1478 		blc = ((119 + mode) ^ (mode << 4)) & 0xff;
1479 	}
1480 
1481 	_pcmChan[chan].setBalance(blc);
1482 
1483 	return 0;
1484 }
1485 
pcmSetInstrument(int chan,int instrId)1486 int TownsAudioInterfaceInternal::pcmSetInstrument(int chan, int instrId) {
1487 	if (chan > 0x47)
1488 		return 1;
1489 	if (instrId > 31)
1490 		return 3;
1491 	chan -= 0x40;
1492 	_pcmChan[chan].setInstrument(&_pcmInstruments[instrId * 128]);
1493 
1494 	return 0;
1495 }
1496 
pcmLoadInstrument(int instrId,const uint8 * data)1497 int TownsAudioInterfaceInternal::pcmLoadInstrument(int instrId, const uint8 *data) {
1498 	if (instrId > 31)
1499 		return 3;
1500 	assert(data);
1501 	memcpy(&_pcmInstruments[instrId * 128], data, 128);
1502 	return 0;
1503 }
1504 
pcmSetPitch(int chan,int pitch)1505 int TownsAudioInterfaceInternal::pcmSetPitch(int chan, int pitch) {
1506 	if (chan > 0x47)
1507 		return 1;
1508 
1509 	if (pitch < -8192 || pitch > 8191)
1510 		return 3;
1511 
1512 	chan -= 0x40;
1513 	TownsAudio_PcmChannel *p = &_pcmChan[chan];
1514 
1515 	uint32 pts = 0x4000;
1516 
1517 	if (pitch < 0)
1518 		pts = (0x20000000 / (-pitch + 0x2001)) >> 2;
1519 	else if (pitch > 0)
1520 		pts = (((pitch + 0x2001) << 16) / 0x2000) >> 2;
1521 
1522 	p->setPitch(pts);
1523 
1524 	return 0;
1525 }
1526 
pcmSetLevel(int chan,int lvl)1527 int TownsAudioInterfaceInternal::pcmSetLevel(int chan, int lvl) {
1528 	if (chan > 0x47)
1529 		return 1;
1530 
1531 	if (lvl & 0x80)
1532 		return 3;
1533 
1534 	chan -= 0x40;
1535 	_pcmChan[chan].setLevel(lvl);
1536 
1537 	return 0;
1538 }
1539 
updateOutputVolume()1540 void TownsAudioInterfaceInternal::updateOutputVolume() {
1541 	// Avoid calls to g_system->getAudioCDManager() functions from the main thread
1542 	// since this can cause mutex lockups.
1543 	_updateOutputVol = true;
1544 }
1545 
updateOutputVolumeInternal()1546 void TownsAudioInterfaceInternal::updateOutputVolumeInternal() {
1547 	if (!_ready)
1548 		return;
1549 
1550 	// FM Towns seems to support volumes of 0 - 63 for each channel.
1551 	// We recalculate sane values for our 0 to 255 volume range and
1552 	// balance values for our -128 to 127 volume range
1553 
1554 	// CD-AUDIO
1555 	uint32 maxVol = MAX(_outputLevel[12] * (_outputMute[12] ^ 1), _outputLevel[13] * (_outputMute[13] ^ 1));
1556 
1557 	int volume = (int)(((float)(maxVol * 255) / 63.0f));
1558 	int balance = maxVol ? (int)( ( ((int)_outputLevel[13] * (_outputMute[13] ^ 1) - _outputLevel[12] * (_outputMute[12] ^ 1)) * 127) / (float)maxVol) : 0;
1559 
1560 	g_system->getAudioCDManager()->setVolume(volume);
1561 	g_system->getAudioCDManager()->setBalance(balance);
1562 
1563 	_updateOutputVol = false;
1564 }
1565 
1566 TownsAudioInterfaceInternal *TownsAudioInterfaceInternal::_refInstance = 0;
1567 
1568 int TownsAudioInterfaceInternal::_refCount = 0;
1569 
1570 const uint8 TownsAudioInterfaceInternal::_chanFlags[] = {
1571 	0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
1572 };
1573 
1574 const uint16 TownsAudioInterfaceInternal::_frequency[] = {
1575 	0x028C, 0x02B4, 0x02DC, 0x030A, 0x0338, 0x0368, 0x039C, 0x03D4, 0x040E, 0x044A, 0x048C, 0x04D0
1576 };
1577 
1578 const uint8 TownsAudioInterfaceInternal::_carrier[] = {
1579 	0x10, 0x10, 0x10, 0x10, 0x30, 0x70, 0x70, 0xF0
1580 };
1581 
1582 const uint8 TownsAudioInterfaceInternal::_fmDefaultInstrument[] = {
1583 	0x45, 0x4C, 0x45, 0x50, 0x49, 0x41, 0x4E, 0x4F, 0x01, 0x0A, 0x02, 0x01,
1584 	0x1E, 0x32, 0x05, 0x00, 0x9C, 0xDC, 0x9C, 0xDC, 0x07, 0x03, 0x14, 0x08,
1585 	0x00, 0x03, 0x05, 0x05, 0x55, 0x45, 0x27, 0xA7, 0x04, 0xC0, 0x00, 0x00,
1586 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1587 };
1588 
TownsAudio_PcmChannel()1589 TownsAudio_PcmChannel::TownsAudio_PcmChannel() {
1590 	_extData = 0;
1591 	clear();
1592 }
1593 
~TownsAudio_PcmChannel()1594 TownsAudio_PcmChannel::~TownsAudio_PcmChannel() {
1595 	clear();
1596 }
1597 
clear()1598 void TownsAudio_PcmChannel::clear() {
1599 	_curInstrument = 0;
1600 	_note = _tl = _level = _velo = 0;
1601 
1602 	_data = 0;
1603 	_dataEnd = 0;
1604 	_loopLen = 0;
1605 
1606 	_pos = 0;
1607 	_loopStart = 0;
1608 
1609 	_step = 0;
1610 	_stepNote = 0x4000;
1611 	_stepPitch = 0x4000;
1612 
1613 	_panLeft = _panRight = 7;
1614 
1615 	_envTotalLevel = _envAttackRate = _envDecayRate = _envSustainLevel = _envSustainRate = _envReleaseRate = 0;
1616 	_envStep = _envCurrentLevel = 0;
1617 
1618 	_envState = kEnvReady;
1619 
1620 	_activeKey = _activeEffect = _activeOutput = _keyPressed = _reserved = false;
1621 
1622 	delete[] _extData;
1623 	_extData = 0;
1624 }
1625 
loadData(TownsAudio_WaveTable * w)1626 void TownsAudio_PcmChannel::loadData(TownsAudio_WaveTable *w) {
1627 	_data = w->data;
1628 	_dataEnd = w->size << 11;
1629 	_pos = 0;
1630 }
1631 
loadData(uint8 * buffer,uint32 size)1632 void TownsAudio_PcmChannel::loadData(uint8 *buffer, uint32 size) {
1633 	delete[] _extData;
1634 	_extData = new int8[size];
1635 	int8 *src = (int8 *)buffer;
1636 	int8 *dst = _extData;
1637 	for (uint32 i = 0; i < size; i++)
1638 		*dst++ = *src & 0x80 ? (*src++ & 0x7f) : -*src++;
1639 
1640 	_data = _extData;
1641 	_dataEnd = size << 11;
1642 	_pos = 0;
1643 }
1644 
initInstrument(uint8 & note,TownsAudio_WaveTable * & tables,int numTables)1645 int TownsAudio_PcmChannel::initInstrument(uint8 &note, TownsAudio_WaveTable *&tables, int numTables) {
1646 	int i = 0;
1647 	for (; i < 8; i++) {
1648 		if (note <= _curInstrument[16 + 2 * i])
1649 			break;
1650 	}
1651 
1652 	if (i == 8)
1653 		return 8;
1654 
1655 	uint8 *d = &_curInstrument[(i << 3) + 64];
1656 	_envTotalLevel = d[0];
1657 	_envAttackRate = d[1];
1658 	_envDecayRate = d[2];
1659 	_envSustainLevel = d[3];
1660 	_envSustainRate = d[4];
1661 	_envReleaseRate = d[5];
1662 	_envStep = 0;
1663 	note += d[6];
1664 
1665 	int32 id = (int32)READ_LE_UINT32(&_curInstrument[i * 4 + 32]);
1666 
1667 	for (i = 0; i < numTables; i++) {
1668 		if (id == tables[i].id)
1669 			break;
1670 	}
1671 
1672 	if (i == numTables)
1673 		return 9;
1674 
1675 	tables = &tables[i];
1676 	return 0;
1677 }
1678 
keyOn(uint8 note,uint8 velo,TownsAudio_WaveTable * w)1679 void TownsAudio_PcmChannel::keyOn(uint8 note, uint8 velo, TownsAudio_WaveTable *w) {
1680 	setupLoop(w->loopLen ? w->loopStart : w->size, w->loopLen);
1681 	setNote(note, w, _reserved);
1682 	setVelo(velo);
1683 
1684 	if (_reserved)
1685 		_activeEffect = true;
1686 	else
1687 		_keyPressed = _activeKey = true;
1688 
1689 	_activeOutput = true;
1690 }
1691 
keyOff()1692 void TownsAudio_PcmChannel::keyOff() {
1693 	_keyPressed = false;
1694 	envRelease();
1695 }
1696 
updateEnvelopeGenerator()1697 void TownsAudio_PcmChannel::updateEnvelopeGenerator() {
1698 	if (!_envCurrentLevel) {
1699 		_activeKey = false;
1700 		_envState = kEnvReady;
1701 	}
1702 
1703 	if (!_activeKey)
1704 		return;
1705 
1706 	switch (_envState) {
1707 	case kEnvAttacking:
1708 		if (((_envCurrentLevel + _envStep) >> 8) > _envTotalLevel) {
1709 			envDecay();
1710 			return;
1711 		} else {
1712 			_envCurrentLevel += _envStep;
1713 		}
1714 		break;
1715 
1716 	case kEnvDecaying:
1717 		if (((_envCurrentLevel - _envStep) >> 8) < _envSustainLevel) {
1718 			envSustain();
1719 			return;
1720 		} else {
1721 			_envCurrentLevel -= _envStep;
1722 		}
1723 		break;
1724 
1725 	case kEnvSustaining:
1726 	case kEnvReleasing:
1727 		_envCurrentLevel -= _envStep;
1728 		if (_envCurrentLevel <= 0)
1729 			_envCurrentLevel = 0;
1730 		break;
1731 
1732 	default:
1733 		break;
1734 	}
1735 	_tl = (_envCurrentLevel >> 8) << 1;
1736 }
1737 
setInstrument(uint8 * instr)1738 void TownsAudio_PcmChannel::setInstrument(uint8 *instr) {
1739 	_curInstrument = instr;
1740 }
1741 
setLevel(uint8 lvl)1742 void TownsAudio_PcmChannel::setLevel(uint8 lvl) {
1743 	if (_reserved) {
1744 		_velo = lvl;
1745 		_tl = lvl << 1;
1746 	} else {
1747 		int32 t = _envStep * lvl;
1748 		if (_level)
1749 			t /= _level;
1750 		_envStep = t;
1751 		t = _envCurrentLevel * lvl;
1752 		if (_level)
1753 			t /= _level;
1754 		_envCurrentLevel = t;
1755 		_level = lvl;
1756 		_tl = _envCurrentLevel >> 8;
1757 	}
1758 }
1759 
setPitch(uint32 pt)1760 void TownsAudio_PcmChannel::setPitch(uint32 pt) {
1761 	_stepPitch = pt & 0xffff;
1762 	_step = (_stepNote * _stepPitch) >> 14;
1763 
1764 //	if (_pcmChanUnkFlag & _chanFlags[chan])
1765 //		 unk[chan] = (((p->step * 1000) << 11) / 98) / 20833;
1766 
1767 	/*else*/
1768 	if (_activeEffect && (_step > 2048))
1769 		_step = 2048;
1770 }
1771 
setBalance(uint8 blc)1772 void TownsAudio_PcmChannel::setBalance(uint8 blc) {
1773 	_panLeft = blc & 0x0f;
1774 	_panRight = blc >> 4;
1775 }
1776 
updateOutput()1777 void TownsAudio_PcmChannel::updateOutput() {
1778 	if (_activeKey || _activeEffect) {
1779 		_pos += _step;
1780 
1781 		if (_pos >= _dataEnd) {
1782 			if (_loopStart != _dataEnd) {
1783 				_pos = _loopStart;
1784 				_dataEnd = _loopLen;
1785 			} else {
1786 				_pos = 0;
1787 				_activeKey = _activeEffect = false;
1788 			}
1789 		}
1790 	}
1791 }
1792 
currentSampleLeft()1793 int32 TownsAudio_PcmChannel::currentSampleLeft() {
1794 	return (_activeOutput && _panLeft) ? (((_data[_pos >> 11] * _tl) * _panLeft) >> 3) : 0;
1795 }
1796 
currentSampleRight()1797 int32 TownsAudio_PcmChannel::currentSampleRight() {
1798 	return (_activeOutput && _panRight) ? (((_data[_pos >> 11] * _tl) * _panRight) >> 3) : 0;
1799 }
1800 
setupLoop(uint32 loopStart,uint32 loopLen)1801 void TownsAudio_PcmChannel::setupLoop(uint32 loopStart, uint32 loopLen) {
1802 	_loopStart = loopStart << 11;
1803 	_loopLen = loopLen << 11;
1804 }
1805 
setNote(uint8 note,TownsAudio_WaveTable * w,bool stepLimit)1806 void TownsAudio_PcmChannel::setNote(uint8 note, TownsAudio_WaveTable *w, bool stepLimit) {
1807 	_note = note;
1808 	int8 diff = _note - w->baseNote;
1809 	uint16 r = w->rate + w->rateOffs;
1810 	uint16 bl = 0;
1811 	uint32 s = 0;
1812 
1813 	if (diff < 0) {
1814 		diff *= -1;
1815 		bl = diff % 12;
1816 		diff /= 12;
1817 		s = (r >> diff);
1818 		if (bl)
1819 			s = (s * _pcmPhase2[bl]) >> 16;
1820 
1821 	} else if (diff > 0) {
1822 		bl = diff % 12;
1823 		diff /= 12;
1824 		s = (r << diff);
1825 		if (bl)
1826 			s += ((s * _pcmPhase1[bl]) >> 16);
1827 
1828 	} else {
1829 		s = r;
1830 	}
1831 
1832 	_stepNote = s & 0xffff;
1833 	_step = (s * _stepPitch) >> 14;
1834 
1835 	if (stepLimit && _step > 2048)
1836 		_step = 2048;
1837 }
1838 
setVelo(uint8 velo)1839 void TownsAudio_PcmChannel::setVelo(uint8 velo) {
1840 	if (_reserved) {
1841 		_velo = velo;
1842 		_tl = velo << 1;
1843 	} else {
1844 		_velo = velo;
1845 		uint32 lvl = _level * _velo;
1846 		_envTotalLevel = ((_envTotalLevel * lvl) >> 14) & 0xff;
1847 		_envSustainLevel = ((_envSustainLevel * lvl) >> 14) & 0xff;
1848 		envAttack();
1849 		_tl = (_envCurrentLevel >> 8) << 1;
1850 	}
1851 }
1852 
envAttack()1853 void TownsAudio_PcmChannel::envAttack() {
1854 	_envState = kEnvAttacking;
1855 	int16 t = _envTotalLevel << 8;
1856 	if (_envAttackRate == 127) {
1857 		_envCurrentLevel = _envStep = 0;
1858 	} else if (_envAttackRate) {
1859 		_envStep = t / _envAttackRate;
1860 		_envCurrentLevel = 1;
1861 	} else {
1862 		_envCurrentLevel = t;
1863 		envDecay();
1864 	}
1865 }
1866 
envDecay()1867 void TownsAudio_PcmChannel::envDecay() {
1868 	_envState = kEnvDecaying;
1869 	int16 t = _envTotalLevel - _envSustainLevel;
1870 	if (t < 0 || _envDecayRate == 127) {
1871 		_envStep = 0;
1872 	} else if (_envDecayRate) {
1873 		_envStep = (t << 8) / _envDecayRate;
1874 	} else {
1875 		_envCurrentLevel = _envSustainLevel << 8;
1876 		envSustain();
1877 	}
1878 }
1879 
envSustain()1880 void TownsAudio_PcmChannel::envSustain() {
1881 	_envState = kEnvSustaining;
1882 	if (_envSustainLevel && _envSustainRate)
1883 		_envStep = (_envSustainRate == 127) ? 0 : (_envCurrentLevel / _envSustainRate) >> 1;
1884 	else
1885 		_envStep = _envCurrentLevel = 1;
1886 }
1887 
envRelease()1888 void TownsAudio_PcmChannel::envRelease() {
1889 	_envState = kEnvReleasing;
1890 	if (_envReleaseRate == 127)
1891 		_envStep = 0;
1892 	else if (_envReleaseRate)
1893 		_envStep = _envCurrentLevel / _envReleaseRate;
1894 	else
1895 		_envStep = _envCurrentLevel = 1;
1896 }
1897 
1898 const uint16 TownsAudio_PcmChannel::_pcmPhase1[] =  {
1899 	0x879B, 0x0F37, 0x1F58, 0x306E, 0x4288, 0x55B6, 0x6A08, 0x7F8F, 0x965E, 0xAE88, 0xC882, 0xE341
1900 };
1901 
1902 const uint16 TownsAudio_PcmChannel::_pcmPhase2[] =  {
1903 	0xFEFE, 0xF1A0, 0xE411, 0xD744, 0xCB2F, 0xBFC7, 0xB504, 0xAAE2, 0xA144, 0x9827, 0x8FAC
1904 };
1905 
TownsAudio_WaveTable()1906 TownsAudio_WaveTable::TownsAudio_WaveTable() {
1907 	data = 0;
1908 	clear();
1909 }
1910 
~TownsAudio_WaveTable()1911 TownsAudio_WaveTable::~TownsAudio_WaveTable() {
1912 	clear();
1913 }
1914 
readHeader(const uint8 * buffer)1915 void TownsAudio_WaveTable::readHeader(const uint8 *buffer) {
1916 	memcpy(name, buffer, 8);
1917 	name[8] = 0;
1918 	id = READ_LE_UINT32(&buffer[8]);
1919 	size = READ_LE_UINT32(&buffer[12]);
1920 	loopStart = READ_LE_UINT32(&buffer[16]);
1921 	loopLen = READ_LE_UINT32(&buffer[20]);
1922 	rate = READ_LE_UINT16(&buffer[24]);
1923 	rateOffs = READ_LE_UINT16(&buffer[26]);
1924 	baseNote = READ_LE_UINT32(&buffer[28]);
1925 }
1926 
readData(const uint8 * buffer)1927 void TownsAudio_WaveTable::readData(const uint8 *buffer) {
1928 	if (!size)
1929 		return;
1930 
1931 	delete[] data;
1932 	data = new int8[size];
1933 
1934 	const int8 *src = (const int8 *)buffer;
1935 	int8 *dst = data;
1936 	for (uint32 i = 0; i < size; i++)
1937 		*dst++ = *src & 0x80 ? (*src++ & 0x7f) : -*src++;
1938 }
1939 
clear()1940 void TownsAudio_WaveTable::clear() {
1941 	name[0] = name[8] = 0;
1942 	id = -1;
1943 	size = 0;
1944 	loopStart = 0;
1945 	loopLen = 0;
1946 	rate = 0;
1947 	rateOffs = 0;
1948 	baseNote = 0;
1949 	delete[] data;
1950 	data = 0;
1951 }
1952 
TownsAudioInterface(Audio::Mixer * mixer,TownsAudioInterfacePluginDriver * driver,bool externalMutex)1953 TownsAudioInterface::TownsAudioInterface(Audio::Mixer *mixer, TownsAudioInterfacePluginDriver *driver, bool externalMutex) {
1954 	_intf = TownsAudioInterfaceInternal::addNewRef(mixer, this, driver, externalMutex);
1955 }
1956 
~TownsAudioInterface()1957 TownsAudioInterface::~TownsAudioInterface() {
1958 	TownsAudioInterfaceInternal::releaseRef(this);
1959 	_intf = 0;
1960 }
1961 
init()1962 bool TownsAudioInterface::init() {
1963 	return _intf->init();
1964 }
1965 
callback(int command,...)1966 TownsAudioInterface::ErrorCode TownsAudioInterface::callback(int command, ...) {
1967 	va_list args;
1968 	va_start(args, command);
1969 
1970 	int res = _intf->processCommand(command, args);
1971 
1972 	va_end(args);
1973 	return (TownsAudioInterface::ErrorCode)res;
1974 }
1975 
setMusicVolume(int volume)1976 void TownsAudioInterface::setMusicVolume(int volume) {
1977 	_intf->setMusicVolume(volume);
1978 }
1979 
setSoundEffectVolume(int volume)1980 void TownsAudioInterface::setSoundEffectVolume(int volume) {
1981 	_intf->setSoundEffectVolume(volume);
1982 }
1983 
setSoundEffectChanMask(int mask)1984 void TownsAudioInterface::setSoundEffectChanMask(int mask) {
1985 	_intf->setSoundEffectChanMask(mask);
1986 }
1987