Remove unused code, fix more warnings.
This commit is contained in:
parent
018d4bfbc0
commit
761069397c
9 changed files with 4 additions and 2415 deletions
|
@ -11,8 +11,8 @@
|
||||||
buildAAX="0" includeBinaryInAppConfig="1" pluginIsMidiEffectPlugin="0"
|
buildAAX="0" includeBinaryInAppConfig="1" pluginIsMidiEffectPlugin="0"
|
||||||
companyWebsite="https://bsutherland.github.io/JuceOPLVSTi/" buildAUv3="0"
|
companyWebsite="https://bsutherland.github.io/JuceOPLVSTi/" buildAUv3="0"
|
||||||
displaySplashScreen="1" reportAppUsage="1" splashScreenColour="Dark"
|
displaySplashScreen="1" reportAppUsage="1" splashScreenColour="Dark"
|
||||||
buildStandalone="0" enableIAA="0" cppLanguageStandard="latest"
|
buildStandalone="0" enableIAA="0" companyCopyright="" pluginFormats="buildVST,buildAU"
|
||||||
companyCopyright="" pluginFormats="buildVST,buildAU" pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn">
|
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn">
|
||||||
<MAINGROUP id="TOefyq" name="JuceOPLVSTi">
|
<MAINGROUP id="TOefyq" name="JuceOPLVSTi">
|
||||||
<GROUP id="{DCA755EB-7953-0641-E719-95C7850E5B2B}" name="Source">
|
<GROUP id="{DCA755EB-7953-0641-E719-95C7850E5B2B}" name="Source">
|
||||||
<FILE id="AqQcu5" name="ChannelButtonLookAndFeel.cpp" compile="1" resource="0"
|
<FILE id="AqQcu5" name="ChannelButtonLookAndFeel.cpp" compile="1" resource="0"
|
||||||
|
@ -23,13 +23,7 @@
|
||||||
file="Source/OPLLookAndFeel.cpp"/>
|
file="Source/OPLLookAndFeel.cpp"/>
|
||||||
<FILE id="igacSV" name="OPLLookAndFeel.h" compile="0" resource="0"
|
<FILE id="igacSV" name="OPLLookAndFeel.h" compile="0" resource="0"
|
||||||
file="Source/OPLLookAndFeel.h"/>
|
file="Source/OPLLookAndFeel.h"/>
|
||||||
<FILE id="o0sULY" name="DROMultiplexer.cpp" compile="1" resource="0"
|
|
||||||
file="Source/DROMultiplexer.cpp"/>
|
|
||||||
<FILE id="cULQN7" name="DROMultiplexer.h" compile="0" resource="0"
|
|
||||||
file="Source/DROMultiplexer.h"/>
|
|
||||||
<FILE id="KRj0DZ" name="tests.cpp" compile="1" resource="0" file="Source/tests.cpp"/>
|
<FILE id="KRj0DZ" name="tests.cpp" compile="1" resource="0" file="Source/tests.cpp"/>
|
||||||
<FILE id="hjHmNq" name="zdopl.cpp" compile="1" resource="0" file="Source/zdopl.cpp"/>
|
|
||||||
<FILE id="TQyCKv" name="zdopl.h" compile="0" resource="0" file="Source/zdopl.h"/>
|
|
||||||
<FILE id="LVSdHL" name="InstrumentLoader.h" compile="0" resource="0"
|
<FILE id="LVSdHL" name="InstrumentLoader.h" compile="0" resource="0"
|
||||||
file="Source/InstrumentLoader.h"/>
|
file="Source/InstrumentLoader.h"/>
|
||||||
<FILE id="SX7G0u" name="SbiLoader.cpp" compile="1" resource="0" file="Source/SbiLoader.cpp"/>
|
<FILE id="SX7G0u" name="SbiLoader.cpp" compile="1" resource="0" file="Source/SbiLoader.cpp"/>
|
||||||
|
|
|
@ -1,420 +0,0 @@
|
||||||
#include "DROMultiplexer.h"
|
|
||||||
#include "JuceHeader.h"
|
|
||||||
|
|
||||||
/// Jeff-Russ added guard against windows.h include if not windows:
|
|
||||||
#ifdef _WIN32 // covers both 32 and 64-bit
|
|
||||||
#include <Windows.h>
|
|
||||||
#else
|
|
||||||
#include "windows.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Jeff-Russ added to replace mising itoa for xcode:
|
|
||||||
#if __APPLE__ || __linux__
|
|
||||||
#include "itoa.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Used by the first recording instance to claim master status
|
|
||||||
DROMultiplexer* DROMultiplexer::master = NULL;
|
|
||||||
|
|
||||||
// Mutex between plugin instances
|
|
||||||
CriticalSection DROMultiplexer::lock;
|
|
||||||
|
|
||||||
static Bit8u dro_header[] = {
|
|
||||||
'D', 'B', 'R', 'A', /* 0x00, Bit32u ID */
|
|
||||||
'W', 'O', 'P', 'L', /* 0x04, Bit32u ID */
|
|
||||||
0x0, 0x00, /* 0x08, Bit16u version low */
|
|
||||||
0x1, 0x00, /* 0x09, Bit16u version high */
|
|
||||||
0x0, 0x0, 0x0, 0x0, /* 0x0c, Bit32u total milliseconds */
|
|
||||||
0x0, 0x0, 0x0, 0x0, /* 0x10, Bit32u total data */
|
|
||||||
0x0, 0x0, 0x0, 0x0 /* 0x14, Bit32u Type 0=opl2,1=opl3,2=dual-opl2 */
|
|
||||||
};
|
|
||||||
|
|
||||||
static Bit8u dro_opl3_enable[] = {
|
|
||||||
0x03, // switch to extended register bank
|
|
||||||
0x05, // register 0x105
|
|
||||||
0x01, // value 0x1
|
|
||||||
0x02 // switch back to regular OPL2 registers
|
|
||||||
};
|
|
||||||
|
|
||||||
// offsets for the 15 two-operator melodic channels
|
|
||||||
// http://www.shikadi.net/moddingwiki/OPL_chip
|
|
||||||
static Bit32u OPERATOR_OFFSETS[15][2] = {
|
|
||||||
{0x000, 0x003}, // 0, 3
|
|
||||||
{0x001, 0x004}, // 1, 4
|
|
||||||
{0x002, 0x005}, // 2, 5
|
|
||||||
{0x008, 0x00b}, // 6, 9
|
|
||||||
{0x009, 0x00c}, // 7, 10
|
|
||||||
{0x00a, 0x00d}, // 8, 11
|
|
||||||
{0x100, 0x103}, // 18, 21
|
|
||||||
{0x101, 0x104}, // 19, 22
|
|
||||||
{0x102, 0x105}, // 20, 23
|
|
||||||
{0x108, 0x10b}, // 24, 27
|
|
||||||
{0x109, 0x10c}, // 25, 28
|
|
||||||
{0x10a, 0x10d}, // 26, 29
|
|
||||||
{0x110, 0x113}, // 30, 33
|
|
||||||
{0x111, 0x114}, // 31, 34
|
|
||||||
{0x112, 0x115}, // 32, 35
|
|
||||||
};
|
|
||||||
|
|
||||||
static Bit32u CHANNEL_OFFSETS[15]= {
|
|
||||||
0x0,
|
|
||||||
0x1,
|
|
||||||
0x2,
|
|
||||||
0x3,
|
|
||||||
0x4,
|
|
||||||
0x5,
|
|
||||||
0x100,
|
|
||||||
0x101,
|
|
||||||
0x102,
|
|
||||||
0x103,
|
|
||||||
0x104,
|
|
||||||
0x105,
|
|
||||||
0x106,
|
|
||||||
0x107,
|
|
||||||
0x108,
|
|
||||||
};
|
|
||||||
|
|
||||||
// bass drum uses two operators.
|
|
||||||
// others use either modulator or carrier.
|
|
||||||
static Bit32u PERCUSSION_OFFSETS[5][2] = {
|
|
||||||
{ 0x13, 0x10 }, // bd
|
|
||||||
{ 0x00, 0x14 }, // sd
|
|
||||||
{ 0x12, 0x00 }, // tt
|
|
||||||
{ 0x00, 0x15 }, // cy
|
|
||||||
{ 0x11, 0x00 }, // hh
|
|
||||||
};
|
|
||||||
|
|
||||||
static Bit32u PERCUSSION_CHANNELS[5] = {
|
|
||||||
7, 7, 8, 8, 9
|
|
||||||
// or 7, 8, 8, 9, 9?
|
|
||||||
};
|
|
||||||
|
|
||||||
INLINE void host_writed(Bit8u *off, Bit32u val) {
|
|
||||||
off[0] = (Bit8u)(val);
|
|
||||||
off[1] = (Bit8u)(val >> 8);
|
|
||||||
off[2] = (Bit8u)(val >> 16);
|
|
||||||
off[3] = (Bit8u)(val >> 24);
|
|
||||||
};
|
|
||||||
|
|
||||||
HANDLE conout;
|
|
||||||
DROMultiplexer::DROMultiplexer()
|
|
||||||
{
|
|
||||||
InitCaptureVariables();
|
|
||||||
#ifdef _DEBUG
|
|
||||||
AllocConsole();
|
|
||||||
conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DROMultiplexer::~DROMultiplexer()
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FreeConsole();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DROMultiplexer* DROMultiplexer::GetMaster() {
|
|
||||||
return DROMultiplexer::master;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CopyOplPercussionSettings(Hiopl* opl, int pIdx) {
|
|
||||||
// input channel 1 is as good as any..
|
|
||||||
int op1Off = opl->_GetOffset(1, 1);
|
|
||||||
int op2Off = opl->_GetOffset(1, 2);
|
|
||||||
Bit32u inAddr;
|
|
||||||
Bit32u outAddr;
|
|
||||||
|
|
||||||
Bit32u* outOff = PERCUSSION_OFFSETS[pIdx];
|
|
||||||
// waveform select
|
|
||||||
int base = 0xe0;
|
|
||||||
if (outOff[0]) {
|
|
||||||
inAddr = base + op1Off;
|
|
||||||
outAddr = base + outOff[0];
|
|
||||||
_CaptureRegWriteWithDelay(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
if (outOff[1]) {
|
|
||||||
inAddr = base + op2Off;
|
|
||||||
outAddr = base + outOff[1];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
// other operator settings
|
|
||||||
for (base = 0x20; base <= 0x80; base += 0x20) {
|
|
||||||
if (outOff[0]) {
|
|
||||||
inAddr = base + op1Off;
|
|
||||||
outAddr = base + outOff[0];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
if (outOff[1]) {
|
|
||||||
inAddr = base + op2Off;
|
|
||||||
outAddr = base + outOff[1];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// channel wide settings
|
|
||||||
int chInOff = opl->_GetOffset(1);
|
|
||||||
inAddr = 0xc0 + chInOff;
|
|
||||||
outAddr = 0xc0 + PERCUSSION_CHANNELS[pIdx];
|
|
||||||
_CaptureRegWrite(outAddr, 0x30 | opl->_ReadReg(inAddr)); // make sure L+R channels always enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CopyOplChannelSettings(Hiopl* opl, int inCh, int outCh) {
|
|
||||||
// read all instrument settings and write them all to the file
|
|
||||||
int op1Off = opl->_GetOffset(inCh, 1);
|
|
||||||
int op2Off = opl->_GetOffset(inCh, 2);
|
|
||||||
Bit32u inAddr;
|
|
||||||
Bit32u outAddr;
|
|
||||||
// waveform select
|
|
||||||
int base = 0xe0;
|
|
||||||
inAddr = base + op1Off;
|
|
||||||
outAddr = base + OPERATOR_OFFSETS[outCh][0];
|
|
||||||
_CaptureRegWriteWithDelay(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
inAddr = base + op2Off;
|
|
||||||
outAddr = base + OPERATOR_OFFSETS[outCh][1];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
// other operator settings
|
|
||||||
for (base = 0x20; base <= 0x80; base += 0x20) {
|
|
||||||
inAddr = base + op1Off;
|
|
||||||
outAddr = base + OPERATOR_OFFSETS[outCh][0];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
inAddr = base + op2Off;
|
|
||||||
outAddr = base + OPERATOR_OFFSETS[outCh][1];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// channel wide settings
|
|
||||||
int chInOff = opl->_GetOffset(inCh);
|
|
||||||
inAddr = 0xc0 + chInOff;
|
|
||||||
outAddr = 0xc0 + CHANNEL_OFFSETS[outCh];
|
|
||||||
_CaptureRegWrite(outAddr, 0x30 | opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::TwoOpMelodicNoteOn(Hiopl* opl, int inCh) {
|
|
||||||
const ScopedLock sl(lock);
|
|
||||||
|
|
||||||
// find a free channel and mark it as used
|
|
||||||
char addr[16];
|
|
||||||
int outCh = _FindFreeChannel(opl, inCh);
|
|
||||||
|
|
||||||
if (outCh >= 0) {
|
|
||||||
//_DebugOut(" <- ");
|
|
||||||
//_DebugOut(itoa((int)opl, addr, 16));
|
|
||||||
//_DebugOut(" ");
|
|
||||||
for (int i = 0; i < MELODIC_CHANNELS; i++) {
|
|
||||||
Hiopl* tmpOpl = channels[i].opl;
|
|
||||||
_DebugOut(NULL == tmpOpl ? "-" : tmpOpl->GetState(channels[i].ch));
|
|
||||||
}
|
|
||||||
//_DebugOut("\n");
|
|
||||||
_CopyOplChannelSettings(opl, inCh, outCh);
|
|
||||||
|
|
||||||
// note frequency
|
|
||||||
int chInOff = opl->_GetOffset(inCh);
|
|
||||||
int inAddr = 0xa0 + chInOff;
|
|
||||||
int outAddr = 0xa0 + CHANNEL_OFFSETS[outCh];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
_DebugOut(itoa(opl->_ReadReg(inAddr), addr, 16));
|
|
||||||
// note-on
|
|
||||||
inAddr = 0xb0 + chInOff;
|
|
||||||
outAddr = 0xb0 + CHANNEL_OFFSETS[outCh];
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
_DebugOut(" ");
|
|
||||||
_DebugOut(itoa(opl->_ReadReg(inAddr), addr, 16));
|
|
||||||
_DebugOut("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::TwoOpMelodicNoteOff(Hiopl* opl, int ch) {
|
|
||||||
const ScopedLock sl(lock);
|
|
||||||
|
|
||||||
int chOff = opl->_GetOffset(ch);
|
|
||||||
OplCh_t key;
|
|
||||||
key.opl = opl;
|
|
||||||
key.ch = ch;
|
|
||||||
|
|
||||||
int outCh = channelMap[key];
|
|
||||||
char n[8];
|
|
||||||
_DebugOut(itoa(outCh, n, 16));
|
|
||||||
_DebugOut(" note off\n");
|
|
||||||
// note-off
|
|
||||||
Bit32u inAddr = 0xb0 + chOff;
|
|
||||||
Bit32u outAddr = 0xb0 + CHANNEL_OFFSETS[outCh];
|
|
||||||
_CaptureRegWriteWithDelay(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_DebugOut(const char* str) {
|
|
||||||
#ifdef _DEBUG
|
|
||||||
DWORD count;
|
|
||||||
count = strlen(str);
|
|
||||||
WriteConsole(conout, str, count, &count, NULL);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int DROMultiplexer::_FindFreeChannel(Hiopl* opl, int inCh) {
|
|
||||||
int i = 0;
|
|
||||||
while (i < MELODIC_CHANNELS) {
|
|
||||||
if (NULL == channels[i].opl || !channels[i].opl->IsActive(channels[i].ch)) {
|
|
||||||
channels[i].opl = opl;
|
|
||||||
channels[i].ch = inCh;
|
|
||||||
channelMap[channels[i]] = i;
|
|
||||||
char n[8];
|
|
||||||
_DebugOut(itoa(i, n, 16));
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
// fall back to a released channel for same opl instance
|
|
||||||
i = 0;
|
|
||||||
while (i < MELODIC_CHANNELS) {
|
|
||||||
if (opl == channels[i].opl && 'R' == opl->GetState(channels[i].ch)[0]) {
|
|
||||||
channels[i].opl = opl;
|
|
||||||
channels[i].ch = inCh;
|
|
||||||
channelMap[channels[i]] = i;
|
|
||||||
char n[8];
|
|
||||||
_DebugOut(itoa(i, n, 16));
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
_DebugOut("Could not find free channel!");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::PercussionChange(Hiopl* opl, int pIdx) {
|
|
||||||
const ScopedLock sl(lock);
|
|
||||||
_CopyOplPercussionSettings(opl, pIdx);
|
|
||||||
Bit8u val = opl->_ReadReg(0xbd);
|
|
||||||
Bit8u maskOut = 1 << abs(4 - pIdx);
|
|
||||||
if (0 == (val & maskOut)) { // note-off
|
|
||||||
_CaptureRegWriteWithDelay(0xbd, 0xBD & (0xe0 | ~maskOut));
|
|
||||||
} else { // note-on
|
|
||||||
char addr[16];
|
|
||||||
// note frequency
|
|
||||||
for (int i = 0; i < i; i++) {
|
|
||||||
Bit32u outOff = PERCUSSION_OFFSETS[pIdx][i];
|
|
||||||
if (0x0 != outOff) {
|
|
||||||
int inAddr = 0xa0 + opl->_GetOffset(1); // any channel is fine, they should have all been written
|
|
||||||
int outAddr = 0xa0 + outOff;
|
|
||||||
_CaptureRegWrite(outAddr, opl->_ReadReg(inAddr));
|
|
||||||
_DebugOut(itoa(opl->_ReadReg(inAddr), addr, 16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_CaptureRegWriteWithDelay(0xbd, OxBD | maskOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::InitCaptureVariables() {
|
|
||||||
captureHandle = NULL;
|
|
||||||
captureLengthBytes = 0;
|
|
||||||
lastWrite = -1;
|
|
||||||
captureStart = -1;
|
|
||||||
channelMap.clear();
|
|
||||||
for (int i = 0; i < MELODIC_CHANNELS; i++) {
|
|
||||||
channels[i].opl = NULL;
|
|
||||||
channels[i].ch = -1;
|
|
||||||
}
|
|
||||||
OxBD = 0x20; // percussion mode should always be enabled
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DROMultiplexer::StartCapture(const char* filepath, Hiopl *opl) {
|
|
||||||
captureHandle = fopen(filepath, "wb");
|
|
||||||
if (captureHandle) {
|
|
||||||
DROMultiplexer::master = this;
|
|
||||||
lastWrite = -1;
|
|
||||||
captureLengthBytes = 0;
|
|
||||||
captureStart = Time::currentTimeMillis();
|
|
||||||
fwrite(dro_header, 1, sizeof(dro_header), captureHandle);
|
|
||||||
for (int i = 0; i <= 0xff; i++) {
|
|
||||||
_CaptureRegWrite(i, 0);
|
|
||||||
}
|
|
||||||
_CaptureOpl3Enable();
|
|
||||||
for (Bit8u i = 0x20; i <= 0x35; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i));
|
|
||||||
}
|
|
||||||
for (Bit8u i = 0x40; i <= 0x55; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i));
|
|
||||||
}
|
|
||||||
for (Bit8u i = 0x60; i <= 0x75; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i));
|
|
||||||
}
|
|
||||||
for (Bit8u i = 0x80; i <= 0x95; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i));
|
|
||||||
}
|
|
||||||
_CaptureRegWrite(0xbd, OxBD | (opl->_ReadReg(0xbd) & 0xc0)); // enable percmode, copy tremolo and vibrato depth only
|
|
||||||
for (Bit8u i = 0xc0; i <= 0xc8; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i) | 0x30); // enable L + R channels
|
|
||||||
}
|
|
||||||
for (Bit8u i = 0xe0; i <= 0xf5; i++) {
|
|
||||||
_CaptureRegWrite(i, opl->_ReadReg(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (NULL != captureHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::StopCapture() {
|
|
||||||
if (NULL != captureHandle) {
|
|
||||||
Bit16u finalDelay = (Bit16u)(Time::currentTimeMillis() - lastWrite);
|
|
||||||
_CaptureDelay(finalDelay);
|
|
||||||
Bit32u lengthMilliseconds = (Bit32u)(finalDelay + Time::currentTimeMillis() - captureStart);
|
|
||||||
host_writed(&dro_header[0x0c], lengthMilliseconds);
|
|
||||||
host_writed(&dro_header[0x10], captureLengthBytes);
|
|
||||||
//if (opl.raw.opl3 && opl.raw.dualopl2) host_writed(&dro_header[0x14],0x1);
|
|
||||||
//else if (opl.raw.dualopl2) host_writed(&dro_header[0x14],0x2);
|
|
||||||
//else host_writed(&dro_header[0x14],0x0);
|
|
||||||
host_writed(&dro_header[0x14], 0x1); // OPL3
|
|
||||||
fseek(captureHandle, 0, 0);
|
|
||||||
fwrite(dro_header, 1, sizeof(dro_header), captureHandle);
|
|
||||||
fclose(captureHandle);
|
|
||||||
}
|
|
||||||
InitCaptureVariables();
|
|
||||||
DROMultiplexer::master = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CaptureDelay(Bit16u delayMs) {
|
|
||||||
Bit8u delay[3];
|
|
||||||
delay[0] = 0x01;
|
|
||||||
delay[1] = delayMs & 0xff;
|
|
||||||
delay[2] = (delayMs >> 8) & 0xff;
|
|
||||||
fwrite(delay, 1, 3, captureHandle);
|
|
||||||
captureLengthBytes += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CaptureRegWrite(Bit32u reg, Bit8u value) {
|
|
||||||
if (reg <= 0x4) {
|
|
||||||
Bit8u escape = 0x4;
|
|
||||||
fwrite(&escape, 1, 1, captureHandle);
|
|
||||||
captureLengthBytes += 1;
|
|
||||||
}
|
|
||||||
Bit8u regAndVal[2];
|
|
||||||
regAndVal[0] = (Bit8u)reg;
|
|
||||||
regAndVal[1] = value;
|
|
||||||
fwrite(regAndVal, 1, 2, captureHandle);
|
|
||||||
captureLengthBytes += 2;
|
|
||||||
if (0xbd == reg) {
|
|
||||||
OxBD = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CaptureRegWriteWithDelay(Bit32u reg, Bit8u value) {
|
|
||||||
if (NULL != captureHandle) {
|
|
||||||
Bit64s t = Time::currentTimeMillis();
|
|
||||||
if (lastWrite >= 0) {
|
|
||||||
// Delays of over 65 seconds will be truncated, but that kind of delay is a bit silly anyway..
|
|
||||||
_CaptureDelay((Bit16u)(t - lastWrite));
|
|
||||||
}
|
|
||||||
_CaptureRegWrite(reg, value);
|
|
||||||
lastWrite = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DROMultiplexer::_CaptureOpl3Enable() {
|
|
||||||
fwrite(dro_opl3_enable, 1, 4, captureHandle);
|
|
||||||
captureLengthBytes += 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DROMultiplexer::IsAnInstanceRecording() {
|
|
||||||
return NULL != DROMultiplexer::master;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DROMultiplexer::IsAnotherInstanceRecording() {
|
|
||||||
return this->IsAnInstanceRecording() && this != DROMultiplexer::master;
|
|
||||||
}
|
|
|
@ -1,58 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include <map>
|
|
||||||
#include "hiopl.h"
|
|
||||||
#include "../JuceLibraryCode/JuceHeader.h"
|
|
||||||
|
|
||||||
class DROMultiplexer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static const int MELODIC_CHANNELS = 15;
|
|
||||||
|
|
||||||
DROMultiplexer();
|
|
||||||
~DROMultiplexer();
|
|
||||||
|
|
||||||
void TwoOpMelodicNoteOn(Hiopl* opl, int ch);
|
|
||||||
void TwoOpMelodicNoteOff(Hiopl* opl, int ch);
|
|
||||||
void PercussionChange(Hiopl* opl, int perc);
|
|
||||||
|
|
||||||
void InitCaptureVariables();
|
|
||||||
bool IsAnInstanceRecording();
|
|
||||||
bool IsAnotherInstanceRecording();
|
|
||||||
bool StartCapture(const char* filepath, Hiopl* opl);
|
|
||||||
void StopCapture();
|
|
||||||
static DROMultiplexer* GetMaster();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _CaptureDelay(Bit16u delayMs);
|
|
||||||
void _CaptureRegWriteWithDelay(Bit32u reg, Bit8u value);
|
|
||||||
void _CaptureRegWrite(Bit32u reg, Bit8u value);
|
|
||||||
void _CaptureOpl3Enable();
|
|
||||||
int _FindFreeChannel(Hiopl* opl, int inCh);
|
|
||||||
void _CopyOplChannelSettings(Hiopl* opl, int inCh, int outCh);
|
|
||||||
void _CopyOplPercussionSettings(Hiopl* opl, int pIdx);
|
|
||||||
void _DebugOut(const char* str);
|
|
||||||
static DROMultiplexer* master;
|
|
||||||
Bit8u OxBD; // cached value of percussion register
|
|
||||||
|
|
||||||
FILE* captureHandle;
|
|
||||||
Bit64s captureStart;
|
|
||||||
Bit64s lastWrite;
|
|
||||||
Bit32u captureLengthBytes;
|
|
||||||
static CriticalSection lock;
|
|
||||||
|
|
||||||
typedef struct oplch {
|
|
||||||
Hiopl* opl;
|
|
||||||
int ch;
|
|
||||||
bool operator<(const oplch &o) const {
|
|
||||||
return opl < o.opl ||
|
|
||||||
(opl == o.opl && ch < o.ch);
|
|
||||||
};
|
|
||||||
bool operator==(const oplch &o) const {
|
|
||||||
return opl == o.opl && ch == o.ch;
|
|
||||||
};
|
|
||||||
} OplCh_t;
|
|
||||||
|
|
||||||
OplCh_t channels[MELODIC_CHANNELS];
|
|
||||||
std::map<OplCh_t, int> channelMap;
|
|
||||||
};
|
|
||||||
|
|
|
@ -16,9 +16,9 @@ float FloatParameter::getParameter(void)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FloatParameter::setParameter(float value)
|
void FloatParameter::setParameter(float _value)
|
||||||
{
|
{
|
||||||
this->value = value;
|
this->value = _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
String FloatParameter::getName(void)
|
String FloatParameter::getName(void)
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include "../JuceLibraryCode/JuceHeader.h"
|
#include "../JuceLibraryCode/JuceHeader.h"
|
||||||
#include "hiopl.h"
|
#include "hiopl.h"
|
||||||
#include "DROMultiplexer.h"
|
|
||||||
#include "FloatParameter.h"
|
#include "FloatParameter.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ Hiopl::Hiopl(Emulator emulator) {
|
||||||
//InitCaptureVariables();
|
//InitCaptureVariables();
|
||||||
|
|
||||||
adlib = new DBOPL::Handler();
|
adlib = new DBOPL::Handler();
|
||||||
//zdoom = JavaOPLCreate(false);
|
|
||||||
|
|
||||||
// channels reordered to match
|
// channels reordered to match
|
||||||
// 'in-memory' order in DOSBox emulator
|
// 'in-memory' order in DOSBox emulator
|
||||||
|
@ -67,10 +66,6 @@ void Hiopl::Generate(int length, float* buffer) {
|
||||||
const float z = y < -1.0f ? -1.0f : y;
|
const float z = y < -1.0f ? -1.0f : y;
|
||||||
buffer[i] = z > 1.0f ? 1.0f : z;
|
buffer[i] = z > 1.0f ? 1.0f : z;
|
||||||
}
|
}
|
||||||
//} else if (ZDOOM == emulator) {
|
|
||||||
// ZDoom hacked to write mono samples
|
|
||||||
// zdoom->Update(buffer, length);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hiopl::SetSampleRate(int hz) {
|
void Hiopl::SetSampleRate(int hz) {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include "adlib.h"
|
#include "adlib.h"
|
||||||
#include "dbopl.h"
|
#include "dbopl.h"
|
||||||
#include "zdopl.h"
|
|
||||||
// Integer buffer used by DOSBox OPL emulator, later converted to floating point.
|
// Integer buffer used by DOSBox OPL emulator, later converted to floating point.
|
||||||
|
|
||||||
// Number of 32-bit samples to use. ~1 MB per buffer. Probably excessive, but should be safe.
|
// Number of 32-bit samples to use. ~1 MB per buffer. Probably excessive, but should be safe.
|
||||||
|
@ -89,7 +88,6 @@ class Hiopl {
|
||||||
private:
|
private:
|
||||||
Emulator emulator;
|
Emulator emulator;
|
||||||
DBOPL::Handler *adlib;
|
DBOPL::Handler *adlib;
|
||||||
OPLEmul *zdoom;
|
|
||||||
Bit8u regCache[OPL_N_REG];
|
Bit8u regCache[OPL_N_REG];
|
||||||
int intermediateBufIdx;
|
int intermediateBufIdx;
|
||||||
Bit32s intermediateBuf[INTERMEDIATE_BUF_N][INTERMEDIATE_BUF_SAMPLES];
|
Bit32s intermediateBuf[INTERMEDIATE_BUF_N][INTERMEDIATE_BUF_SAMPLES];
|
||||||
|
|
1895
Source/zdopl.cpp
1895
Source/zdopl.cpp
File diff suppressed because it is too large
Load diff
|
@ -1,24 +0,0 @@
|
||||||
#ifndef OPL_H
|
|
||||||
#define OPL_H
|
|
||||||
|
|
||||||
// Abstract base class for OPL emulators
|
|
||||||
|
|
||||||
class OPLEmul
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
OPLEmul() {}
|
|
||||||
virtual ~OPLEmul() {}
|
|
||||||
|
|
||||||
virtual void Reset() = 0;
|
|
||||||
virtual void WriteReg(int reg, int v) = 0;
|
|
||||||
virtual void Update(float *buffer, int length) = 0;
|
|
||||||
virtual void SetPanning(int c, float left, float right) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
OPLEmul *JavaOPLCreate(bool stereo);
|
|
||||||
|
|
||||||
#define OPL_SAMPLE_RATE 49716.0
|
|
||||||
#define CENTER_PANNING_POWER 0.70710678118 /* [RH] volume at center for EQP */
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue