mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-18 23:57:32 +00:00
161 lines
4.3 KiB
C++
161 lines
4.3 KiB
C++
/* 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
|