More channel assignment improvements but DRO output still seems to lose notes.
This commit is contained in:
parent
454fbdfde5
commit
13f671265b
8 changed files with 61 additions and 48 deletions
|
@ -74,10 +74,7 @@ INLINE void host_writed(Bit8u *off, Bit32u val) {
|
||||||
HANDLE conout;
|
HANDLE conout;
|
||||||
DROMultiplexer::DROMultiplexer()
|
DROMultiplexer::DROMultiplexer()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MELODIC_CHANNELS; i++) {
|
InitCaptureVariables();
|
||||||
channels[i].opl = NULL;
|
|
||||||
channels[i].ch = -1;
|
|
||||||
}
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
AllocConsole();
|
AllocConsole();
|
||||||
conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
conout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
@ -98,19 +95,16 @@ DROMultiplexer* DROMultiplexer::GetMaster() {
|
||||||
void DROMultiplexer::TwoOpMelodicNoteOn(Hiopl* opl, int inCh) {
|
void DROMultiplexer::TwoOpMelodicNoteOn(Hiopl* opl, int inCh) {
|
||||||
const ScopedLock sl(lock);
|
const ScopedLock sl(lock);
|
||||||
|
|
||||||
for (int i = 1; i <= Hiopl::CHANNELS; i++) {
|
|
||||||
char s[2];
|
|
||||||
s[0] = opl->GetState(i);
|
|
||||||
s[1] = '\0';
|
|
||||||
_DebugOut(s);
|
|
||||||
}
|
|
||||||
_DebugOut(" ");
|
|
||||||
|
|
||||||
// find a free channel and mark it as used
|
// find a free channel and mark it as used
|
||||||
char addr[16];
|
char addr[16];
|
||||||
int outCh = _FindFreeChannel(opl, inCh);
|
int outCh = _FindFreeChannel(opl, inCh);
|
||||||
_DebugOut(" <- ");
|
_DebugOut(" <- ");
|
||||||
_DebugOut(itoa((int)opl, addr, 16));
|
_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");
|
_DebugOut("\n");
|
||||||
|
|
||||||
// read all instrument settings and write them all to the file
|
// read all instrument settings and write them all to the file
|
||||||
|
@ -160,13 +154,16 @@ void DROMultiplexer::TwoOpMelodicNoteOff(Hiopl* opl, int ch) {
|
||||||
key.ch = ch;
|
key.ch = ch;
|
||||||
|
|
||||||
int outCh = channelMap[key];
|
int outCh = channelMap[key];
|
||||||
|
char n[8];
|
||||||
|
_DebugOut(itoa(outCh, n, 16));
|
||||||
|
_DebugOut(" note off\n");
|
||||||
// note-off
|
// note-off
|
||||||
Bit32u inAddr = 0xb0 + chOff;
|
Bit32u inAddr = 0xb0 + chOff;
|
||||||
Bit32u outAddr = 0xb0 + CHANNEL_OFFSETS[outCh];
|
Bit32u outAddr = 0xb0 + CHANNEL_OFFSETS[outCh];
|
||||||
_CaptureRegWriteWithDelay(outAddr, opl->_ReadReg(inAddr));
|
_CaptureRegWriteWithDelay(outAddr, opl->_ReadReg(inAddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DROMultiplexer::_DebugOut(char* str) {
|
void DROMultiplexer::_DebugOut(const char* str) {
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
DWORD count;
|
DWORD count;
|
||||||
count = strlen(str);
|
count = strlen(str);
|
||||||
|
@ -182,7 +179,7 @@ int DROMultiplexer::_FindFreeChannel(Hiopl* opl, int inCh) {
|
||||||
channels[i].ch = inCh;
|
channels[i].ch = inCh;
|
||||||
channelMap[channels[i]] = i;
|
channelMap[channels[i]] = i;
|
||||||
char n[8];
|
char n[8];
|
||||||
_DebugOut(itoa(i, n, 10));
|
_DebugOut(itoa(i, n, 16));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -201,7 +198,11 @@ void DROMultiplexer::InitCaptureVariables() {
|
||||||
captureLengthBytes = 0;
|
captureLengthBytes = 0;
|
||||||
lastWrite = -1;
|
lastWrite = -1;
|
||||||
captureStart = -1;
|
captureStart = -1;
|
||||||
// channelMap.clear();
|
channelMap.clear();
|
||||||
|
for (int i = 0; i < MELODIC_CHANNELS; i++) {
|
||||||
|
channels[i].opl = NULL;
|
||||||
|
channels[i].ch = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DROMultiplexer::StartCapture(const char* filepath, Hiopl *opl) {
|
bool DROMultiplexer::StartCapture(const char* filepath, Hiopl *opl) {
|
||||||
|
|
|
@ -28,7 +28,7 @@ private:
|
||||||
void _CaptureRegWrite(Bit32u reg, Bit8u value);
|
void _CaptureRegWrite(Bit32u reg, Bit8u value);
|
||||||
void _CaptureOpl3Enable();
|
void _CaptureOpl3Enable();
|
||||||
int _FindFreeChannel(Hiopl* opl, int inCh);
|
int _FindFreeChannel(Hiopl* opl, int inCh);
|
||||||
void _DebugOut(char* str);
|
void _DebugOut(const char* str);
|
||||||
static DROMultiplexer* master;
|
static DROMultiplexer* master;
|
||||||
|
|
||||||
FILE* captureHandle;
|
FILE* captureHandle;
|
||||||
|
|
|
@ -1017,18 +1017,13 @@ PluginGui::PluginGui (JuceOplvstiAudioProcessor* ownerFilter)
|
||||||
keyscaleEnvButton2->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
|
keyscaleEnvButton2->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
|
||||||
sustainButton2->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
|
sustainButton2->setColour(TextButton::buttonColourId, Colour(COLOUR_MID));
|
||||||
|
|
||||||
|
Font fw(Font::getDefaultMonospacedFontName(), 14, Font::bold);
|
||||||
for (unsigned int i = 0; i < channels.size(); ++i)
|
for (unsigned int i = 0; i < channels.size(); ++i)
|
||||||
{
|
{
|
||||||
ImageButton *channel = new ImageButton("new button");
|
Label *channel = new Label("chan label", TRANS("-"));
|
||||||
|
channel->setColour(Label::textColourId, Colour(COLOUR_MID));
|
||||||
|
channel->setJustificationType(Justification::centred);
|
||||||
addAndMakeVisible(channel);
|
addAndMakeVisible(channel);
|
||||||
channel->addListener(this);
|
|
||||||
|
|
||||||
channel->setImages(false, true, true,
|
|
||||||
ImageCache::getFromMemory(channeloff_png, channeloff_pngSize), 1.000f, Colour(0x00000000),
|
|
||||||
Image(), 1.000f, Colour(0x00000000),
|
|
||||||
ImageCache::getFromMemory(channelon_png, channelon_pngSize), 1.000f, Colour(0x00000000));
|
|
||||||
|
|
||||||
channels[i] = channel;
|
channels[i] = channel;
|
||||||
}
|
}
|
||||||
//[/UserPreSize]
|
//[/UserPreSize]
|
||||||
|
@ -1238,7 +1233,7 @@ void PluginGui::resized()
|
||||||
percussionLabel->setBounds (40, 488, 163, 24);
|
percussionLabel->setBounds (40, 488, 163, 24);
|
||||||
//[UserResized] Add your own custom resize handling here..
|
//[UserResized] Add your own custom resize handling here..
|
||||||
for (unsigned int i = 0; i < channels.size(); ++i)
|
for (unsigned int i = 0; i < channels.size(); ++i)
|
||||||
channels[i]->setBounds(456+44*i+4, 36, 16, 16);
|
channels[i]->setBounds(456+44*i+4, 36, 20, 20);
|
||||||
//[/UserResized]
|
//[/UserResized]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1623,8 +1618,10 @@ void PluginGui::buttonClicked (Button* buttonThatWasClicked)
|
||||||
|
|
||||||
void PluginGui::timerCallback()
|
void PluginGui::timerCallback()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < Hiopl::CHANNELS; ++i)
|
for (int i = 0; i < Hiopl::CHANNELS; ++i) {
|
||||||
channels[i]->setState(processor->isChannelActive(i+1) ? Button::buttonDown : Button::buttonNormal);
|
channels[i]->setText(processor->getChannelEnvelopeStage(i + 1), NotificationType::dontSendNotification);
|
||||||
|
}
|
||||||
|
//channels[i]->setState(processor->isChannelActive(i+1) ? Button::buttonDown : Button::buttonNormal);
|
||||||
}
|
}
|
||||||
//[/MiscUserCode]
|
//[/MiscUserCode]
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ private:
|
||||||
static const uint32 COLOUR_MID = 0xff007f00;
|
static const uint32 COLOUR_MID = 0xff007f00;
|
||||||
static const uint32 COLOUR_RECORDING = 0xffff0000;
|
static const uint32 COLOUR_RECORDING = 0xffff0000;
|
||||||
JuceOplvstiAudioProcessor* processor;
|
JuceOplvstiAudioProcessor* processor;
|
||||||
std::array<ScopedPointer<ImageButton>, Hiopl::CHANNELS> channels;
|
std::array<ScopedPointer<Label>, Hiopl::CHANNELS> channels;
|
||||||
TooltipWindow tooltipWindow;
|
TooltipWindow tooltipWindow;
|
||||||
//[/UserVariables]
|
//[/UserVariables]
|
||||||
|
|
||||||
|
|
|
@ -909,6 +909,13 @@ int JuceOplvstiAudioProcessor::isChannelActive(int idx) const
|
||||||
return active_notes[idx] != NO_NOTE;
|
return active_notes[idx] != NO_NOTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @param idx 1-based channel index
|
||||||
|
const char* JuceOplvstiAudioProcessor::getChannelEnvelopeStage(int idx) const
|
||||||
|
{
|
||||||
|
return Opl->GetState(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// This creates new instances of the plugin..
|
// This creates new instances of the plugin..
|
||||||
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
void setParametersByRegister(int register_base, int op, uint8 value);
|
void setParametersByRegister(int register_base, int op, uint8 value);
|
||||||
|
|
||||||
int isChannelActive(int idx) const;
|
int isChannelActive(int idx) const;
|
||||||
|
const char* getChannelEnvelopeStage(int idx) const;
|
||||||
|
|
||||||
void updateGuiIfPresent();
|
void updateGuiIfPresent();
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@ Hiopl::Hiopl(int buflen, Emulator emulator) {
|
||||||
adlib = new DBOPL::Handler();
|
adlib = new DBOPL::Handler();
|
||||||
zdoom = JavaOPLCreate(false);
|
zdoom = JavaOPLCreate(false);
|
||||||
|
|
||||||
|
// channels reordered to match
|
||||||
|
// 'in-memory' order in DOSBox emulator
|
||||||
_op1offset[1] = 0x0;
|
_op1offset[1] = 0x0;
|
||||||
_op1offset[2] = 0x1;
|
_op1offset[2] = 0x1;
|
||||||
_op1offset[3] = 0x2;
|
_op1offset[3] = 0x2;
|
||||||
|
@ -190,14 +192,14 @@ void Hiopl::KeyOff(int ch) {
|
||||||
_ClearRegBits(0xb0+offset, 0x20);
|
_ClearRegBits(0xb0+offset, 0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char STATE[] = {
|
static const char* STATE[] = {
|
||||||
'-',
|
"-",
|
||||||
'R',
|
"R",
|
||||||
'S',
|
"S",
|
||||||
'D',
|
"D",
|
||||||
'A',
|
"A",
|
||||||
};
|
};
|
||||||
char Hiopl::GetState(int ch) {
|
const char* Hiopl::GetState(int ch) const {
|
||||||
return STATE[adlib->chip.chan[ch - 1].op[1].state];
|
return STATE[adlib->chip.chan[ch - 1].op[1].state];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,18 +272,22 @@ int Hiopl::_GetOffset(int ch, int osc) {
|
||||||
return (1 == osc) ? _op1offset[ch] : _op2offset[ch];
|
return (1 == osc) ? _op1offset[ch] : _op2offset[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// re-ordered to match in-memory ordering of DOSBox emulator
|
||||||
|
static int OFFSET_MAP[] = {
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
3,//1,
|
||||||
|
1,//2,
|
||||||
|
4,//3,
|
||||||
|
2,//4,
|
||||||
|
5,
|
||||||
|
6,
|
||||||
|
7,
|
||||||
|
8,
|
||||||
|
9,
|
||||||
|
};
|
||||||
int Hiopl::_GetOffset(int ch) {
|
int Hiopl::_GetOffset(int ch) {
|
||||||
assert(_CheckParams(ch));
|
assert(_CheckParams(ch));
|
||||||
return ch - 1;
|
return OFFSET_MAP[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
2. Two-operator Melodic and Percussion Mode
|
|
||||||
|
|
||||||
ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
|
|
||||||
³ Channel ³ 0 1 2 3 4 5 BD SD TT CY HH 9 10 11 12 13 14 15 16 17 ³
|
|
||||||
ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´
|
|
||||||
³ Operator 1 ³ 0 1 2 6 7 8 12 16 14 17 13 18 19 20 24 25 26 30 31 32 ³
|
|
||||||
³ Operator 2 ³ 3 4 5 9 10 11 15 21 22 23 27 28 29 33 34 35 ³
|
|
||||||
ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
|
|
||||||
*/
|
|
||||||
|
|
|
@ -68,7 +68,8 @@ class Hiopl {
|
||||||
void KeyOff(int ch);
|
void KeyOff(int ch);
|
||||||
// Return false if no note is active on the channel (ie release is complete)
|
// Return false if no note is active on the channel (ie release is complete)
|
||||||
bool IsActive(int ch);
|
bool IsActive(int ch);
|
||||||
char GetState(int ch);
|
// Return a single character string representing the stage of the envelope for the carrier operator for the channel
|
||||||
|
const char* GetState(int ch) const;
|
||||||
void SetFrequency(int ch, float frqHz, bool keyOn=false);
|
void SetFrequency(int ch, float frqHz, bool keyOn=false);
|
||||||
void _WriteReg(Bit32u reg, Bit8u value, Bit8u mask=0x0);
|
void _WriteReg(Bit32u reg, Bit8u value, Bit8u mask=0x0);
|
||||||
void _ClearRegBits(Bit32u reg, Bit8u mask);
|
void _ClearRegBits(Bit32u reg, Bit8u mask);
|
||||||
|
|
Loading…
Reference in a new issue