Skip to content

Commit

Permalink
add raw YM2151
Browse files Browse the repository at this point in the history
  • Loading branch information
jpcima committed Mar 28, 2019
1 parent a609f4c commit 3f2e5c1
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ set(FILEFORMATS_SOURCES
"src/FileFormats/format_mucom88_dat.cpp"
"src/FileFormats/format_vgi.cpp"
"src/FileFormats/format_wohlstand_opn2.cpp"
"src/FileFormats/ym2612_to_wopi.cpp")
"src/FileFormats/ym2612_to_wopi.cpp"
"src/FileFormats/ym2151_to_wopi.cpp")
add_library(FileFormats STATIC ${FILEFORMATS_SOURCES})
target_include_directories(FileFormats PUBLIC "src")
target_link_libraries(FileFormats PUBLIC Common)
Expand Down
2 changes: 2 additions & 0 deletions FMBankEdit.pro
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ SOURCES += \
src/FileFormats/format_vgi.cpp \
src/FileFormats/format_wohlstand_opn2.cpp \
src/FileFormats/ym2612_to_wopi.cpp \
src/FileFormats/ym2151_to_wopi.cpp \
src/formats_sup.cpp \
src/importer.cpp \
src/latency.cpp \
Expand Down Expand Up @@ -157,6 +158,7 @@ HEADERS += \
src/FileFormats/format_vgi.h \
src/FileFormats/format_wohlstand_opn2.h \
src/FileFormats/ym2612_to_wopi.h \
src/FileFormats/ym2151_to_wopi.h \
src/formats_sup.h \
src/importer.h \
src/latency.h \
Expand Down
10 changes: 10 additions & 0 deletions src/FileFormats/format_vgm_import.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "format_vgm_import.h"
#include "ym2612_to_wopi.h"
#include "ym2151_to_wopi.h"
#include "../common.h"

#include <QSet>
Expand All @@ -35,7 +36,9 @@ FfmtErrCode VGM_Importer::loadFile(QString filePath, FmBank &bank)
{
RawYm2612ToWopi pseudoChip;
RawYm2612ToWopi pseudoChip2608;
RawYm2151ToWopi pseudoChip2151;
pseudoChip2608.shareInstruments(pseudoChip);
pseudoChip2151.shareInstruments(pseudoChip);

char magic[4];
uint8_t numb[4];
Expand Down Expand Up @@ -82,6 +85,12 @@ FfmtErrCode VGM_Importer::loadFile(QString filePath, FmBank &bank)
pseudoChip.passReg(1, reg, val);
break;

case 0x54://Write YM2151 port
file.read(char_p(&reg), 1);
file.read(char_p(&val), 1);
pseudoChip2151.passReg(reg, val);
break;

case 0x56://Write YM2608 port 0
file.read(char_p(&reg), 1);
file.read(char_p(&val), 1);
Expand Down Expand Up @@ -116,6 +125,7 @@ FfmtErrCode VGM_Importer::loadFile(QString filePath, FmBank &bank)
file.seek(file.pos() + 2);
pseudoChip.doAnalyzeState();
pseudoChip2608.doAnalyzeState();
pseudoChip2151.doAnalyzeState();
break;

case 0x66://End of sound data
Expand Down
144 changes: 144 additions & 0 deletions src/FileFormats/ym2151_to_wopi.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/*
* OPN2 Bank Editor by Wohlstand, a free tool for music bank editing
* Copyright (c) 2017-2019 Vitaly Novichkov <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include "ym2151_to_wopi.h"
#include <cstring>

RawYm2151ToWopi::RawYm2151ToWopi()
{
m_insdata.reset(new InstrumentData);
reset();
}

void RawYm2151ToWopi::reset()
{
InstrumentData &insdata = *m_insdata;
insdata.cache.clear();
insdata.caughtInstruments.clear();

std::memset(m_keys, 0, sizeof(m_keys));
std::memset(m_ymram, 0, sizeof(m_ymram));
}

void RawYm2151ToWopi::passReg(uint8_t reg, uint8_t val)
{
if(reg == 0x08)
m_keys[val & 3] = (val >> 3) & 15;

m_ymram[reg] = val;
}

void RawYm2151ToWopi::doAnalyzeState()
{
InstrumentData &insdata = *m_insdata;

/* Analyze dumps and take the instruments */
for(uint8_t ch = 0; ch < 8; ch++)
{
if(m_keys[ch] == 0)
continue;//Skip if key is not pressed

QByteArray insRaw;//Raw instrument
FmBank::Instrument ins = FmBank::emptyInst();
for(uint8_t op = 0; op < 4; op++)
{
ins.setRegDUMUL(op, m_ymram[0x40 + (op * 8) + ch]);
ins.setRegLevel(op, m_ymram[0x60 + (op * 8) + ch]);
ins.setRegRSAt(op, m_ymram[0x80 + (op * 8) + ch]);
ins.setRegAMD1(op, m_ymram[0xa0 + (op * 8) + ch]);
ins.setRegD2(op, m_ymram[0xc0 + (op * 8) + ch]);
ins.setRegSysRel(op,m_ymram[0xe0 + (op * 8) + ch]);
insRaw.push_back((char)ins.getRegDUMUL(op));
insRaw.push_back((char)ins.getRegLevel(op));
insRaw.push_back((char)ins.getRegRSAt(op));
insRaw.push_back((char)ins.getRegAMD1(op));
insRaw.push_back((char)ins.getRegD2(op));
insRaw.push_back((char)ins.getRegSysRel(op));
insRaw.push_back((char)ins.getRegSsgEg(op));
}

ins.am = m_ymram[0x38] & 3;
ins.fm = (m_ymram[0x38] >> 4) & 7;
ins.algorithm = m_ymram[0x20] & 7;
ins.feedback = (m_ymram[0x20] >> 3) & 7;
insRaw.push_back((char)ins.getRegLfoSens());
insRaw.push_back((char)ins.getRegFbAlg());

/* Maximize key volume */
uint8_t olevels[4] =
{
ins.OP[OPERATOR1].level,
ins.OP[OPERATOR2].level,
ins.OP[OPERATOR3].level,
ins.OP[OPERATOR4].level
};

uint8_t dec = 0;
switch(ins.algorithm)
{
case 0:case 1: case 2: case 3:
ins.OP[OPERATOR4].level = 0;
break;
case 4:
dec = std::min({olevels[OPERATOR3], olevels[OPERATOR4]});
ins.OP[OPERATOR3].level = olevels[OPERATOR3] - dec;
ins.OP[OPERATOR4].level = olevels[OPERATOR4] - dec;
break;
case 5:
dec = std::min({olevels[OPERATOR2], olevels[OPERATOR3], olevels[OPERATOR4]});
ins.OP[OPERATOR2].level = olevels[OPERATOR2] - dec;
ins.OP[OPERATOR3].level = olevels[OPERATOR3] - dec;
ins.OP[OPERATOR4].level = olevels[OPERATOR4] - dec;
break;
case 6:
dec = std::min({olevels[OPERATOR2], olevels[OPERATOR3], olevels[OPERATOR4]});
ins.OP[OPERATOR2].level = olevels[OPERATOR2] - dec;
ins.OP[OPERATOR3].level = olevels[OPERATOR3] - dec;
ins.OP[OPERATOR4].level = olevels[OPERATOR4] - dec;
break;
case 7:
dec = std::min({olevels[OPERATOR1], olevels[OPERATOR2], olevels[OPERATOR3], olevels[OPERATOR4]});
ins.OP[OPERATOR1].level = olevels[OPERATOR1] - dec;
ins.OP[OPERATOR2].level = olevels[OPERATOR2] - dec;
ins.OP[OPERATOR3].level = olevels[OPERATOR3] - dec;
ins.OP[OPERATOR4].level = olevels[OPERATOR4] - dec;
break;
}

//Encode volume bytes back
insRaw[1 + OPERATOR1*7] = (char)ins.getRegLevel(OPERATOR1);
insRaw[1 + OPERATOR2*7] = (char)ins.getRegLevel(OPERATOR2);
insRaw[1 + OPERATOR3*7] = (char)ins.getRegLevel(OPERATOR3);
insRaw[1 + OPERATOR4*7] = (char)ins.getRegLevel(OPERATOR4);

if(!insdata.cache.contains(insRaw))
{
std::snprintf(ins.name, 32,
"Ins %d, channel %d",
insdata.caughtInstruments.size(),
(int)ch);
insdata.caughtInstruments.push_back(ins);
insdata.cache.insert(insRaw);
}
}
}

const QList<FmBank::Instrument> &RawYm2151ToWopi::caughtInstruments()
{
return m_insdata->caughtInstruments;
}
46 changes: 46 additions & 0 deletions src/FileFormats/ym2151_to_wopi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* OPN2 Bank Editor by Wohlstand, a free tool for music bank editing
* Copyright (c) 2017-2019 Vitaly Novichkov <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef YM2151_TO_WOPI_H
#define YM2151_TO_WOPI_H

#include <stdint.h>
#include <memory>
#include <QSet>
#include <QList>

#include "../bank.h"
#include "ym2612_to_wopi.h" // instrument sharing

class RawYm2151ToWopi
{
typedef RawYm2612ToWopi::InstrumentData InstrumentData;
uint8_t m_keys[8];
uint8_t m_ymram[0xFF];
std::shared_ptr<InstrumentData> m_insdata;

public:
RawYm2151ToWopi();
void reset();
template <class Ym> void shareInstruments(Ym &other) { m_insdata = other.m_insdata; }
void passReg(uint8_t reg, uint8_t val);
void doAnalyzeState();
const QList<FmBank::Instrument> &caughtInstruments();
};

#endif // YM2151_TO_WOPI_H
2 changes: 2 additions & 0 deletions src/FileFormats/ym2612_to_wopi.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class RawYm2612ToWopi
bool m_dacOn = false;
std::shared_ptr<InstrumentData> m_insdata;

friend class RawYm2151ToWopi; // instrument sharing

public:
RawYm2612ToWopi();
void reset();
Expand Down

0 comments on commit 3f2e5c1

Please sign in to comment.