mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 23:21:41 +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)
|
void OPLio::OPLwriteChannel(uint regbase, uint channel, uchar data1, uchar data2)
|
||||||
{
|
{
|
||||||
static const uint op_num[] = {
|
static const uint op_num[OPL2CHANNELS] = {
|
||||||
0x000, 0x001, 0x002, 0x008, 0x009, 0x00A, 0x010, 0x011, 0x012,
|
0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12};
|
||||||
0x100, 0x101, 0x102, 0x108, 0x109, 0x10A, 0x110, 0x111, 0x112};
|
|
||||||
|
|
||||||
uint reg = regbase+op_num[channel];
|
uint which = channel / OPL2CHANNELS;
|
||||||
uint which = reg>>8;
|
uint reg = regbase + op_num[channel % OPL2CHANNELS];
|
||||||
OPLwriteReg (which, reg, data1);
|
OPLwriteReg (which, reg, data1);
|
||||||
OPLwriteReg (which, reg+3, data2);
|
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)
|
void OPLio::OPLwriteValue(uint regbase, uint channel, uchar value)
|
||||||
{
|
{
|
||||||
static const uint reg_num[] = {
|
uint which = channel / OPL2CHANNELS;
|
||||||
0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x006, 0x007, 0x008,
|
uint reg = regbase + (channel % OPL2CHANNELS);
|
||||||
0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107, 0x108};
|
|
||||||
|
|
||||||
uint reg = regbase+reg_num[channel];
|
|
||||||
uint which = reg>>8;
|
|
||||||
OPLwriteReg (which, reg, value);
|
OPLwriteReg (which, reg, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,9 +249,10 @@ void OPLio::OPLwritePan(uint channel, struct OPL2instrument *instr, int pan)
|
||||||
OPLwriteValue(0xC0, channel, instr->feedback | bits);
|
OPLwriteValue(0xC0, channel, instr->feedback | bits);
|
||||||
|
|
||||||
// Set real panning if we're using emulated chips.
|
// 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)
|
int OPLio::OPLinit(uint numchips, bool stereo)
|
||||||
{
|
{
|
||||||
assert(numchips >= 1 && numchips <= 2);
|
assert(numchips >= 1 && numchips <= countof(chips));
|
||||||
uint i;
|
uint i;
|
||||||
memset(chips, 0, sizeof(chips));
|
memset(chips, 0, sizeof(chips));
|
||||||
for (i = 0; i < numchips; ++i)
|
for (i = 0; i < numchips; ++i)
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
|
|
||||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||||
|
|
||||||
|
EXTERN_CVAR(Int, opl_numchips)
|
||||||
|
|
||||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||||
|
|
||||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||||
|
@ -92,7 +94,7 @@ OPLMIDIDevice::OPLMIDIDevice()
|
||||||
|
|
||||||
int OPLMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata)
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,8 @@ struct OP2instrEntry {
|
||||||
/* From MLOPL_IO.CPP */
|
/* From MLOPL_IO.CPP */
|
||||||
#define OPL2CHANNELS 9
|
#define OPL2CHANNELS 9
|
||||||
#define OPL3CHANNELS 18
|
#define OPL3CHANNELS 18
|
||||||
#define MAXCHANNELS 18
|
#define MAXOPL2CHIPS 8
|
||||||
|
#define MAXCHANNELS (OPL2CHANNELS * MAXOPL2CHIPS)
|
||||||
|
|
||||||
|
|
||||||
/* Channel Flags: */
|
/* Channel Flags: */
|
||||||
|
@ -183,7 +184,7 @@ struct OPLio {
|
||||||
virtual void SetClockRate(double samples_per_tick);
|
virtual void SetClockRate(double samples_per_tick);
|
||||||
virtual void WriteDelay(int ticks);
|
virtual void WriteDelay(int ticks);
|
||||||
|
|
||||||
class OPLEmul *chips[2];
|
class OPLEmul *chips[MAXOPL2CHIPS];
|
||||||
uint OPLchannels;
|
uint OPLchannels;
|
||||||
uint NumChips;
|
uint NumChips;
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
|
|
||||||
#define IMF_RATE 700.0
|
#define IMF_RATE 700.0
|
||||||
|
|
||||||
EXTERN_CVAR (Bool, opl_onechip)
|
EXTERN_CVAR (Int, opl_numchips)
|
||||||
|
|
||||||
OPLmusicBlock::OPLmusicBlock()
|
OPLmusicBlock::OPLmusicBlock()
|
||||||
{
|
{
|
||||||
scoredata = NULL;
|
scoredata = NULL;
|
||||||
NextTickIn = 0;
|
NextTickIn = 0;
|
||||||
LastOffset = 0;
|
LastOffset = 0;
|
||||||
TwoChips = !opl_onechip;
|
NumChips = MIN(*opl_numchips, 2);
|
||||||
Looping = false;
|
Looping = false;
|
||||||
IsStereo = false;
|
IsStereo = false;
|
||||||
io = NULL;
|
io = NULL;
|
||||||
|
@ -37,10 +37,9 @@ OPLmusicBlock::~OPLmusicBlock()
|
||||||
|
|
||||||
void OPLmusicBlock::ResetChips ()
|
void OPLmusicBlock::ResetChips ()
|
||||||
{
|
{
|
||||||
TwoChips = !opl_onechip;
|
|
||||||
ChipAccess.Enter();
|
ChipAccess.Enter();
|
||||||
io->OPLdeinit ();
|
io->OPLdeinit ();
|
||||||
TwoChips = io->OPLinit(TwoChips + 1, IsStereo) == 2;
|
NumChips = io->OPLinit(MIN(*opl_numchips, 2), IsStereo);
|
||||||
ChipAccess.Leave();
|
ChipAccess.Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ fail: delete[] scoredata;
|
||||||
memcpy(scoredata, &musiccache[0], len);
|
memcpy(scoredata, &musiccache[0], len);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == io->OPLinit (TwoChips + 1))
|
if (0 == (NumChips = io->OPLinit(NumChips)))
|
||||||
{
|
{
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -411,7 +410,7 @@ int OPLmusicFile::PlayTick ()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // It's something to stuff into the OPL chip
|
default: // It's something to stuff into the OPL chip
|
||||||
if (WhichChip == 0 || TwoChips)
|
if (WhichChip < NumChips)
|
||||||
{
|
{
|
||||||
io->OPLwriteReg(WhichChip, reg, data);
|
io->OPLwriteReg(WhichChip, reg, data);
|
||||||
}
|
}
|
||||||
|
@ -454,7 +453,7 @@ int OPLmusicFile::PlayTick ()
|
||||||
{
|
{
|
||||||
data = *score++;
|
data = *score++;
|
||||||
}
|
}
|
||||||
if (WhichChip == 0 || TwoChips)
|
if (WhichChip < NumChips)
|
||||||
{
|
{
|
||||||
io->OPLwriteReg(WhichChip, reg, data);
|
io->OPLwriteReg(WhichChip, reg, data);
|
||||||
}
|
}
|
||||||
|
@ -485,7 +484,7 @@ int OPLmusicFile::PlayTick ()
|
||||||
{
|
{
|
||||||
return (data + 1) << 8;
|
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);
|
io->OPLwriteReg(which, to_reg[code], data);
|
||||||
}
|
}
|
||||||
|
@ -527,14 +526,14 @@ OPLmusicFile::OPLmusicFile(const OPLmusicFile *source, const char *filename)
|
||||||
SamplesPerTick = source->SamplesPerTick;
|
SamplesPerTick = source->SamplesPerTick;
|
||||||
RawPlayer = source->RawPlayer;
|
RawPlayer = source->RawPlayer;
|
||||||
score = source->score;
|
score = source->score;
|
||||||
TwoChips = source->TwoChips;
|
NumChips = source->NumChips;
|
||||||
WhichChip = 0;
|
WhichChip = 0;
|
||||||
if (io != NULL)
|
if (io != NULL)
|
||||||
{
|
{
|
||||||
delete io;
|
delete io;
|
||||||
}
|
}
|
||||||
io = new DiskWriterIO(filename);
|
io = new DiskWriterIO(filename);
|
||||||
io->OPLinit(TwoChips + 1);
|
NumChips = io->OPLinit(NumChips);
|
||||||
Restart();
|
Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ protected:
|
||||||
|
|
||||||
double NextTickIn;
|
double NextTickIn;
|
||||||
double SamplesPerTick;
|
double SamplesPerTick;
|
||||||
bool TwoChips;
|
int NumChips;
|
||||||
bool Looping;
|
bool Looping;
|
||||||
double LastOffset;
|
double LastOffset;
|
||||||
bool IsStereo;
|
bool IsStereo;
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
#include "i_musicinterns.h"
|
#include "i_musicinterns.h"
|
||||||
|
#include "oplsynth/muslib.h"
|
||||||
|
|
||||||
static bool OPL_Active;
|
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 ();
|
static_cast<OPLMUSSong *>(currSong)->ResetChips ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1408,7 +1408,7 @@ OptionMenu AdvSoundOptions
|
||||||
Option "Buffer count", "snd_buffercount", "BufferCounts"
|
Option "Buffer count", "snd_buffercount", "BufferCounts"
|
||||||
StaticText " "
|
StaticText " "
|
||||||
StaticText "OPL Synthesis", 1
|
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"
|
Option "Support MIDI stero panning", "opl_stereo", "OnOff"
|
||||||
StaticText " "
|
StaticText " "
|
||||||
StaticText "GUS Emulation", 1
|
StaticText "GUS Emulation", 1
|
||||||
|
|
Loading…
Reference in a new issue