vgm-conv
Version:
Chip-type and clock converter for VGM.
251 lines (250 loc) • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.convert = exports.getChipConverter = exports.getClockConverter = void 0;
const vgm_parser_1 = require("vgm-parser");
const ym2413_clock_converter_1 = require("./converter/ym2413-clock-converter");
const ay8910_clock_converter_1 = require("./converter/ay8910-clock-converter");
const opn_clock_converter_1 = require("./converter/opn-clock-converter");
const ym2413_to_ym2608_converter_1 = require("./converter/ym2413-to-ym2608-converter");
const ay8910_to_ssg_converter_1 = require("./converter/ay8910-to-ssg-converter");
const ay8910_to_opl_converter_1 = require("./converter/ay8910-to-opl-converter");
const ym2413_to_opl_converter_1 = require("./converter/ym2413-to-opl-converter");
const opl_clock_converter_1 = require("./converter/opl-clock-converter");
const sn76489_clock_converter_1 = require("./converter/sn76489-clock-converter");
const sn76489_to_ay8910_converter_1 = require("./converter/sn76489-to-ay8910-converter");
const sn76489_to_opn_converter_1 = require("./converter/sn76489-to-opn-converter");
const ym2203_to_ym2413_converter_1 = require("./converter/ym2203-to-ym2413-converter");
const ym2608_to_ym2413_converter_1 = require("./converter/ym2608-to-ym2413-converter");
const ym2612_to_ym2413_converter_1 = require("./converter/ym2612-to-ym2413-converter");
const ssg_to_ay8910_converter_1 = require("./converter/ssg-to-ay8910-converter");
const ym2203_to_opl_converter_1 = require("./converter/ym2203-to-opl-converter");
const opm_clock_converter_1 = require("./converter/opm-clock-converter");
const opl2_to_opl_converter_1 = require("./converter/opl2-to-opl-converter");
const opl_to_opl2_converter_1 = require("./converter/opl-to-opl2-converter");
const opl_to_opll_converter_1 = require("./converter/opl-to-opll-converter");
const opn_to_opm_converter_1 = require("./converter/opn-to-opm-converter");
const ay8910_to_opm_coverter_1 = require("./converter/ay8910-to-opm-coverter");
function getClockConverter(from, to, opts) {
if (to.chip === "ym3812" || to.chip === "y8950" || to.chip === "ym3526" || to.chip === "ymf262") {
return new opl_clock_converter_1.OPLClockConverter(from, to, opts);
}
if (to.chip === "ym2413") {
return new ym2413_clock_converter_1.YM2413ClockConverter(from, to.clock, opts);
}
if (to.chip === "ay8910") {
return new ay8910_clock_converter_1.AY8910ClockConverter(from, to.clock, opts);
}
if (to.chip === "ym2203") {
return new opn_clock_converter_1.YM2203ClockConverter(from, to.clock, opts);
}
if (to.chip === "ym2608") {
return new opn_clock_converter_1.YM2608ClockConverter(from, to.clock, opts);
}
if (to.chip === "ym2612") {
return new opn_clock_converter_1.YM2612ClockConverter(from, to.clock, opts);
}
if (to.chip === "sn76489") {
return new sn76489_clock_converter_1.SN76489ClockConverter(from, to.clock, opts);
}
if (to.chip === "ym2151") {
return new opm_clock_converter_1.OPMClockConverter(from, to.clock, opts);
}
return null;
}
exports.getClockConverter = getClockConverter;
function getChipConverter(from, to, opts) {
if (from.chip === "ym2612") {
if (to.chip === "ym2413") {
return new ym2612_to_ym2413_converter_1.YM2612ToYM2413Converter(from, to, opts);
}
if (to.chip === "ym2151") {
return new opn_to_opm_converter_1.YM2612ToOPMConverter(from, to, opts);
}
}
if (from.chip === "ym3812") {
if (to.chip === "y8950" || to.chip === "ym3526") {
return new opl2_to_opl_converter_1.OPL2ToOPLConverter(from, to, opts);
}
if (to.chip === "ym2413") {
return new opl_to_opll_converter_1.OPLToOPLLConverter(from, to, opts);
}
}
if (from.chip === "ym3526") {
if (to.chip === "ym3812" || to.chip === "ymf262") {
return new opl_to_opl2_converter_1.OPLToOPL2Converter(from, to, opts);
}
if (to.chip === "ym2413") {
return new opl_to_opll_converter_1.OPLToOPLLConverter(from, to, opts);
}
}
if (from.chip === "y8950") {
if (to.chip === "ym3812" || to.chip === "ymf262") {
return new opl_to_opl2_converter_1.OPLToOPL2Converter(from, to, opts);
}
if (to.chip === "ym2413") {
return new opl_to_opll_converter_1.OPLToOPLLConverter(from, to, opts);
}
}
if (from.chip === "ym2203") {
if (to.chip === "ym3812" || to.chip === "y8950" || to.chip === "ym3526" || to.chip === "ymf262") {
return new ym2203_to_opl_converter_1.YM2203ToOPLConverter(from, to, opts);
}
if (to.chip === "ym2151") {
return new opn_to_opm_converter_1.YM2203ToOPMConverter(from, to, opts);
}
if (to.chip === "ym2413") {
return new ym2203_to_ym2413_converter_1.YM2203ToYM2413Converter(from, to, opts);
}
if (to.chip === "ay8910") {
return new ssg_to_ay8910_converter_1.YM2203ToAY8910Converter(from, to, opts);
}
}
if (from.chip === "ym2608") {
if (to.chip === "ym2151") {
return new opn_to_opm_converter_1.YM2608ToOPMConverter(from, to, opts);
}
if (to.chip === "ym2413") {
return new ym2608_to_ym2413_converter_1.YM2608ToYM2413Converter(from, to, opts);
}
if (to.chip === "ay8910") {
return new ssg_to_ay8910_converter_1.YM2608ToAY8910Converter(from, to, opts);
}
}
if (from.chip === "ym2413") {
const optsEx = { opllVariant: from.variantName, ...opts };
if (to.chip === "ym2608") {
return new ym2413_to_ym2608_converter_1.YM2413ToYM2608Converter(from, to, optsEx);
}
if (to.chip === "ym3812" || to.chip === "y8950" || to.chip === "ym3526" || to.chip === "ymf262") {
return new ym2413_to_opl_converter_1.YM2413ToOPLConverter(from, to, optsEx);
}
}
if (from.chip === "ay8910") {
if (to.chip == "ym2151") {
return new ay8910_to_opm_coverter_1.AY8910ToOPMConverter(from, to, opts);
}
if (to.chip === "ym2608") {
return new ay8910_to_ssg_converter_1.AY8910ToYM2608Converter(from, to, opts);
}
if (to.chip === "ym2203") {
return new ay8910_to_ssg_converter_1.AY8910ToYM2203Converter(from, to, opts);
}
if (to.chip === "ym3812" || to.chip === "y8950" || to.chip === "ym3526" || to.chip === "ymf262") {
return new ay8910_to_opl_converter_1.AY8910ToOPLConverter(from, to, opts);
}
}
if (from.chip === "sn76489") {
if (to.chip === "ay8910") {
return new sn76489_to_ay8910_converter_1.SN76489ToAY8910Converter(from, to, opts);
}
if (to.chip === "ym2203" || to.chip === "ym2608" || to.chip === "ym2612") {
return new sn76489_to_opn_converter_1.SN76489ToOPNConverter(from, to, opts);
}
}
return null;
}
exports.getChipConverter = getChipConverter;
function convert(input, converter) {
let index = 0;
const data = new Uint8Array(input.data);
const ds = new vgm_parser_1.VGMDataStream();
for (const e of converter.getInitialCommands()) {
ds.push(e);
}
while (true) {
if (input.offsets.data + index === input.offsets.loop) {
ds.markLoopPoint();
for (const e of converter.getLoopCommands()) {
ds.push(e);
}
}
const cmd = (0, vgm_parser_1.parseVGMCommand)(data, index);
if (cmd == null) {
break;
}
for (const e of converter.convert(cmd)) {
ds.push(e);
}
index += cmd.size;
if (cmd instanceof vgm_parser_1.VGMEndCommand) {
break;
}
if (data.length <= index) {
// convert dummy VGMEndCommand
for (const e of converter.convert(new vgm_parser_1.VGMEndCommand())) {
ds.push(e);
}
break;
}
}
const res = input.clone();
res.setDataStream(ds);
return res;
}
exports.convert = convert;
function convertVGM(input, from, to, opts) {
if (input.chips[from.chip] === null) {
throw new Error(`Cannot find the chip ${from.chip}`);
}
let vgm = input.clone();
vgm.setVersionCode(0x171);
let cur = from;
if (cur.chip != to.chip) {
const chipConverter = getChipConverter(cur, to, opts);
if (chipConverter) {
vgm = convert(vgm, chipConverter);
cur = chipConverter.convertedChipInfo;
const { clock } = chipConverter.convertedChipInfo;
if (to.clock != clock) {
const tmp = { ...cur, clock: (cur.clock * to.clock) / clock };
const clockConverter = getClockConverter(cur, tmp, opts);
if (clockConverter) {
vgm = convert(vgm, clockConverter);
cur = clockConverter.convertedChipInfo;
}
else {
throw new Error(`Clock converter for ${to.chip} is not implemented.`);
}
}
}
else {
throw new Error(`Converter from ${cur.chip} to ${to.chip} is not implemented.`);
}
}
else {
// clock conversion only
if (0 < to.clock && cur.clock != to.clock) {
const clockConverter = getClockConverter(cur, to, opts);
if (clockConverter) {
vgm = convert(vgm, clockConverter);
cur = clockConverter.convertedChipInfo;
}
else {
throw new Error(`Clock converter for ${to.chip} is not implemented.`);
}
}
}
const chips = vgm.chips;
if (from.subModule == null) {
delete chips[from.chip];
}
if (chips[cur.chip] == null) {
chips[cur.chip] = {};
}
chips[to.chip].clock = cur.clock;
let variantName = null;
if (from.chip == "ym2413") {
const opllVariant = opts.opllVariant ?? from.variantName;
if (opllVariant != "ym2413" && opllVariant != null) {
variantName = opllVariant;
}
}
let fromName = from.chip.toUpperCase();
if (variantName != null) {
fromName += `(as ${variantName.toUpperCase()})`;
}
const toName = cur.chip.toUpperCase();
console.error(`${fromName}{from.clock}Hz => ${toName}{cur.clock}Hz`);
return vgm;
}
exports.default = convertVGM;