Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
125
Src/external_dependencies/openmpt-trunk/soundlib/OPL.h
Normal file
125
Src/external_dependencies/openmpt-trunk/soundlib/OPL.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* OPL.h
|
||||
* -----
|
||||
* Purpose: Translate data coming from OpenMPT's mixer into OPL commands to be sent to the Opal emulator.
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
#include "Snd_defs.h"
|
||||
|
||||
class Opal;
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
class OPL
|
||||
{
|
||||
public:
|
||||
enum OPLRegisters : uint8
|
||||
{
|
||||
// Operators (combine with result of OperatorToRegister)
|
||||
AM_VIB = 0x20, // AM / VIB / EG / KSR / Multiple (0x20 to 0x35)
|
||||
KSL_LEVEL = 0x40, // KSL / Total level (0x40 to 0x55)
|
||||
ATTACK_DECAY = 0x60, // Attack rate / Decay rate (0x60 to 0x75)
|
||||
SUSTAIN_RELEASE = 0x80, // Sustain level / Release rate (0x80 to 0x95)
|
||||
WAVE_SELECT = 0xE0, // Wave select (0xE0 to 0xF5)
|
||||
|
||||
// Channels (combine with result of ChannelToRegister)
|
||||
FNUM_LOW = 0xA0, // F-number low bits (0xA0 to 0xA8)
|
||||
KEYON_BLOCK = 0xB0, // F-number high bits / Key on / Block (octave) (0xB0 to 0xB8)
|
||||
FEEDBACK_CONNECTION = 0xC0, // Feedback / Connection (0xC0 to 0xC8)
|
||||
};
|
||||
|
||||
enum OPLValues : uint8
|
||||
{
|
||||
// AM_VIB
|
||||
TREMOLO_ON = 0x80,
|
||||
VIBRATO_ON = 0x40,
|
||||
SUSTAIN_ON = 0x20,
|
||||
KSR = 0x10, // Key scaling rate
|
||||
MULTIPLE_MASK = 0x0F, // Frequency multiplier
|
||||
|
||||
// KSL_LEVEL
|
||||
KSL_MASK = 0xC0, // Envelope scaling bits
|
||||
TOTAL_LEVEL_MASK = 0x3F, // Strength (volume) of OP
|
||||
|
||||
// ATTACK_DECAY
|
||||
ATTACK_MASK = 0xF0,
|
||||
DECAY_MASK = 0x0F,
|
||||
|
||||
// SUSTAIN_RELEASE
|
||||
SUSTAIN_MASK = 0xF0,
|
||||
RELEASE_MASK = 0x0F,
|
||||
|
||||
// KEYON_BLOCK
|
||||
KEYON_BIT = 0x20,
|
||||
|
||||
// FEEDBACK_CONNECTION
|
||||
FEEDBACK_MASK = 0x0E, // Valid just for first OP of a voice
|
||||
CONNECTION_BIT = 0x01,
|
||||
VOICE_TO_LEFT = 0x10,
|
||||
VOICE_TO_RIGHT = 0x20,
|
||||
STEREO_BITS = VOICE_TO_LEFT | VOICE_TO_RIGHT,
|
||||
};
|
||||
|
||||
class IRegisterLogger
|
||||
{
|
||||
public:
|
||||
virtual void Port(CHANNELINDEX c, uint16 reg, uint8 value) = 0;
|
||||
virtual ~IRegisterLogger() {}
|
||||
};
|
||||
|
||||
OPL(uint32 samplerate);
|
||||
OPL(IRegisterLogger &logger);
|
||||
~OPL();
|
||||
|
||||
void Initialize(uint32 samplerate);
|
||||
void Mix(int32 *buffer, size_t count, uint32 volumeFactorQ16);
|
||||
|
||||
void NoteOff(CHANNELINDEX c);
|
||||
void NoteCut(CHANNELINDEX c, bool unassign = true);
|
||||
void Frequency(CHANNELINDEX c, uint32 milliHertz, bool keyOff, bool beatingOscillators);
|
||||
void Volume(CHANNELINDEX c, uint8 vol, bool applyToModulator);
|
||||
int8 Pan(CHANNELINDEX c, int32 pan);
|
||||
void Patch(CHANNELINDEX c, const OPLPatch &patch);
|
||||
bool IsActive(CHANNELINDEX c) const { return GetVoice(c) != OPL_CHANNEL_INVALID; }
|
||||
void MoveChannel(CHANNELINDEX from, CHANNELINDEX to);
|
||||
void Reset();
|
||||
|
||||
// A list of all registers for channels and operators
|
||||
static std::vector<uint16> AllVoiceRegisters();
|
||||
|
||||
protected:
|
||||
static uint16 ChannelToRegister(uint8 oplCh);
|
||||
static uint16 OperatorToRegister(uint8 oplCh);
|
||||
static uint8 CalcVolume(uint8 trackerVol, uint8 kslVolume);
|
||||
uint8 GetVoice(CHANNELINDEX c) const;
|
||||
uint8 AllocateVoice(CHANNELINDEX c);
|
||||
void Port(CHANNELINDEX c, uint16 reg, uint8 value);
|
||||
|
||||
enum
|
||||
{
|
||||
OPL_CHANNELS = 18, // 9 for OPL2 or 18 for OPL3
|
||||
OPL_CHANNEL_CUT = 0x80, // Indicates that the channel has been cut and used as a hint to re-use the channel for the same tracker channel if possible
|
||||
OPL_CHANNEL_MASK = 0x7F,
|
||||
OPL_CHANNEL_INVALID = 0xFF,
|
||||
OPL_BASERATE = 49716,
|
||||
};
|
||||
|
||||
std::unique_ptr<Opal> m_opl;
|
||||
IRegisterLogger *m_logger = nullptr;
|
||||
|
||||
std::array<uint8, OPL_CHANNELS> m_KeyOnBlock;
|
||||
std::array<CHANNELINDEX, OPL_CHANNELS> m_OPLtoChan;
|
||||
std::array<uint8, MAX_CHANNELS> m_ChanToOPL;
|
||||
std::array<OPLPatch, OPL_CHANNELS> m_Patches;
|
||||
|
||||
bool m_isActive = false;
|
||||
};
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue