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 #ifndef SCUMM_IMUSE_PCSPK_H 24 #define SCUMM_IMUSE_PCSPK_H 25 26 #include "audio/softsynth/emumidi.h" 27 #include "audio/softsynth/pcspk.h" 28 29 namespace Scumm { 30 31 class PcSpkDriver : public MidiDriver_Emulated { 32 public: 33 PcSpkDriver(Audio::Mixer *mixer); 34 ~PcSpkDriver() override; 35 36 int open() override; 37 void close() override; 38 39 void send(uint32 d) override; 40 void sysEx_customInstrument(byte channel, uint32 type, const byte *instr) override; 41 42 MidiChannel *allocateChannel() override; getPercussionChannel()43 MidiChannel *getPercussionChannel() override { return 0; } 44 isStereo()45 bool isStereo() const override { return _pcSpk.isStereo(); } getRate()46 int getRate() const override { return _pcSpk.getRate(); } 47 protected: 48 void generateSamples(int16 *buf, int len) override; 49 void onTimer() override; 50 51 private: 52 Audio::PCSpeaker _pcSpk; 53 int _effectTimer; 54 uint8 _randBase; 55 56 void updateNote(); 57 void output(uint16 out); 58 59 static uint8 getEffectModifier(uint16 level); 60 int16 getEffectModLevel(int16 level, int8 mod); 61 int16 getRandScale(int16 input); 62 63 struct EffectEnvelope { 64 uint8 state; 65 int16 currentLevel; 66 int16 duration; 67 int16 maxLevel; 68 int16 startLevel; 69 uint8 loop; 70 uint8 stateTargetLevels[4]; 71 uint8 stateModWheelLevels[4]; 72 uint8 modWheelSensitivity; 73 uint8 modWheelState; 74 uint8 modWheelLast; 75 int16 stateNumSteps; 76 int16 stateStepCounter; 77 int16 changePerStep; 78 int8 dir; 79 int16 changePerStepRem; 80 int16 changeCountRem; 81 }; 82 83 struct EffectDefinition { 84 int16 phase; 85 uint8 type; 86 uint8 useModWheel; 87 EffectEnvelope *envelope; 88 }; 89 90 struct OutputChannel { 91 uint8 active; 92 uint8 note; 93 uint8 sustainNoteOff; 94 uint8 length; 95 const uint8 *instrument; 96 uint8 unkA; 97 uint8 unkB; 98 uint8 unkC; 99 int16 unkE; 100 EffectEnvelope effectEnvelopeA; 101 EffectDefinition effectDefA; 102 EffectEnvelope effectEnvelopeB; 103 EffectDefinition effectDefB; 104 int16 unk60; 105 }; 106 107 struct MidiChannel_PcSpk : public MidiChannel { 108 MidiDriver *device() override; 109 byte getNumber() override; 110 void release() override; 111 112 void send(uint32 b) override; 113 void noteOff(byte note) override; 114 void noteOn(byte note, byte velocity) override; 115 void programChange(byte program) override; 116 void pitchBend(int16 bend) override; 117 void controlChange(byte control, byte value) override; 118 void pitchBendFactor(byte value) override; 119 void priority(byte value) override; 120 void sysEx_customInstrument(uint32 type, const byte *instr) override; 121 122 void init(PcSpkDriver *owner, byte channel); 123 bool allocate(); 124 125 PcSpkDriver *_owner; 126 bool _allocated; 127 byte _channel; 128 129 OutputChannel _out; 130 uint8 _instrument[23]; 131 uint8 _programNr; 132 uint8 _priority; 133 uint8 _tl; 134 uint8 _modWheel; 135 uint8 _sustain; 136 uint8 _pitchBendFactor; 137 int16 _pitchBend; 138 }; 139 140 void setupEffects(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def, byte flags, const byte *data); 141 void startEffect(EffectEnvelope &env, const byte *data); 142 void initNextEnvelopeState(EffectEnvelope &env); 143 void updateEffectGenerator(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def); 144 uint8 advanceEffectEnvelope(EffectEnvelope &env, EffectDefinition &def); 145 146 MidiChannel_PcSpk _channels[6]; 147 MidiChannel_PcSpk *_activeChannel; 148 149 MidiChannel_PcSpk *_lastActiveChannel; 150 uint16 _lastActiveOut; 151 152 static const byte _outInstrumentData[1024]; 153 static const byte _outputTable1[]; 154 static const byte _outputTable2[]; 155 static const uint16 _effectEnvStepTable[]; 156 static const uint16 _frequencyTable[]; 157 }; 158 159 } // End of namespace Scumm 160 161 #endif 162