aboutsummaryrefslogtreecommitdiff
path: root/audio/softsynth/fmtowns_pc98/towns_euphony.h
diff options
context:
space:
mode:
Diffstat (limited to 'audio/softsynth/fmtowns_pc98/towns_euphony.h')
-rw-r--r--audio/softsynth/fmtowns_pc98/towns_euphony.h234
1 files changed, 137 insertions, 97 deletions
diff --git a/audio/softsynth/fmtowns_pc98/towns_euphony.h b/audio/softsynth/fmtowns_pc98/towns_euphony.h
index d77217884d..2e935a3ca5 100644
--- a/audio/softsynth/fmtowns_pc98/towns_euphony.h
+++ b/audio/softsynth/fmtowns_pc98/towns_euphony.h
@@ -24,160 +24,200 @@
#define TOWNS_EUP_H
#include "audio/softsynth/fmtowns_pc98/towns_audio.h"
+#include "common/array.h"
-class TownsEuphonyDriver : public TownsAudioInterfacePluginDriver {
+class EuphonyBaseDriver {
public:
- TownsEuphonyDriver(Audio::Mixer *mixer);
- virtual ~TownsEuphonyDriver();
+ EuphonyBaseDriver() {}
+ virtual ~EuphonyBaseDriver() {}
+
+ virtual bool init() { return true; }
+
+ virtual void send(uint8 command) = 0;
+};
+
+class EuphonyPlayer;
+
+class EuphonyDriver : public EuphonyBaseDriver {
+public:
+ EuphonyDriver(Audio::Mixer *mixer, EuphonyPlayer *pl);
+ ~EuphonyDriver();
bool init();
void reset();
+ int assignPartToChannel(int chan, int part);
+
+ void send(uint8 command);
+
+ void setTimerA(bool enable, int tempo);
+ void setTimerB(bool enable, int tempo);
+
void loadInstrument(int chanType, int id, const uint8 *data);
+ void setInstrument(int chan, int instrID);
void loadWaveTable(const uint8 *data);
void unloadWaveTable(int id);
- void reserveSoundEffectChannels(int num);
-
- int setMusicTempo(int tempo);
- int startMusicTrack(const uint8 *data, int trackSize, int startTick);
- void setMusicLoop(bool loop);
- void stopParser();
- bool parserIsPlaying() {return _playing; }
- void continueParsing();
+ void reserveSoundEffectChannels(int num);
void playSoundEffect(int chan, int note, int velo, const uint8 *data);
void stopSoundEffect(int chan);
bool soundEffectIsPlaying(int chan);
- void chanPanPos(int chan, int mode);
- void chanPitch(int chan, int pitch);
- void chanVolume(int chan, int vol);
+ void channelPan(int chan, int mode);
+ void channelPitch(int chan, int pitch);
+ void channelVolume(int chan, int vol);
void setOutputVolume(int chanType, int volLeft, int volRight);
+ void cdaToggle(int a);
- int configChan_enable(int tableEntry, int val);
- int configChan_setMode(int tableEntry, int val);
- int configChan_remap(int tableEntry, int val);
- int configChan_adjustVolume(int tableEntry, int val);
- int configChan_setTranspose(int tableEntry, int val);
+ void setMusicVolume(int volume);
+ void setSoundEffectVolume(int volume);
- int assignChannel(int chan, int tableEntry);
+private:
+ void noteOff();
+ void noteOn();
+ void controlChange_volume();
+ void controlChange_panPos();
+ void controlChange_allNotesOff();
+ void programChange();
+ void pitchWheel();
+
+ Common::Array<uint8> _currentEvent;
+ int8 *_partToChanMapping;
+ int8 *_sustainChannels;
- void timerCallback(int timerId);
+ struct Channel {
+ int8 part;
+ int8 next;
+ uint8 note;
+ uint8 pri;
+ } *_channels;
- void setMusicVolume(int volume);
- void setSoundEffectVolume(int volume);
+ TownsAudioInterface *_intf;
+};
- TownsAudioInterface *intf() {
- return _intf;
- }
+class Type0Driver : public EuphonyBaseDriver {
+public:
+ Type0Driver(EuphonyPlayer *pl);
+ ~Type0Driver();
-private:
- void resetTables();
+ bool init();
+
+ void send(uint8 command);
+};
+
+class EuphonyPlayer : public TownsAudioInterfacePluginDriver {
+public:
+ EuphonyPlayer(Audio::Mixer *mixer);
+ virtual ~EuphonyPlayer();
+
+ bool init();
+
+ int startTrack(const uint8 *data, int trackSize, int barLen);
+ void stop();
+ void pause();
+ void resume();
+
+ int setTempo(int tempo);
+ void setLoopStatus(bool loop);
+
+ bool isPlaying() {return _playing; }
+
+ int configPart_enable(int part, int val);
+ int configPart_setType(int part, int val);
+ int configPart_remap(int part, int val);
+ int configPart_adjustVolume(int part, int val);
+ int configPart_setTranspose(int part, int val);
+
+ void timerCallback(int timerId);
+
+ EuphonyDriver *driver() { return _eupDriver; }
+private:
+ void reset();
+ void resetPartConfig();
void resetTempo();
- void setTempoIntern(int tempo);
- void setTimerA(bool enable, int tempo);
- void setTimerB(bool enable, int tempo);
- void updatePulseCount();
- void updateTimeStampBase();
+ void updatePulseCounters();
+ void updateBeat();
void updateParser();
void updateCheckEot();
- bool parseNext();
- void jumpNextLoop();
+ bool parseEvent();
+ void proceedToNextEvent();
- void updateEventBuffer();
- void flushEventBuffer();
- void processBufferNote(int mode, int evt, int note, int velo);
-
- void resetControl();
- void resetControlIntern(int mode, int chan);
+ void updateHangingNotes();
+ void clearHangingNotes();
+
+ void resetAllControls();
+ void allPartsOff();
+
uint8 appendEvent(uint8 evt, uint8 chan);
- void sendEvent(uint8 mode, uint8 command);
-
- typedef bool(TownsEuphonyDriver::*EuphonyOpcode)();
- bool evtSetupNote();
- bool evtPolyphonicAftertouch();
- bool evtControlPitch();
- bool evtInstrumentChanAftertouch();
- bool evtLoadInstrument();
- bool evtAdvanceTimestampOffset();
- bool evtTempo();
- bool evtModeOrdrChange();
- bool evtNotImpl() {
- return false;
- }
+ typedef bool(EuphonyPlayer::*EuphonyEvent)();
+ bool event_notImpl();
+ bool event_noteOn();
+ bool event_polyphonicAftertouch();
+ bool event_controlChange_pitchWheel();
+ bool event_programChange_channelAftertouch();
+
+ bool event_loadInstrument();
+ bool event_advanceBar();
+ bool event_setTempo();
+ bool event_typeOrdrChange();
uint8 applyTranspose(uint8 in);
uint8 applyVolumeAdjust(uint8 in);
- void sendNoteOff();
- void sendNoteOn();
- void sendChanVolume();
- void sendPanPosition();
- void sendAllNotesOff();
- void sendSetInstrument();
- void sendPitch();
+ void sendEvent(uint8 type, uint8 command);
+ void sendNoteEvent(int type, int evt, int note, int velo);
+ void sendControllerReset(int type, int part);
+ void sendAllNotesOff(int type, int part);
+ void sendTempo(int tempo);
- int8 *_activeChannels;
- int8 *_sustainChannels;
+ uint8 *_partConfig_enable;
+ uint8 *_partConfig_type;
+ uint8 *_partConfig_ordr;
+ int8 *_partConfig_volume;
+ int8 *_partConfig_transpose;
- struct ActiveChannel {
- int8 chan;
- int8 next;
- uint8 note;
- uint8 sub;
- } *_assignedChannels;
-
- uint8 *_tEnable;
- uint8 *_tMode;
- uint8 *_tOrdr;
- int8 *_tLevel;
- int8 *_tTranspose;
-
- struct DlEvent {
+ struct TimedEvent {
uint8 evt;
- uint8 mode;
+ uint8 type;
uint8 note;
uint8 velo;
uint16 len;
- } *_eventBuffer;
- int _bufferedEventsCount;
-
- uint8 _para[2];
- uint8 _paraCount;
- uint8 _command;
+ } *_timedEvents;
+ int _timedEventsCount;
- uint8 _defaultBaseTickLen;
- uint8 _baseTickLen;
- uint32 _pulseCount;
+ uint8 _defaultBarLength;
+ uint8 _barLength;
+ int _playerUpdatesLeft;
int _tempoControlMode;
- int _extraTimingControlRemainder;
- int _extraTimingControl;
+ int _updatesPerPulseRemainder;
+ int _updatesPerPulse;
int _timerSetting;
- int8 _tempoDiff;
+ int8 _tempoMode1PulseCounter;
int _tempoModifier;
- uint32 _timeStampDest;
- uint32 _timeStampBase;
- int8 _elapsedEvents;
+ uint32 _bar;
+ uint32 _parseToBar;
+ int8 _tempoMode1UpdateF8;
uint8 _deltaTicks;
- uint32 _tickCounter;
+ uint32 _beat;
uint8 _defaultTempo;
int _trackTempo;
bool _loop;
bool _playing;
bool _endOfTrack;
- bool _suspendParsing;
+ bool _paused;
const uint8 *_musicStart;
const uint8 *_musicPos;
uint32 _musicTrackSize;
- TownsAudioInterface *_intf;
+ EuphonyDriver *_eupDriver;
+ EuphonyBaseDriver *_drivers[3];
};
#endif