- Renamed opl_stereo to opl_fullpan, since DOSBox's core is emulating an OPL3, which is stereo

but only supports three pan positions and not the full 127 MIDI pan positions.
- Added opl_core cvar to select emulator core. 0 is MAME and 1 is DOSBox.
- Added DOSBox's LGPL OPL core, distantly related to one adlibemu.c written by Ken Silverman
  (not to be confused with the ancient MAME-derived and GPL-licensed core also found in DOSBox).
  I believe this corresponds to their "compat" emulator, but I'm not sure.

SVN r3946 (trunk)
This commit is contained in:
Randy Heit 2012-11-08 05:45:58 +00:00
parent 12ee3271c4
commit 3ec387ac32
14 changed files with 114 additions and 68 deletions

View file

@ -566,11 +566,6 @@ else( NO_ASM )
ADD_ASM_FILE( asm_ia32 tmap2 )
ADD_ASM_FILE( asm_ia32 tmap3 )
endif( X64 )
if( WIN32 )
if( NOT X64 )
ADD_ASM_FILE( win32 wrappers )
endif( NOT X64 )
endif( WIN32 )
endif( NO_ASM )
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h
@ -817,6 +812,7 @@ add_executable( zdoom WIN32
oplsynth/music_opldumper_mididevice.cpp
oplsynth/music_opl_mididevice.cpp
oplsynth/opl_mus_player.cpp
oplsynth/dosbox/opl.cpp
resourcefiles/ancientzip.cpp
resourcefiles/file_7z.cpp
resourcefiles/file_grp.cpp

View file

@ -100,7 +100,7 @@ Revision History:
#include <stdarg.h>
#include <math.h>
//#include "driver.h" /* use M.A.M.E. */
#include "fmopl.h"
#include "opl.h"
/* compiler dependence */
#ifndef OSD_CPU_H
@ -1576,17 +1576,9 @@ public:
}
/* YM3812 I/O interface */
int Write(int a, int v)
void WriteReg(int reg, int v)
{
if( !(a&1) )
{ /* address port */
Chip.address = v & 0xff;
}
else
{ /* data port */
OPLWriteReg(&Chip, Chip.address, v);
}
return Chip.status>>7;
OPLWriteReg(&Chip, reg & 0xff, v);
}
void Reset()
@ -1676,7 +1668,7 @@ public:
}
};
OPLEmul *YM3812Init(bool stereo)
OPLEmul *YM3812Create(bool stereo)
{
/* emulator create */
return new YM3812(stereo);

View file

@ -1,11 +0,0 @@
#ifndef __FMOPL_H_
#define __FMOPL_H_
#include "opl.h"
// Multiplying OPL_SAMPLE_RATE by ADLIB_CLOCK_MUL gives the number
// Adlib clocks per second, as used by the RAWADATA file format.
OPLEmul *YM3812Init(bool stereo);
#endif

View file

@ -42,7 +42,10 @@
#include <conio.h>
#endif
#include "muslib.h"
#include "fmopl.h"
#include "opl.h"
#include "c_cvars.h"
EXTERN_CVAR(Int, opl_core)
OPLio::~OPLio()
{
@ -58,8 +61,12 @@ void OPLio::WriteDelay(int ticks)
void OPLio::OPLwriteReg(int which, uint reg, uchar data)
{
chips[which]->Write(0, reg);
chips[which]->Write(1, data);
if (IsOPL3)
{
reg |= (which & 1) << 8;
which >>= 1;
}
chips[which]->WriteReg(reg, data);
}
/*
@ -249,10 +256,11 @@ 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.
int which = channel / OPL2CHANNELS;
int chanper = IsOPL3 ? OPL3CHANNELS : OPL2CHANNELS;
int which = channel / chanper;
if (chips[which] != NULL)
{
chips[which]->SetPanning(channel % OPL2CHANNELS, pan + 64);
chips[which]->SetPanning(channel % chanper, pan + 64);
}
}
}
@ -300,15 +308,20 @@ void OPLio::OPLshutup(void)
/*
* Initialize hardware upon startup
*/
int OPLio::OPLinit(uint numchips, bool stereo)
int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3)
{
assert(numchips >= 1 && numchips <= countof(chips));
uint i;
IsOPL3 = (opl_core == 1);
memset(chips, 0, sizeof(chips));
if (IsOPL3)
{
numchips = (numchips + 1) >> 1;
}
for (i = 0; i < numchips; ++i)
{
OPLEmul *chip = YM3812Init(stereo);
OPLEmul *chip = IsOPL3 ? DBOPLCreate(stereo) : YM3812Create(stereo);
if (chip == NULL)
{
break;
@ -316,18 +329,24 @@ int OPLio::OPLinit(uint numchips, bool stereo)
chips[i] = chip;
}
NumChips = i;
OPLchannels = OPL2CHANNELS * i;
OPLwriteInitState();
OPLchannels = i * (IsOPL3 ? OPL3CHANNELS : OPL2CHANNELS);
OPLwriteInitState(initopl3);
return i;
}
void OPLio::OPLwriteInitState()
void OPLio::OPLwriteInitState(bool initopl3)
{
for (uint i = 0; i < OPLchannels / OPL2CHANNELS; ++i)
for (uint i = 0; i < NumChips; ++i)
{
OPLwriteReg (i, 0x01, 0x20); // enable Waveform Select
OPLwriteReg (i, 0x0B, 0x40); // turn off CSW mode
OPLwriteReg (i, 0xBD, 0x00); // set vibrato/tremolo depth to low, set melodic mode
int chip = i << (int)IsOPL3;
if (IsOPL3 && initopl3)
{
OPLwriteReg(chip, 0x105, 0x01); // enable YMF262/OPL3 mode
OPLwriteReg(chip, 0x104, 0x00); // disable 4-operator mode
}
OPLwriteReg(chip, 0x01, 0x20); // enable Waveform Select
OPLwriteReg(chip, 0x0B, 0x40); // turn off CSW mode
OPLwriteReg(chip, 0xBD, 0x00); // set vibrato/tremolo depth to low, set melodic mode
}
OPLshutup();
}

View file

@ -41,7 +41,7 @@
#include "m_swap.h"
#include "w_wad.h"
#include "v_text.h"
#include "fmopl.h"
#include "opl.h"
// MACROS ------------------------------------------------------------------
@ -66,7 +66,7 @@ EXTERN_CVAR(Int, opl_numchips)
// PUBLIC DATA DEFINITIONS -------------------------------------------------
CVAR(Bool, opl_stereo, true, CVAR_ARCHIVE);
CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
// CODE --------------------------------------------------------------------
@ -78,7 +78,7 @@ CVAR(Bool, opl_stereo, true, CVAR_ARCHIVE);
OPLMIDIDevice::OPLMIDIDevice()
{
IsStereo = opl_stereo;
FullPan = opl_fullpan;
FWadLump data = Wads.OpenLumpName("GENMIDI");
OPLloadBank(data);
SampleRate = (int)OPL_SAMPLE_RATE;
@ -94,11 +94,11 @@ OPLMIDIDevice::OPLMIDIDevice()
int OPLMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata)
{
if (io == NULL || 0 == (NumChips = io->OPLinit(opl_numchips, IsStereo)))
if (io == NULL || 0 == (NumChips = io->OPLinit(opl_numchips, FullPan, true)))
{
return 1;
}
int ret = OpenStream(14, IsStereo ? 0 : SoundStream::Mono, callback, userdata);
int ret = OpenStream(14, (FullPan || io->IsOPL3) ? 0 : SoundStream::Mono, callback, userdata);
if (ret == 0)
{
OPLstopMusic();

View file

@ -39,7 +39,7 @@
#include "doomdef.h"
#include "m_swap.h"
#include "w_wad.h"
#include "fmopl.h"
#include "opl.h"
// MACROS ------------------------------------------------------------------
@ -188,7 +188,7 @@ int DiskWriterIO::OPLinit(uint numchips, bool dontcare)
CurIntTime = 0;
CurChip = 0;
OPLchannels = OPL2CHANNELS * numchips;
OPLwriteInitState();
OPLwriteInitState(false);
return numchips;
}

View file

@ -176,9 +176,9 @@ struct OPLio {
void OPLwritePan(uint channel, struct OPL2instrument *instr, int pan);
void OPLwriteInstrument(uint channel, struct OPL2instrument *instr);
void OPLshutup(void);
void OPLwriteInitState();
void OPLwriteInitState(bool initopl3);
virtual int OPLinit(uint numchips, bool stereo=false);
virtual int OPLinit(uint numchips, bool stereo=false, bool initopl3=false);
virtual void OPLdeinit(void);
virtual void OPLwriteReg(int which, uint reg, uchar data);
virtual void SetClockRate(double samples_per_tick);
@ -187,6 +187,7 @@ struct OPLio {
class OPLEmul *chips[MAXOPL2CHIPS];
uint OPLchannels;
uint NumChips;
bool IsOPL3;
};
struct DiskWriterIO : public OPLio

View file

@ -12,10 +12,13 @@ public:
virtual ~OPLEmul() {}
virtual void Reset() = 0;
virtual int Write(int a, int v) = 0;
virtual void WriteReg(int reg, int v) = 0;
virtual void Update(float *buffer, int length) = 0;
virtual void SetPanning(int c, int pan) = 0;
virtual FString GetVoiceString() { return FString(); }
};
OPLEmul *YM3812Create(bool stereo);
OPLEmul *DBOPLCreate(bool stereo);
#endif

View file

@ -7,7 +7,7 @@
#include "opl_mus_player.h"
#include "doomtype.h"
#include "fmopl.h"
#include "opl.h"
#include "w_wad.h"
#include "templates.h"
#include "c_cvars.h"
@ -25,7 +25,7 @@ OPLmusicBlock::OPLmusicBlock()
LastOffset = 0;
NumChips = MIN(*opl_numchips, 2);
Looping = false;
IsStereo = false;
FullPan = false;
io = NULL;
io = new OPLio;
}
@ -39,7 +39,7 @@ void OPLmusicBlock::ResetChips ()
{
ChipAccess.Enter();
io->OPLdeinit ();
NumChips = io->OPLinit(MIN(*opl_numchips, 2), IsStereo);
NumChips = io->OPLinit(MIN(*opl_numchips, 2), FullPan);
ChipAccess.Leave();
}
@ -223,7 +223,8 @@ void OPLmusicFile::Restart ()
bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
{
float *samples1 = (float *)buff;
int numsamples = numbytes / (sizeof(float) << int(IsStereo));
int stereoshift = (int)(FullPan | io->IsOPL3);
int numsamples = numbytes / (sizeof(float) << stereoshift);
bool prevEnded = false;
bool res = true;
@ -243,12 +244,12 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
{
io->chips[i]->Update(samples1, samplesleft);
}
OffsetSamples(samples1, samplesleft << int(IsStereo));
OffsetSamples(samples1, samplesleft << stereoshift);
assert(NextTickIn == ticky);
NextTickIn -= samplesleft;
assert (NextTickIn >= 0);
numsamples -= samplesleft;
samples1 += samplesleft << int(IsStereo);
samples1 += samplesleft << stereoshift;
}
if (NextTickIn < 1)
@ -265,7 +266,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes)
{
io->chips[i]->Update(samples1, samplesleft);
}
OffsetSamples(samples1, numsamples << int(IsStereo));
OffsetSamples(samples1, numsamples << stereoshift);
}
res = false;
break;

View file

@ -21,7 +21,7 @@ protected:
int NumChips;
bool Looping;
double LastOffset;
bool IsStereo;
bool FullPan;
FCriticalSection ChipAccess;
};

View file

@ -19,6 +19,8 @@ CUSTOM_CVAR (Int, opl_numchips, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
}
}
CVAR(Int, opl_core, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
OPLMUSSong::OPLMUSSong (FILE *file, BYTE *musiccache, int len)
{
int samples = int(OPL_SAMPLE_RATE / 14);
@ -26,7 +28,7 @@ OPLMUSSong::OPLMUSSong (FILE *file, BYTE *musiccache, int len)
Music = new OPLmusicFile (file, musiccache, len);
m_Stream = GSnd->CreateStream (FillStream, samples*4,
SoundStream::Mono | SoundStream::Float, int(OPL_SAMPLE_RATE), this);
(opl_core != 1 ? SoundStream::Mono : 0) | SoundStream::Float, int(OPL_SAMPLE_RATE), this);
if (m_Stream == NULL)
{
Printf (PRINT_BOLD, "Could not create music stream.\n");

View file

@ -1400,6 +1400,12 @@ OptionValue GusMemory
4, "1024K"
}
OptionValue OplCores
{
0, "MAME"
1, "DOSBox"
}
OptionMenu AdvSoundOptions
{
Title "ADVANCED SOUND OPTIONS"
@ -1409,7 +1415,8 @@ OptionMenu AdvSoundOptions
StaticText " "
StaticText "OPL Synthesis", 1
Slider "Number of emulated OPL chips", "opl_numchips", 1, 8, 1, 0
Option "Support MIDI stero panning", "opl_stereo", "OnOff"
Option "Full MIDI stereo panning", "opl_fullpan", "OnOff"
Option "OPL Emulator Core", "opl_core", "OplCores"
StaticText " "
StaticText "GUS Emulation", 1
Slider "MIDI voices", "midi_voices", 16, 256, 4, 0

View file

@ -2602,10 +2602,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\oplsynth\fmopl.h"
>
</File>
<File
RelativePath=".\src\oplsynth\mlopl.cpp"
>
@ -2630,6 +2626,46 @@
RelativePath=".\src\oplsynth\opl_mus_player.h"
>
</File>
<Filter
Name="DOSBox"
>
<File
RelativePath=".\src\oplsynth\dosbox\opl.cpp"
>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\src\oplsynth\dosbox\opl.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Timidity"

View file

@ -115,7 +115,7 @@ set(ZLIB_SRCS
trees.c
uncompr.c
zutil.c
win32/zlib1.rc
# win32/zlib1.rc
)
# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION