mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- Replaced the opl_onechip cvar with opl_numchips. You can now emulate up to 8 of them for MIDI
playback. (Raw OPL playback will still clamp it to 2, since there's no use for more than that with any of the raw OPL formats.) SVN r3945 (trunk)
This commit is contained in:
parent
54ad69ebad
commit
12ee3271c4
7 changed files with 38 additions and 31 deletions
|
@ -68,12 +68,11 @@ void OPLio::OPLwriteReg(int which, uint reg, uchar data)
|
|||
*/
|
||||
void OPLio::OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2)
|
||||
{
|
||||
static const uint op_num[] = {
|
||||
0x000, 0x001, 0x002, 0x008, 0x009, 0x00A, 0x010, 0x011, 0x012,
|
||||
0x100, 0x101, 0x102, 0x108, 0x109, 0x10A, 0x110, 0x111, 0x112};
|
||||
static const uint op_num[OPL2CHANNELS] = {
|
||||
0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12};
|
||||
|
||||
uint reg = regbase+op_num[channel];
|
||||
uint which = reg>>8;
|
||||
uint which = channel / OPL2CHANNELS;
|
||||
uint reg = regbase + op_num[channel % OPL2CHANNELS];
|
||||
OPLwriteReg (which, reg, data1);
|
||||
OPLwriteReg (which, reg+3, data2);
|
||||
}
|
||||
|
@ -84,12 +83,8 @@ void OPLio::OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2
|
|||
*/
|
||||
void OPLio::OPLwriteValue(uint regbase, uint channel, uchar value)
|
||||
{
|
||||
static const uint reg_num[] = {
|
||||
0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008,
|
||||
0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108};
|
||||
|
||||
uint reg = regbase+reg_num[channel];
|
||||
uint which = reg>>8;
|
||||
uint which = channel / OPL2CHANNELS;
|
||||
uint reg = regbase + (channel % OPL2CHANNELS);
|
||||
OPLwriteReg (which, reg, value);
|
||||
}
|
||||
|
||||
|
@ -254,9 +249,10 @@ void OPLio::OPLwritePan(uint channel, struct OPL2instrument *instr, int pan)
|
|||
OPLwriteValue(0xC0, channel, instr->feedback | bits);
|
||||
|
||||
// Set real panning if we're using emulated chips.
|
||||
if (chips[0] != NULL)
|
||||
int which = channel / OPL2CHANNELS;
|
||||
if (chips[which] != NULL)
|
||||
{
|
||||
chips[channel/9]->SetPanning(channel%9, pan+64);
|
||||
chips[which]->SetPanning(channel % OPL2CHANNELS, pan + 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +302,7 @@ void OPLio::OPLshutup(void)
|
|||
*/
|
||||
int OPLio::OPLinit(uint numchips, bool stereo)
|
||||
{
|
||||
assert(numchips >= 1 && numchips <= 2);
|
||||
assert(numchips >= 1 && numchips <= countof(chips));
|
||||
uint i;
|
||||
memset(chips, 0, sizeof(chips));
|
||||
for (i = 0; i < numchips; ++i)
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
EXTERN_CVAR(Int, opl_numchips)
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
@ -92,7 +94,7 @@ OPLMIDIDevice::OPLMIDIDevice()
|
|||
|
||||
int OPLMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata)
|
||||
{
|
||||
if (io == NULL || 0 == io->OPLinit(TwoChips + 1, IsStereo))
|
||||
if (io == NULL || 0 == (NumChips = io->OPLinit(opl_numchips, IsStereo)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -141,7 +141,8 @@ struct OP2instrEntry {
|
|||
/* From MLOPL_IO.CPP */
|
||||
#define OPL2CHANNELS 9
|
||||
#define OPL3CHANNELS 18
|
||||
#define MAXCHANNELS 18
|
||||
#define MAXOPL2CHIPS 8
|
||||
#define MAXCHANNELS (OPL2CHANNELS * MAXOPL2CHIPS)
|
||||
|
||||
|
||||
/* Channel Flags: */
|
||||
|
@ -183,7 +184,7 @@ struct OPLio {
|
|||
virtual void SetClockRate(double samples_per_tick);
|
||||
virtual void WriteDelay(int ticks);
|
||||
|
||||
class OPLEmul *chips[2];
|
||||
class OPLEmul *chips[MAXOPL2CHIPS];
|
||||
uint OPLchannels;
|
||||
uint NumChips;
|
||||
};
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
|
||||
#define IMF_RATE 700.0
|
||||
|
||||
EXTERN_CVAR (Bool, opl_onechip)
|
||||
EXTERN_CVAR (Int, opl_numchips)
|
||||
|
||||
OPLmusicBlock::OPLmusicBlock()
|
||||
{
|
||||
scoredata = NULL;
|
||||
NextTickIn = 0;
|
||||
LastOffset = 0;
|
||||
TwoChips = !opl_onechip;
|
||||
NumChips = MIN(*opl_numchips, 2);
|
||||
Looping = false;
|
||||
IsStereo = false;
|
||||
io = NULL;
|
||||
|
@ -37,10 +37,9 @@ OPLmusicBlock::~OPLmusicBlock()
|
|||
|
||||
void OPLmusicBlock::ResetChips ()
|
||||
{
|
||||
TwoChips = !opl_onechip;
|
||||
ChipAccess.Enter();
|
||||
io->OPLdeinit ();
|
||||
TwoChips = io->OPLinit(TwoChips + 1, IsStereo) == 2;
|
||||
NumChips = io->OPLinit(MIN(*opl_numchips, 2), IsStereo);
|
||||
ChipAccess.Leave();
|
||||
}
|
||||
|
||||
|
@ -77,7 +76,7 @@ fail: delete[] scoredata;
|
|||
memcpy(scoredata, &musiccache[0], len);
|
||||
}
|
||||
|
||||
if (0 == io->OPLinit (TwoChips + 1))
|
||||
if (0 == (NumChips = io->OPLinit(NumChips)))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
@ -411,7 +410,7 @@ int OPLmusicFile::PlayTick ()
|
|||
break;
|
||||
|
||||
default: // It's something to stuff into the OPL chip
|
||||
if (WhichChip == 0 || TwoChips)
|
||||
if (WhichChip < NumChips)
|
||||
{
|
||||
io->OPLwriteReg(WhichChip, reg, data);
|
||||
}
|
||||
|
@ -454,7 +453,7 @@ int OPLmusicFile::PlayTick ()
|
|||
{
|
||||
data = *score++;
|
||||
}
|
||||
if (WhichChip == 0 || TwoChips)
|
||||
if (WhichChip < NumChips)
|
||||
{
|
||||
io->OPLwriteReg(WhichChip, reg, data);
|
||||
}
|
||||
|
@ -485,7 +484,7 @@ int OPLmusicFile::PlayTick ()
|
|||
{
|
||||
return (data + 1) << 8;
|
||||
}
|
||||
else if (code < to_reg_size && (which = 0 || TwoChips))
|
||||
else if (code < to_reg_size && which < NumChips)
|
||||
{
|
||||
io->OPLwriteReg(which, to_reg[code], data);
|
||||
}
|
||||
|
@ -527,14 +526,14 @@ OPLmusicFile::OPLmusicFile(const OPLmusicFile *source, const char *filename)
|
|||
SamplesPerTick = source->SamplesPerTick;
|
||||
RawPlayer = source->RawPlayer;
|
||||
score = source->score;
|
||||
TwoChips = source->TwoChips;
|
||||
NumChips = source->NumChips;
|
||||
WhichChip = 0;
|
||||
if (io != NULL)
|
||||
{
|
||||
delete io;
|
||||
}
|
||||
io = new DiskWriterIO(filename);
|
||||
io->OPLinit(TwoChips + 1);
|
||||
NumChips = io->OPLinit(NumChips);
|
||||
Restart();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ protected:
|
|||
|
||||
double NextTickIn;
|
||||
double SamplesPerTick;
|
||||
bool TwoChips;
|
||||
int NumChips;
|
||||
bool Looping;
|
||||
double LastOffset;
|
||||
bool IsStereo;
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
#include "i_musicinterns.h"
|
||||
#include "oplsynth/muslib.h"
|
||||
|
||||
static bool OPL_Active;
|
||||
|
||||
CUSTOM_CVAR (Bool, opl_onechip, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CUSTOM_CVAR (Int, opl_numchips, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
{
|
||||
if (OPL_Active && currSong != NULL)
|
||||
if (*self <= 0)
|
||||
{
|
||||
self = 1;
|
||||
}
|
||||
else if (*self > MAXOPL2CHIPS)
|
||||
{
|
||||
self = MAXOPL2CHIPS;
|
||||
}
|
||||
else if (OPL_Active && currSong != NULL)
|
||||
{
|
||||
static_cast<OPLMUSSong *>(currSong)->ResetChips ();
|
||||
}
|
||||
|
|
|
@ -1408,7 +1408,7 @@ OptionMenu AdvSoundOptions
|
|||
Option "Buffer count", "snd_buffercount", "BufferCounts"
|
||||
StaticText " "
|
||||
StaticText "OPL Synthesis", 1
|
||||
Option "Only emulate one OPL chip", "opl_onechip", "OnOff"
|
||||
Slider "Number of emulated OPL chips", "opl_numchips", 1, 8, 1, 0
|
||||
Option "Support MIDI stero panning", "opl_stereo", "OnOff"
|
||||
StaticText " "
|
||||
StaticText "GUS Emulation", 1
|
||||
|
|
Loading…
Reference in a new issue