1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef SCUMM_IMUSE_PCSPK_H
#define SCUMM_IMUSE_PCSPK_H
#include "audio/softsynth/emumidi.h"
#include "audio/softsynth/pcspk.h"
namespace Scumm {
class PcSpkDriver : public MidiDriver_Emulated {
public:
PcSpkDriver(Audio::Mixer *mixer);
~PcSpkDriver();
virtual int open();
virtual void close();
virtual void send(uint32 d);
virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr);
virtual MidiChannel *allocateChannel();
virtual MidiChannel *getPercussionChannel() { return 0; }
bool isStereo() const { return _pcSpk.isStereo(); }
int getRate() const { return _pcSpk.getRate(); }
protected:
void generateSamples(int16 *buf, int len);
void onTimer();
private:
Audio::PCSpeaker _pcSpk;
int _effectTimer;
uint8 _randBase;
void updateNote();
void output(uint16 out);
static uint8 getEffectModifier(uint16 level);
int16 getEffectModLevel(int16 level, int8 mod);
int16 getRandScale(int16 input);
struct EffectEnvelope {
uint8 state;
int16 currentLevel;
int16 duration;
int16 maxLevel;
int16 startLevel;
uint8 loop;
uint8 stateTargetLevels[4];
uint8 stateModWheelLevels[4];
uint8 modWheelSensitivity;
uint8 modWheelState;
uint8 modWheelLast;
int16 stateNumSteps;
int16 stateStepCounter;
int16 changePerStep;
int8 dir;
int16 changePerStepRem;
int16 changeCountRem;
};
struct EffectDefinition {
int16 phase;
uint8 type;
uint8 useModWheel;
EffectEnvelope *envelope;
};
struct OutputChannel {
uint8 active;
uint8 note;
uint8 sustainNoteOff;
uint8 length;
const uint8 *instrument;
uint8 unkA;
uint8 unkB;
uint8 unkC;
int16 unkE;
EffectEnvelope effectEnvelopeA;
EffectDefinition effectDefA;
EffectEnvelope effectEnvelopeB;
EffectDefinition effectDefB;
int16 unk60;
};
struct MidiChannel_PcSpk : public MidiChannel {
virtual MidiDriver *device();
virtual byte getNumber();
virtual void release();
virtual void send(uint32 b);
virtual void noteOff(byte note);
virtual void noteOn(byte note, byte velocity);
virtual void programChange(byte program);
virtual void pitchBend(int16 bend);
virtual void controlChange(byte control, byte value);
virtual void pitchBendFactor(byte value);
virtual void priority(byte value);
virtual void sysEx_customInstrument(uint32 type, const byte *instr);
void init(PcSpkDriver *owner, byte channel);
bool allocate();
PcSpkDriver *_owner;
bool _allocated;
byte _channel;
OutputChannel _out;
uint8 _instrument[23];
uint8 _programNr;
uint8 _priority;
uint8 _tl;
uint8 _modWheel;
uint8 _sustain;
uint8 _pitchBendFactor;
int16 _pitchBend;
};
void setupEffects(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def, byte flags, const byte *data);
void startEffect(EffectEnvelope &env, const byte *data);
void initNextEnvelopeState(EffectEnvelope &env);
void updateEffectGenerator(MidiChannel_PcSpk &chan, EffectEnvelope &env, EffectDefinition &def);
uint8 advanceEffectEnvelope(EffectEnvelope &env, EffectDefinition &def);
MidiChannel_PcSpk _channels[6];
MidiChannel_PcSpk *_activeChannel;
MidiChannel_PcSpk *_lastActiveChannel;
uint16 _lastActiveOut;
static const byte _outInstrumentData[1024];
static const byte _outputTable1[];
static const byte _outputTable2[];
static const uint16 _effectEnvStepTable[];
static const uint16 _frequencyTable[];
};
} // End of namespace Scumm
#endif
|