2022-02-15 03:12:20 +00:00
|
|
|
/**
|
|
|
|
* Furnace Tracker - multi-system chiptune tracker
|
2024-01-17 02:26:57 +00:00
|
|
|
* Copyright (C) 2021-2024 tildearrow and contributors
|
2022-02-15 03:12:20 +00:00
|
|
|
*
|
|
|
|
* 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 2 of the License, or
|
|
|
|
* (at your option) 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, write to the Free Software Foundation, Inc.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*/
|
|
|
|
|
2021-05-15 21:42:48 +00:00
|
|
|
#ifndef _INSTRUMENT_H
|
|
|
|
#define _INSTRUMENT_H
|
2022-01-19 08:28:29 +00:00
|
|
|
#include "safeWriter.h"
|
2022-01-22 05:14:48 +00:00
|
|
|
#include "dataErrors.h"
|
2021-05-12 22:19:18 +00:00
|
|
|
#include "../ta-utils.h"
|
2023-09-20 05:24:55 +00:00
|
|
|
#include "../pch.h"
|
2021-05-12 22:19:18 +00:00
|
|
|
|
2022-11-19 09:21:43 +00:00
|
|
|
struct DivSong;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-03-07 03:36:32 +00:00
|
|
|
// NOTICE!
|
|
|
|
// before adding new instrument types to this struct, please ask me first.
|
|
|
|
// absolutely zero support granted to conflicting formats.
|
2022-04-10 21:52:03 +00:00
|
|
|
enum DivInstrumentType: unsigned short {
|
2022-01-09 08:52:41 +00:00
|
|
|
DIV_INS_STD=0,
|
|
|
|
DIV_INS_FM=1,
|
|
|
|
DIV_INS_GB=2,
|
|
|
|
DIV_INS_C64=3,
|
2022-01-13 18:55:33 +00:00
|
|
|
DIV_INS_AMIGA=4,
|
|
|
|
DIV_INS_PCE=5,
|
2022-01-14 05:02:10 +00:00
|
|
|
DIV_INS_AY=6,
|
2022-01-14 20:21:57 +00:00
|
|
|
DIV_INS_AY8930=7,
|
2022-01-15 04:26:22 +00:00
|
|
|
DIV_INS_TIA=8,
|
2022-02-02 23:24:33 +00:00
|
|
|
DIV_INS_SAA1099=9,
|
|
|
|
DIV_INS_VIC=10,
|
|
|
|
DIV_INS_PET=11,
|
|
|
|
DIV_INS_VRC6=12,
|
|
|
|
DIV_INS_OPLL=13,
|
|
|
|
DIV_INS_OPL=14,
|
|
|
|
DIV_INS_FDS=15,
|
|
|
|
DIV_INS_VBOY=16,
|
|
|
|
DIV_INS_N163=17,
|
|
|
|
DIV_INS_SCC=18,
|
|
|
|
DIV_INS_OPZ=19,
|
|
|
|
DIV_INS_POKEY=20,
|
|
|
|
DIV_INS_BEEPER=21,
|
|
|
|
DIV_INS_SWAN=22,
|
2022-02-20 17:15:15 +00:00
|
|
|
DIV_INS_MIKEY=23,
|
2022-03-07 03:21:51 +00:00
|
|
|
DIV_INS_VERA=24,
|
|
|
|
DIV_INS_X1_010=25,
|
2022-03-31 20:25:58 +00:00
|
|
|
DIV_INS_VRC6_SAW=26,
|
2022-04-27 05:56:15 +00:00
|
|
|
DIV_INS_ES5506=27,
|
|
|
|
DIV_INS_MULTIPCM=28,
|
|
|
|
DIV_INS_SNES=29,
|
|
|
|
DIV_INS_SU=30,
|
2022-05-20 07:43:39 +00:00
|
|
|
DIV_INS_NAMCO=31,
|
2022-05-30 23:37:07 +00:00
|
|
|
DIV_INS_OPL_DRUMS=32,
|
2022-09-23 08:41:38 +00:00
|
|
|
DIV_INS_OPM=33,
|
|
|
|
DIV_INS_NES=34,
|
2022-08-28 00:59:56 +00:00
|
|
|
DIV_INS_MSM6258=35,
|
|
|
|
DIV_INS_MSM6295=36,
|
|
|
|
DIV_INS_ADPCMA=37,
|
|
|
|
DIV_INS_ADPCMB=38,
|
|
|
|
DIV_INS_SEGAPCM=39,
|
|
|
|
DIV_INS_QSOUND=40,
|
|
|
|
DIV_INS_YMZ280B=41,
|
|
|
|
DIV_INS_RF5C68=42,
|
2022-10-01 08:15:40 +00:00
|
|
|
DIV_INS_MSM5232=43,
|
2022-10-12 05:46:33 +00:00
|
|
|
DIV_INS_T6W28=44,
|
2022-12-08 05:18:22 +00:00
|
|
|
DIV_INS_K007232=45,
|
2022-12-15 05:47:46 +00:00
|
|
|
DIV_INS_GA20=46,
|
|
|
|
DIV_INS_POKEMINI=47,
|
2023-02-11 12:56:41 +00:00
|
|
|
DIV_INS_SM8521=48,
|
2023-03-05 19:01:21 +00:00
|
|
|
DIV_INS_PV1000=49,
|
2023-04-02 05:32:47 +00:00
|
|
|
DIV_INS_K053260=50,
|
2023-07-23 09:42:38 +00:00
|
|
|
// DIV_INS_YMF292=51,
|
|
|
|
DIV_INS_TED=52,
|
2023-08-09 11:30:00 +00:00
|
|
|
DIV_INS_C140=53,
|
2023-08-27 23:46:10 +00:00
|
|
|
DIV_INS_C219=54,
|
2023-10-14 11:10:37 +00:00
|
|
|
DIV_INS_ESFM=55,
|
2024-01-24 08:15:41 +00:00
|
|
|
DIV_INS_POWERNOISE=56,
|
2022-03-07 03:21:51 +00:00
|
|
|
DIV_INS_MAX,
|
2022-04-27 05:56:15 +00:00
|
|
|
DIV_INS_NULL
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
|
|
|
|
2023-10-06 04:51:34 +00:00
|
|
|
enum DivMacroType: unsigned char {
|
|
|
|
DIV_MACRO_VOL=0,
|
|
|
|
DIV_MACRO_ARP,
|
|
|
|
DIV_MACRO_DUTY,
|
|
|
|
DIV_MACRO_WAVE,
|
|
|
|
DIV_MACRO_PITCH,
|
|
|
|
DIV_MACRO_EX1,
|
|
|
|
DIV_MACRO_EX2,
|
|
|
|
DIV_MACRO_EX3,
|
|
|
|
DIV_MACRO_ALG,
|
|
|
|
DIV_MACRO_FB,
|
|
|
|
DIV_MACRO_FMS,
|
|
|
|
DIV_MACRO_AMS,
|
|
|
|
DIV_MACRO_PAN_LEFT,
|
|
|
|
DIV_MACRO_PAN_RIGHT,
|
|
|
|
DIV_MACRO_PHASE_RESET,
|
|
|
|
DIV_MACRO_EX4,
|
|
|
|
DIV_MACRO_EX5,
|
|
|
|
DIV_MACRO_EX6,
|
|
|
|
DIV_MACRO_EX7,
|
|
|
|
DIV_MACRO_EX8
|
|
|
|
};
|
|
|
|
|
|
|
|
enum DivMacroTypeOp: unsigned char {
|
|
|
|
DIV_MACRO_OP_AM=32,
|
|
|
|
DIV_MACRO_OP_AR,
|
|
|
|
DIV_MACRO_OP_DR,
|
|
|
|
DIV_MACRO_OP_MULT,
|
|
|
|
DIV_MACRO_OP_RR,
|
|
|
|
DIV_MACRO_OP_SL,
|
|
|
|
DIV_MACRO_OP_TL,
|
|
|
|
DIV_MACRO_OP_DT2,
|
|
|
|
DIV_MACRO_OP_RS,
|
|
|
|
DIV_MACRO_OP_DT,
|
|
|
|
DIV_MACRO_OP_D2R,
|
|
|
|
DIV_MACRO_OP_SSG,
|
|
|
|
DIV_MACRO_OP_DAM,
|
|
|
|
DIV_MACRO_OP_DVB,
|
|
|
|
DIV_MACRO_OP_EGT,
|
|
|
|
DIV_MACRO_OP_KSL,
|
|
|
|
DIV_MACRO_OP_SUS,
|
|
|
|
DIV_MACRO_OP_VIB,
|
|
|
|
DIV_MACRO_OP_WS,
|
|
|
|
DIV_MACRO_OP_KSR,
|
|
|
|
};
|
|
|
|
|
2022-03-01 07:38:10 +00:00
|
|
|
// FM operator structure:
|
|
|
|
// - OPN:
|
|
|
|
// - AM, AR, DR, MULT, RR, SL, TL, RS, DT, D2R, SSG-EG
|
|
|
|
// - OPM:
|
|
|
|
// - AM, AR, DR, MULT, RR, SL, TL, DT2, RS, DT, D2R
|
|
|
|
// - OPLL:
|
|
|
|
// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
|
|
|
|
// - KSL, VIB, KSR
|
|
|
|
// - OPL:
|
|
|
|
// - AM, AR, DR, MULT, RR, SL, TL, SSG-EG&8 = EG-S
|
|
|
|
// - KSL, VIB, WS (OPL2/3), KSR
|
2022-04-07 03:56:06 +00:00
|
|
|
// - OPZ:
|
2022-03-01 07:38:10 +00:00
|
|
|
// - AM, AR, DR, MULT (CRS), RR, SL, TL, DT2, RS, DT, D2R
|
2022-04-07 03:56:06 +00:00
|
|
|
// - WS, DVB = MULT (FINE), DAM = REV, KSL = EGShift, EGT = Fixed
|
2022-03-01 07:38:10 +00:00
|
|
|
|
2021-05-11 20:08:08 +00:00
|
|
|
struct DivInstrumentFM {
|
2022-04-07 05:45:53 +00:00
|
|
|
unsigned char alg, fb, fms, ams, fms2, ams2, ops, opllPreset;
|
2022-03-04 06:18:16 +00:00
|
|
|
bool fixedDrums;
|
|
|
|
unsigned short kickFreq, snareHatFreq, tomTopFreq;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentFM& other);
|
|
|
|
bool operator!=(const DivInstrumentFM& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
2021-05-12 22:19:18 +00:00
|
|
|
struct Operator {
|
2022-04-10 05:01:55 +00:00
|
|
|
bool enable;
|
2021-05-11 20:26:38 +00:00
|
|
|
unsigned char am, ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
2022-03-01 07:38:10 +00:00
|
|
|
unsigned char dam, dvb, egt, ksl, sus, vib, ws, ksr; // YMU759/OPL/OPZ
|
2022-09-22 00:27:42 +00:00
|
|
|
unsigned char kvs;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const Operator& other);
|
|
|
|
bool operator!=(const Operator& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
2021-12-12 23:19:43 +00:00
|
|
|
Operator():
|
2022-04-10 21:52:03 +00:00
|
|
|
enable(true),
|
2021-12-12 23:19:43 +00:00
|
|
|
am(0),
|
|
|
|
ar(0),
|
|
|
|
dr(0),
|
|
|
|
mult(0),
|
|
|
|
rr(0),
|
|
|
|
sl(0),
|
|
|
|
tl(0),
|
|
|
|
dt2(0),
|
|
|
|
rs(0),
|
|
|
|
dt(0),
|
|
|
|
d2r(0),
|
|
|
|
ssgEnv(0),
|
|
|
|
dam(0),
|
|
|
|
dvb(0),
|
|
|
|
egt(0),
|
|
|
|
ksl(0),
|
|
|
|
sus(0),
|
|
|
|
vib(0),
|
|
|
|
ws(0),
|
2022-09-22 00:27:42 +00:00
|
|
|
ksr(0),
|
|
|
|
kvs(2) {}
|
2021-05-11 20:08:08 +00:00
|
|
|
} op[4];
|
2021-12-12 23:19:43 +00:00
|
|
|
DivInstrumentFM():
|
|
|
|
alg(0),
|
|
|
|
fb(0),
|
|
|
|
fms(0),
|
|
|
|
ams(0),
|
2022-04-07 05:45:53 +00:00
|
|
|
fms2(0),
|
|
|
|
ams2(0),
|
2022-03-17 07:13:45 +00:00
|
|
|
ops(2),
|
2022-03-04 06:18:16 +00:00
|
|
|
opllPreset(0),
|
|
|
|
fixedDrums(false),
|
|
|
|
kickFreq(0x520),
|
|
|
|
snareHatFreq(0x550),
|
|
|
|
tomTopFreq(0x1c0) {
|
2021-12-27 22:21:43 +00:00
|
|
|
// default instrument
|
|
|
|
fb=4;
|
|
|
|
op[0].tl=42;
|
|
|
|
op[0].ar=31;
|
2022-03-17 19:32:01 +00:00
|
|
|
op[0].dr=8;
|
2021-12-27 22:21:43 +00:00
|
|
|
op[0].sl=15;
|
|
|
|
op[0].rr=3;
|
|
|
|
op[0].mult=5;
|
|
|
|
op[0].dt=5;
|
|
|
|
|
|
|
|
op[2].tl=18;
|
|
|
|
op[2].ar=31;
|
|
|
|
op[2].dr=10;
|
|
|
|
op[2].sl=15;
|
|
|
|
op[2].rr=4;
|
|
|
|
op[2].mult=1;
|
|
|
|
op[2].dt=0;
|
|
|
|
|
2022-03-17 19:32:01 +00:00
|
|
|
op[1].tl=48;
|
2021-12-27 22:21:43 +00:00
|
|
|
op[1].ar=31;
|
2022-03-17 19:32:01 +00:00
|
|
|
op[1].dr=4;
|
2021-12-27 22:21:43 +00:00
|
|
|
op[1].sl=11;
|
2022-03-17 19:32:01 +00:00
|
|
|
op[1].rr=1;
|
2021-12-27 22:21:43 +00:00
|
|
|
op[1].mult=1;
|
|
|
|
op[1].dt=5;
|
|
|
|
|
|
|
|
op[3].tl=2;
|
|
|
|
op[3].ar=31;
|
|
|
|
op[3].dr=9;
|
|
|
|
op[3].sl=15;
|
|
|
|
op[3].rr=9;
|
|
|
|
op[3].mult=1;
|
|
|
|
op[3].dt=0;
|
|
|
|
}
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
|
|
|
|
2022-04-04 09:47:52 +00:00
|
|
|
// this is getting out of hand
|
2022-04-10 05:01:55 +00:00
|
|
|
struct DivInstrumentMacro {
|
|
|
|
int val[256];
|
|
|
|
unsigned int mode;
|
2022-10-07 09:11:45 +00:00
|
|
|
unsigned char open;
|
2022-08-22 07:13:33 +00:00
|
|
|
unsigned char len, delay, speed, loop, rel;
|
2023-10-06 05:34:51 +00:00
|
|
|
// 0-31: normal
|
|
|
|
// 32+: operator (top 3 bits select operator, starting from 1)
|
|
|
|
unsigned char macroType;
|
2022-05-07 21:25:02 +00:00
|
|
|
|
|
|
|
// the following variables are used by the GUI and not saved in the file
|
|
|
|
int vScroll, vZoom;
|
2022-10-07 21:47:18 +00:00
|
|
|
int typeMemory[16];
|
|
|
|
unsigned char lenMemory;
|
2022-05-07 21:25:02 +00:00
|
|
|
|
2023-10-06 04:51:34 +00:00
|
|
|
explicit DivInstrumentMacro(unsigned char initType, bool initOpen=false):
|
2022-04-10 05:01:55 +00:00
|
|
|
mode(0),
|
|
|
|
open(initOpen),
|
|
|
|
len(0),
|
2022-08-22 07:13:33 +00:00
|
|
|
delay(0),
|
|
|
|
speed(1),
|
|
|
|
loop(255),
|
|
|
|
rel(255),
|
2023-10-06 05:34:51 +00:00
|
|
|
macroType(initType),
|
2022-05-07 21:25:02 +00:00
|
|
|
vScroll(0),
|
2022-10-07 21:47:18 +00:00
|
|
|
vZoom(-1),
|
|
|
|
lenMemory(0) {
|
2022-04-10 08:26:50 +00:00
|
|
|
memset(val,0,256*sizeof(int));
|
2022-10-07 21:47:18 +00:00
|
|
|
memset(typeMemory,0,16*sizeof(int));
|
2022-04-10 21:52:03 +00:00
|
|
|
}
|
2022-04-10 05:01:55 +00:00
|
|
|
};
|
2022-04-04 09:47:52 +00:00
|
|
|
|
2022-04-10 05:01:55 +00:00
|
|
|
struct DivInstrumentSTD {
|
|
|
|
DivInstrumentMacro volMacro;
|
|
|
|
DivInstrumentMacro arpMacro;
|
|
|
|
DivInstrumentMacro dutyMacro;
|
|
|
|
DivInstrumentMacro waveMacro;
|
|
|
|
DivInstrumentMacro pitchMacro;
|
|
|
|
DivInstrumentMacro ex1Macro;
|
|
|
|
DivInstrumentMacro ex2Macro;
|
|
|
|
DivInstrumentMacro ex3Macro;
|
|
|
|
DivInstrumentMacro algMacro;
|
|
|
|
DivInstrumentMacro fbMacro;
|
|
|
|
DivInstrumentMacro fmsMacro;
|
|
|
|
DivInstrumentMacro amsMacro;
|
|
|
|
DivInstrumentMacro panLMacro;
|
|
|
|
DivInstrumentMacro panRMacro;
|
|
|
|
DivInstrumentMacro phaseResetMacro;
|
|
|
|
DivInstrumentMacro ex4Macro;
|
|
|
|
DivInstrumentMacro ex5Macro;
|
|
|
|
DivInstrumentMacro ex6Macro;
|
|
|
|
DivInstrumentMacro ex7Macro;
|
|
|
|
DivInstrumentMacro ex8Macro;
|
2022-04-04 09:47:52 +00:00
|
|
|
|
2022-01-18 21:32:53 +00:00
|
|
|
struct OpMacro {
|
|
|
|
// ar, dr, mult, rr, sl, tl, dt2, rs, dt, d2r, ssgEnv;
|
2022-04-10 05:01:55 +00:00
|
|
|
DivInstrumentMacro amMacro;
|
|
|
|
DivInstrumentMacro arMacro;
|
|
|
|
DivInstrumentMacro drMacro;
|
|
|
|
DivInstrumentMacro multMacro;
|
|
|
|
DivInstrumentMacro rrMacro;
|
|
|
|
DivInstrumentMacro slMacro;
|
|
|
|
DivInstrumentMacro tlMacro;
|
|
|
|
DivInstrumentMacro dt2Macro;
|
|
|
|
DivInstrumentMacro rsMacro;
|
|
|
|
DivInstrumentMacro dtMacro;
|
|
|
|
DivInstrumentMacro d2rMacro;
|
|
|
|
DivInstrumentMacro ssgMacro;
|
|
|
|
DivInstrumentMacro damMacro;
|
|
|
|
DivInstrumentMacro dvbMacro;
|
|
|
|
DivInstrumentMacro egtMacro;
|
|
|
|
DivInstrumentMacro kslMacro;
|
|
|
|
DivInstrumentMacro susMacro;
|
|
|
|
DivInstrumentMacro vibMacro;
|
|
|
|
DivInstrumentMacro wsMacro;
|
|
|
|
DivInstrumentMacro ksrMacro;
|
2022-01-18 21:32:53 +00:00
|
|
|
OpMacro():
|
2023-10-06 04:51:34 +00:00
|
|
|
amMacro(DIV_MACRO_OP_AM), arMacro(DIV_MACRO_OP_AR), drMacro(DIV_MACRO_OP_DR), multMacro(DIV_MACRO_OP_MULT),
|
|
|
|
rrMacro(DIV_MACRO_OP_RR), slMacro(DIV_MACRO_OP_SL), tlMacro(DIV_MACRO_OP_TL,true), dt2Macro(DIV_MACRO_OP_DT2),
|
|
|
|
rsMacro(DIV_MACRO_OP_RS), dtMacro(DIV_MACRO_OP_DT), d2rMacro(DIV_MACRO_OP_D2R), ssgMacro(DIV_MACRO_OP_SSG),
|
|
|
|
damMacro(DIV_MACRO_OP_DAM), dvbMacro(DIV_MACRO_OP_DVB), egtMacro(DIV_MACRO_OP_EGT), kslMacro(DIV_MACRO_OP_KSL),
|
|
|
|
susMacro(DIV_MACRO_OP_SUS), vibMacro(DIV_MACRO_OP_VIB), wsMacro(DIV_MACRO_OP_WS), ksrMacro(DIV_MACRO_OP_KSR) {}
|
2022-01-18 21:32:53 +00:00
|
|
|
} opMacros[4];
|
2021-12-12 23:19:43 +00:00
|
|
|
DivInstrumentSTD():
|
2023-10-06 04:51:34 +00:00
|
|
|
volMacro(DIV_MACRO_VOL,true),
|
|
|
|
arpMacro(DIV_MACRO_ARP),
|
|
|
|
dutyMacro(DIV_MACRO_DUTY),
|
|
|
|
waveMacro(DIV_MACRO_WAVE),
|
|
|
|
pitchMacro(DIV_MACRO_PITCH),
|
|
|
|
ex1Macro(DIV_MACRO_EX1),
|
|
|
|
ex2Macro(DIV_MACRO_EX2),
|
|
|
|
ex3Macro(DIV_MACRO_EX3),
|
|
|
|
algMacro(DIV_MACRO_ALG),
|
|
|
|
fbMacro(DIV_MACRO_FB),
|
|
|
|
fmsMacro(DIV_MACRO_FMS),
|
|
|
|
amsMacro(DIV_MACRO_AMS),
|
|
|
|
panLMacro(DIV_MACRO_PAN_LEFT),
|
|
|
|
panRMacro(DIV_MACRO_PAN_RIGHT),
|
|
|
|
phaseResetMacro(DIV_MACRO_PHASE_RESET),
|
|
|
|
ex4Macro(DIV_MACRO_EX4),
|
|
|
|
ex5Macro(DIV_MACRO_EX5),
|
2023-10-06 05:34:51 +00:00
|
|
|
ex6Macro(DIV_MACRO_EX6),
|
2023-10-06 04:51:34 +00:00
|
|
|
ex7Macro(DIV_MACRO_EX7),
|
|
|
|
ex8Macro(DIV_MACRO_EX8) {
|
|
|
|
for (int i=0; i<4; i++) {
|
|
|
|
opMacros[i].amMacro.macroType=DIV_MACRO_OP_AM+(i<<5);
|
|
|
|
opMacros[i].arMacro.macroType=DIV_MACRO_OP_AR+(i<<5);
|
|
|
|
opMacros[i].drMacro.macroType=DIV_MACRO_OP_DR+(i<<5);
|
|
|
|
opMacros[i].multMacro.macroType=DIV_MACRO_OP_MULT+(i<<5);
|
|
|
|
opMacros[i].rrMacro.macroType=DIV_MACRO_OP_RR+(i<<5);
|
|
|
|
opMacros[i].slMacro.macroType=DIV_MACRO_OP_SL+(i<<5);
|
|
|
|
opMacros[i].tlMacro.macroType=DIV_MACRO_OP_TL+(i<<5);
|
|
|
|
opMacros[i].dt2Macro.macroType=DIV_MACRO_OP_DT2+(i<<5);
|
|
|
|
opMacros[i].rsMacro.macroType=DIV_MACRO_OP_RS+(i<<5);
|
|
|
|
opMacros[i].dtMacro.macroType=DIV_MACRO_OP_DT+(i<<5);
|
|
|
|
opMacros[i].d2rMacro.macroType=DIV_MACRO_OP_D2R+(i<<5);
|
|
|
|
opMacros[i].ssgMacro.macroType=DIV_MACRO_OP_SSG+(i<<5);
|
|
|
|
|
|
|
|
opMacros[i].damMacro.macroType=DIV_MACRO_OP_DAM+(i<<5);
|
|
|
|
opMacros[i].dvbMacro.macroType=DIV_MACRO_OP_DVB+(i<<5);
|
|
|
|
opMacros[i].egtMacro.macroType=DIV_MACRO_OP_EGT+(i<<5);
|
|
|
|
opMacros[i].kslMacro.macroType=DIV_MACRO_OP_KSL+(i<<5);
|
|
|
|
opMacros[i].susMacro.macroType=DIV_MACRO_OP_SUS+(i<<5);
|
|
|
|
opMacros[i].vibMacro.macroType=DIV_MACRO_OP_VIB+(i<<5);
|
|
|
|
opMacros[i].wsMacro.macroType=DIV_MACRO_OP_WS+(i<<5);
|
|
|
|
opMacros[i].ksrMacro.macroType=DIV_MACRO_OP_KSR+(i<<5);
|
|
|
|
}
|
|
|
|
}
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DivInstrumentGB {
|
2022-08-07 05:03:27 +00:00
|
|
|
unsigned char envVol, envDir, envLen, soundLen, hwSeqLen;
|
2022-08-10 06:55:44 +00:00
|
|
|
bool softEnv, alwaysInit;
|
2022-08-07 06:32:28 +00:00
|
|
|
enum HWSeqCommands: unsigned char {
|
|
|
|
DIV_GB_HWCMD_ENVELOPE=0,
|
|
|
|
DIV_GB_HWCMD_SWEEP,
|
|
|
|
DIV_GB_HWCMD_WAIT,
|
|
|
|
DIV_GB_HWCMD_WAIT_REL,
|
|
|
|
DIV_GB_HWCMD_LOOP,
|
|
|
|
DIV_GB_HWCMD_LOOP_REL,
|
|
|
|
|
|
|
|
DIV_GB_HWCMD_MAX
|
|
|
|
};
|
2023-10-21 23:42:37 +00:00
|
|
|
struct HWSeqCommandGB {
|
2022-08-07 05:03:27 +00:00
|
|
|
unsigned char cmd;
|
|
|
|
unsigned short data;
|
|
|
|
} hwSeq[256];
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentGB& other);
|
|
|
|
bool operator!=(const DivInstrumentGB& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2021-12-12 23:19:43 +00:00
|
|
|
DivInstrumentGB():
|
2021-12-18 03:14:41 +00:00
|
|
|
envVol(15),
|
2021-12-12 23:19:43 +00:00
|
|
|
envDir(0),
|
2021-12-18 03:14:41 +00:00
|
|
|
envLen(2),
|
2022-08-07 05:03:27 +00:00
|
|
|
soundLen(64),
|
2022-08-10 06:55:44 +00:00
|
|
|
hwSeqLen(0),
|
|
|
|
softEnv(false),
|
|
|
|
alwaysInit(false) {
|
2023-10-21 23:42:37 +00:00
|
|
|
memset(hwSeq,0,256*sizeof(HWSeqCommandGB));
|
2022-08-07 05:03:27 +00:00
|
|
|
}
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DivInstrumentC64 {
|
|
|
|
bool triOn, sawOn, pulseOn, noiseOn;
|
|
|
|
unsigned char a, d, s, r;
|
2022-01-09 22:00:52 +00:00
|
|
|
unsigned short duty;
|
2021-05-11 20:08:08 +00:00
|
|
|
unsigned char ringMod, oscSync;
|
2023-10-29 07:25:35 +00:00
|
|
|
bool toFilter, initFilter, dutyIsAbs, filterIsAbs, noTest;
|
2022-01-09 22:00:52 +00:00
|
|
|
unsigned char res;
|
|
|
|
unsigned short cut;
|
2021-05-11 20:08:08 +00:00
|
|
|
bool hp, lp, bp, ch3off;
|
2021-12-12 23:19:43 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentC64& other);
|
|
|
|
bool operator!=(const DivInstrumentC64& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2021-12-12 23:19:43 +00:00
|
|
|
DivInstrumentC64():
|
|
|
|
triOn(false),
|
|
|
|
sawOn(true),
|
|
|
|
pulseOn(false),
|
|
|
|
noiseOn(false),
|
|
|
|
a(0),
|
|
|
|
d(8),
|
|
|
|
s(0),
|
|
|
|
r(0),
|
2022-01-09 22:00:52 +00:00
|
|
|
duty(2048),
|
2021-12-12 23:19:43 +00:00
|
|
|
ringMod(0),
|
|
|
|
oscSync(0),
|
|
|
|
toFilter(false),
|
|
|
|
initFilter(false),
|
2022-01-09 08:52:41 +00:00
|
|
|
dutyIsAbs(false),
|
|
|
|
filterIsAbs(false),
|
2022-04-28 04:54:45 +00:00
|
|
|
noTest(false),
|
2021-12-12 23:19:43 +00:00
|
|
|
res(0),
|
|
|
|
cut(0),
|
|
|
|
hp(false),
|
|
|
|
lp(false),
|
|
|
|
bp(false),
|
|
|
|
ch3off(false) {}
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
|
|
|
|
2022-01-09 08:52:41 +00:00
|
|
|
struct DivInstrumentAmiga {
|
2022-07-20 14:01:06 +00:00
|
|
|
struct SampleMap {
|
|
|
|
int freq;
|
|
|
|
short map;
|
2023-10-13 00:52:44 +00:00
|
|
|
signed char dpcmFreq;
|
|
|
|
signed char dpcmDelta;
|
|
|
|
SampleMap(int f=0, short m=-1, signed char df=15, signed char dd=-1):
|
2022-07-20 14:01:06 +00:00
|
|
|
freq(f),
|
2023-10-13 00:52:44 +00:00
|
|
|
map(m),
|
|
|
|
dpcmFreq(df),
|
|
|
|
dpcmDelta(dd) {}
|
2022-07-20 14:01:06 +00:00
|
|
|
};
|
2022-01-09 08:52:41 +00:00
|
|
|
short initSample;
|
2022-03-16 22:01:44 +00:00
|
|
|
bool useNoteMap;
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
bool useSample;
|
2022-04-12 06:19:00 +00:00
|
|
|
bool useWave;
|
|
|
|
unsigned char waveLen;
|
2022-07-20 14:01:06 +00:00
|
|
|
SampleMap noteMap[120];
|
2022-01-09 08:52:41 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentAmiga& other);
|
|
|
|
bool operator!=(const DivInstrumentAmiga& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-05-13 23:46:52 +00:00
|
|
|
/**
|
|
|
|
* get the sample at specified note.
|
|
|
|
* @return the sample.
|
|
|
|
*/
|
|
|
|
inline short getSample(int note) {
|
|
|
|
if (useNoteMap) {
|
|
|
|
if (note<0) note=0;
|
|
|
|
if (note>119) note=119;
|
2022-07-20 14:01:06 +00:00
|
|
|
return noteMap[note].map;
|
2022-05-13 23:46:52 +00:00
|
|
|
}
|
|
|
|
return initSample;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-10-14 00:57:36 +00:00
|
|
|
* get the sample playback note at specified note.
|
|
|
|
* @return the note, or -1 if not using note map.
|
2022-05-13 23:46:52 +00:00
|
|
|
*/
|
|
|
|
inline int getFreq(int note) {
|
|
|
|
if (useNoteMap) {
|
|
|
|
if (note<0) note=0;
|
|
|
|
if (note>119) note=119;
|
2022-07-20 14:01:06 +00:00
|
|
|
return noteMap[note].freq;
|
2022-05-13 23:46:52 +00:00
|
|
|
}
|
2023-04-07 21:54:05 +00:00
|
|
|
return note;
|
2022-05-13 23:46:52 +00:00
|
|
|
}
|
|
|
|
|
2023-10-14 00:57:36 +00:00
|
|
|
/**
|
|
|
|
* get the DPCM pitch at specified note.
|
|
|
|
* @return the pitch, or -1 if not using note map.
|
|
|
|
*/
|
|
|
|
inline signed char getDPCMFreq(int note) {
|
|
|
|
if (useNoteMap) {
|
|
|
|
if (note<0) note=0;
|
|
|
|
if (note>119) note=119;
|
|
|
|
return noteMap[note].dpcmFreq;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get the DPCM delta counter value at specified note.
|
|
|
|
* @return the delta counter value, or -1 if not using note map.
|
|
|
|
*/
|
|
|
|
inline signed char getDPCMDelta(int note) {
|
|
|
|
if (useNoteMap) {
|
|
|
|
if (note<0) note=0;
|
|
|
|
if (note>119) note=119;
|
|
|
|
return noteMap[note].dpcmDelta;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2022-01-09 08:52:41 +00:00
|
|
|
DivInstrumentAmiga():
|
2022-03-16 22:01:44 +00:00
|
|
|
initSample(0),
|
2022-04-12 06:19:00 +00:00
|
|
|
useNoteMap(false),
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
useSample(false),
|
2022-04-12 06:19:00 +00:00
|
|
|
useWave(false),
|
|
|
|
waveLen(31) {
|
2023-04-07 21:54:05 +00:00
|
|
|
for (int i=0; i<120; i++) {
|
|
|
|
noteMap[i].map=-1;
|
|
|
|
noteMap[i].freq=i;
|
2022-07-20 14:01:06 +00:00
|
|
|
}
|
2022-03-16 22:01:44 +00:00
|
|
|
}
|
2022-01-09 08:52:41 +00:00
|
|
|
};
|
|
|
|
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
struct DivInstrumentX1_010 {
|
|
|
|
int bankSlot;
|
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentX1_010& other);
|
|
|
|
bool operator!=(const DivInstrumentX1_010& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
DivInstrumentX1_010():
|
|
|
|
bankSlot(0) {}
|
|
|
|
};
|
|
|
|
|
2022-03-23 18:53:07 +00:00
|
|
|
struct DivInstrumentN163 {
|
|
|
|
int wave, wavePos, waveLen;
|
|
|
|
unsigned char waveMode;
|
2023-07-22 00:54:35 +00:00
|
|
|
bool perChanPos;
|
|
|
|
int wavePosCh[8];
|
|
|
|
int waveLenCh[8];
|
2022-03-23 18:53:07 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentN163& other);
|
|
|
|
bool operator!=(const DivInstrumentN163& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-23 18:53:07 +00:00
|
|
|
DivInstrumentN163():
|
|
|
|
wave(-1),
|
|
|
|
wavePos(0),
|
2022-03-28 03:04:01 +00:00
|
|
|
waveLen(32),
|
2023-07-22 00:54:35 +00:00
|
|
|
waveMode(3),
|
|
|
|
perChanPos(false) {
|
|
|
|
for (int i=0; i<8; i++) {
|
|
|
|
wavePosCh[i]=(i&3)<<5;
|
|
|
|
waveLenCh[i]=32;
|
|
|
|
}
|
|
|
|
}
|
2022-03-23 18:53:07 +00:00
|
|
|
};
|
|
|
|
|
2022-04-04 03:37:16 +00:00
|
|
|
struct DivInstrumentFDS {
|
|
|
|
signed char modTable[32];
|
2022-04-04 09:47:52 +00:00
|
|
|
int modSpeed, modDepth;
|
|
|
|
// this is here for compatibility.
|
|
|
|
bool initModTableWithFirstWave;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentFDS& other);
|
|
|
|
bool operator!=(const DivInstrumentFDS& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-04 03:37:16 +00:00
|
|
|
DivInstrumentFDS():
|
|
|
|
modSpeed(0),
|
2022-04-04 09:47:52 +00:00
|
|
|
modDepth(0),
|
|
|
|
initModTableWithFirstWave(false) {
|
2022-04-04 03:37:16 +00:00
|
|
|
memset(modTable,0,32);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-05 19:20:36 +00:00
|
|
|
struct DivInstrumentMultiPCM {
|
|
|
|
unsigned char ar, d1r, dl, d2r, rr, rc;
|
|
|
|
unsigned char lfo, vib, am;
|
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentMultiPCM& other);
|
|
|
|
bool operator!=(const DivInstrumentMultiPCM& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-05-05 19:20:36 +00:00
|
|
|
DivInstrumentMultiPCM():
|
|
|
|
ar(15), d1r(15), dl(0), d2r(0), rr(15), rc(15),
|
|
|
|
lfo(0), vib(0), am(0) {
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-04-07 20:46:48 +00:00
|
|
|
enum DivWaveSynthEffects {
|
|
|
|
DIV_WS_NONE=0,
|
|
|
|
// one waveform effects
|
|
|
|
DIV_WS_INVERT,
|
|
|
|
DIV_WS_ADD,
|
|
|
|
DIV_WS_SUBTRACT,
|
|
|
|
DIV_WS_AVERAGE,
|
|
|
|
DIV_WS_PHASE,
|
2022-05-21 23:36:15 +00:00
|
|
|
DIV_WS_CHORUS,
|
2022-04-07 23:27:17 +00:00
|
|
|
|
|
|
|
DIV_WS_SINGLE_MAX,
|
|
|
|
|
2022-04-07 20:46:48 +00:00
|
|
|
// two waveform effects
|
|
|
|
DIV_WS_NONE_DUAL=128,
|
|
|
|
DIV_WS_WIPE,
|
|
|
|
DIV_WS_FADE,
|
|
|
|
DIV_WS_PING_PONG,
|
|
|
|
DIV_WS_OVERLAY,
|
|
|
|
DIV_WS_NEGATIVE_OVERLAY,
|
2022-05-21 23:36:15 +00:00
|
|
|
DIV_WS_SLIDE,
|
|
|
|
DIV_WS_MIX,
|
|
|
|
DIV_WS_PHASE_MOD,
|
2022-04-07 23:27:17 +00:00
|
|
|
|
|
|
|
DIV_WS_DUAL_MAX
|
2022-04-07 20:46:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct DivInstrumentWaveSynth {
|
|
|
|
int wave1, wave2;
|
2022-04-08 09:34:39 +00:00
|
|
|
unsigned char rateDivider;
|
2022-04-07 23:27:17 +00:00
|
|
|
unsigned char effect;
|
2022-04-07 20:46:48 +00:00
|
|
|
bool oneShot, enabled, global;
|
|
|
|
unsigned char speed, param1, param2, param3, param4;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentWaveSynth& other);
|
|
|
|
bool operator!=(const DivInstrumentWaveSynth& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-07 20:46:48 +00:00
|
|
|
DivInstrumentWaveSynth():
|
|
|
|
wave1(0),
|
|
|
|
wave2(0),
|
|
|
|
rateDivider(1),
|
|
|
|
effect(DIV_WS_NONE),
|
|
|
|
oneShot(false),
|
|
|
|
enabled(false),
|
|
|
|
global(false),
|
2022-04-08 07:11:33 +00:00
|
|
|
speed(0),
|
2022-04-07 20:46:48 +00:00
|
|
|
param1(0),
|
|
|
|
param2(0),
|
|
|
|
param3(0),
|
|
|
|
param4(0) {}
|
|
|
|
};
|
|
|
|
|
2022-08-06 09:04:18 +00:00
|
|
|
struct DivInstrumentSoundUnit {
|
|
|
|
bool switchRoles;
|
2023-10-21 23:42:37 +00:00
|
|
|
unsigned char hwSeqLen;
|
|
|
|
enum HWSeqCommands: unsigned char {
|
|
|
|
DIV_SU_HWCMD_VOL=0,
|
|
|
|
DIV_SU_HWCMD_PITCH,
|
|
|
|
DIV_SU_HWCMD_CUT,
|
|
|
|
DIV_SU_HWCMD_WAIT,
|
|
|
|
DIV_SU_HWCMD_WAIT_REL,
|
|
|
|
DIV_SU_HWCMD_LOOP,
|
|
|
|
DIV_SU_HWCMD_LOOP_REL,
|
|
|
|
|
|
|
|
DIV_SU_HWCMD_MAX
|
|
|
|
};
|
|
|
|
struct HWSeqCommandSU {
|
|
|
|
unsigned char cmd;
|
|
|
|
unsigned char bound;
|
|
|
|
unsigned char val;
|
|
|
|
unsigned short speed;
|
|
|
|
unsigned short padding;
|
|
|
|
} hwSeq[256];
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentSoundUnit& other);
|
|
|
|
bool operator!=(const DivInstrumentSoundUnit& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
2022-08-06 09:04:18 +00:00
|
|
|
DivInstrumentSoundUnit():
|
2023-10-21 23:42:37 +00:00
|
|
|
switchRoles(false),
|
|
|
|
hwSeqLen(0) {
|
|
|
|
memset(hwSeq,0,256*sizeof(HWSeqCommandSU));
|
|
|
|
}
|
2022-08-06 09:04:18 +00:00
|
|
|
};
|
|
|
|
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
struct DivInstrumentES5506 {
|
|
|
|
struct Filter {
|
|
|
|
enum FilterMode: unsigned char { // filter mode for pole 4,3
|
|
|
|
FILTER_MODE_HPK2_HPK2=0,
|
|
|
|
FILTER_MODE_HPK2_LPK1,
|
|
|
|
FILTER_MODE_LPK2_LPK2,
|
|
|
|
FILTER_MODE_LPK2_LPK1,
|
|
|
|
};
|
|
|
|
FilterMode mode;
|
|
|
|
unsigned short k1, k2;
|
|
|
|
Filter():
|
|
|
|
mode(FILTER_MODE_LPK2_LPK1),
|
|
|
|
k1(0xffff),
|
|
|
|
k2(0xffff) {}
|
|
|
|
};
|
|
|
|
struct Envelope {
|
|
|
|
unsigned short ecount;
|
|
|
|
signed char lVRamp, rVRamp;
|
|
|
|
signed char k1Ramp, k2Ramp;
|
|
|
|
bool k1Slow, k2Slow;
|
|
|
|
Envelope():
|
|
|
|
ecount(0),
|
|
|
|
lVRamp(0),
|
|
|
|
rVRamp(0),
|
|
|
|
k1Ramp(0),
|
|
|
|
k2Ramp(0),
|
|
|
|
k1Slow(false),
|
|
|
|
k2Slow(false) {}
|
|
|
|
};
|
|
|
|
Filter filter;
|
|
|
|
Envelope envelope;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentES5506& other);
|
|
|
|
bool operator!=(const DivInstrumentES5506& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
DivInstrumentES5506():
|
|
|
|
filter(Filter()),
|
|
|
|
envelope(Envelope()) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DivInstrumentSNES {
|
2022-09-24 07:53:11 +00:00
|
|
|
enum GainMode: unsigned char {
|
|
|
|
GAIN_MODE_DIRECT=0,
|
|
|
|
GAIN_MODE_DEC_LINEAR=4,
|
|
|
|
GAIN_MODE_DEC_LOG=5,
|
|
|
|
GAIN_MODE_INC_LINEAR=6,
|
|
|
|
GAIN_MODE_INC_INVLOG=7
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
};
|
2022-12-24 23:03:57 +00:00
|
|
|
bool useEnv;
|
|
|
|
// 0: no sustain (key off = cut)
|
|
|
|
// 1: sustain (R = d2; key off = dec linear to r)
|
|
|
|
// 2: sustain (R = d2; key off = dec exponential to r)
|
|
|
|
// 3: sustain (R = d2; key off = R to r)
|
|
|
|
unsigned char sus;
|
2022-09-24 07:53:11 +00:00
|
|
|
GainMode gainMode;
|
|
|
|
unsigned char gain;
|
2022-12-24 23:03:57 +00:00
|
|
|
unsigned char a, d, s, r, d2;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
2022-11-19 19:40:41 +00:00
|
|
|
bool operator==(const DivInstrumentSNES& other);
|
|
|
|
bool operator!=(const DivInstrumentSNES& other) {
|
|
|
|
return !(*this==other);
|
2022-11-19 09:05:52 +00:00
|
|
|
}
|
|
|
|
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
DivInstrumentSNES():
|
|
|
|
useEnv(true),
|
2022-12-24 23:03:57 +00:00
|
|
|
sus(0),
|
2022-09-24 07:53:11 +00:00
|
|
|
gainMode(GAIN_MODE_DIRECT),
|
|
|
|
gain(127),
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
a(15),
|
|
|
|
d(7),
|
|
|
|
s(7),
|
2022-12-24 23:03:57 +00:00
|
|
|
r(0),
|
|
|
|
d2(0) {}
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
};
|
|
|
|
|
2023-10-14 11:10:37 +00:00
|
|
|
// ESFM operator structure:
|
|
|
|
// - DELAY, OUT, MOD, L, R, NOISE
|
2023-10-15 22:46:07 +00:00
|
|
|
// - Virtual: CT, DT, FIXED
|
2023-10-14 11:10:37 +00:00
|
|
|
// - In FM struct: AM, DAM, AR, DR, MULT, RR, SL, TL
|
|
|
|
// - In FM struct: KSL, VIB, DVB, WS, SUS, KSR
|
|
|
|
// - Not in struct: FNUML, FNUMH, BLOCK
|
|
|
|
|
|
|
|
struct DivInstrumentESFM {
|
|
|
|
bool operator==(const DivInstrumentESFM& other);
|
|
|
|
bool operator!=(const DivInstrumentESFM& other) {
|
|
|
|
return !(*this==other);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only works on OP4, so putting it outside the Operator struct instead
|
|
|
|
unsigned char noise;
|
|
|
|
struct Operator {
|
2023-10-15 22:46:07 +00:00
|
|
|
unsigned char delay, outLvl, modIn, left, right, fixed;
|
2023-10-14 11:10:37 +00:00
|
|
|
signed char ct, dt;
|
|
|
|
|
|
|
|
bool operator==(const Operator& other);
|
|
|
|
bool operator!=(const Operator& other) {
|
|
|
|
return !(*this==other);
|
|
|
|
}
|
|
|
|
Operator():
|
|
|
|
delay(0),
|
|
|
|
outLvl(0),
|
|
|
|
modIn(0),
|
2023-10-15 22:46:07 +00:00
|
|
|
left(1),
|
|
|
|
right(1),
|
|
|
|
fixed(0),
|
2023-10-14 11:10:37 +00:00
|
|
|
ct(0),
|
|
|
|
dt(0) {}
|
|
|
|
} op[4];
|
|
|
|
DivInstrumentESFM():
|
|
|
|
noise(0)
|
|
|
|
{
|
|
|
|
op[0].modIn=4;
|
|
|
|
op[0].outLvl=0;
|
|
|
|
|
|
|
|
op[1].modIn=7;
|
|
|
|
op[1].outLvl=0;
|
|
|
|
|
|
|
|
op[2].modIn=7;
|
|
|
|
op[2].outLvl=0;
|
|
|
|
|
|
|
|
op[3].modIn=7;
|
|
|
|
op[3].outLvl=7;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-05-11 20:08:08 +00:00
|
|
|
struct DivInstrument {
|
|
|
|
String name;
|
|
|
|
DivInstrumentType type;
|
|
|
|
DivInstrumentFM fm;
|
|
|
|
DivInstrumentSTD std;
|
|
|
|
DivInstrumentGB gb;
|
|
|
|
DivInstrumentC64 c64;
|
2022-01-09 08:52:41 +00:00
|
|
|
DivInstrumentAmiga amiga;
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
DivInstrumentX1_010 x1_010;
|
2022-03-23 18:53:07 +00:00
|
|
|
DivInstrumentN163 n163;
|
2022-04-04 09:47:52 +00:00
|
|
|
DivInstrumentFDS fds;
|
2022-05-05 19:20:36 +00:00
|
|
|
DivInstrumentMultiPCM multipcm;
|
2022-04-07 20:46:48 +00:00
|
|
|
DivInstrumentWaveSynth ws;
|
2022-08-06 09:04:18 +00:00
|
|
|
DivInstrumentSoundUnit su;
|
Prepare for split sample chip instrument
(MSM6258, MSM6295, QSound, Sega PCM, ADPCM-A, ADPCM-B, YMZ280B, RF5C68)
Instrument color and icons are placeholder.
different volume range, hard panned/soft panned and/or independent volume per output, chip-dependent features (global volume, echo, etc)
Allow use sample in instrument tab for chip with sample support
Prepare to support X1-010 Seta 2 style bankswitch behavior
Prepare to support AY89x0 PCM DAC
Support volume for PCE sample (DAC)
Fix Lynx, Y8950 sample pitch matches to sample preview
Support PCM DAC with backward and pingpong loop mode
Reduce some codes
Add Sega PCM, AY89x0, QSound, PCM DAC, Lynx per-channel debug support
2022-08-27 07:27:36 +00:00
|
|
|
DivInstrumentES5506 es5506;
|
|
|
|
DivInstrumentSNES snes;
|
2023-10-14 11:10:37 +00:00
|
|
|
DivInstrumentESFM esfm;
|
2022-11-19 09:05:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* these are internal functions.
|
|
|
|
*/
|
2023-10-06 04:51:34 +00:00
|
|
|
void writeMacro(SafeWriter* w, const DivInstrumentMacro& m);
|
2022-11-19 09:05:52 +00:00
|
|
|
void writeFeatureNA(SafeWriter* w);
|
2022-11-19 23:13:17 +00:00
|
|
|
void writeFeatureFM(SafeWriter* w, bool fui);
|
2022-11-19 09:05:52 +00:00
|
|
|
void writeFeatureMA(SafeWriter* w);
|
|
|
|
void writeFeature64(SafeWriter* w);
|
|
|
|
void writeFeatureGB(SafeWriter* w);
|
|
|
|
void writeFeatureSM(SafeWriter* w);
|
|
|
|
void writeFeatureOx(SafeWriter* w, int op);
|
|
|
|
void writeFeatureLD(SafeWriter* w);
|
|
|
|
void writeFeatureSN(SafeWriter* w);
|
|
|
|
void writeFeatureN1(SafeWriter* w);
|
|
|
|
void writeFeatureFD(SafeWriter* w);
|
|
|
|
void writeFeatureWS(SafeWriter* w);
|
2022-11-20 03:12:05 +00:00
|
|
|
size_t writeFeatureSL(SafeWriter* w, std::vector<int>& list, const DivSong* song);
|
|
|
|
size_t writeFeatureWL(SafeWriter* w, std::vector<int>& list, const DivSong* song);
|
2022-11-19 09:05:52 +00:00
|
|
|
void writeFeatureMP(SafeWriter* w);
|
|
|
|
void writeFeatureSU(SafeWriter* w);
|
|
|
|
void writeFeatureES(SafeWriter* w);
|
|
|
|
void writeFeatureX1(SafeWriter* w);
|
2023-10-13 00:52:44 +00:00
|
|
|
void writeFeatureNE(SafeWriter* w);
|
2023-10-14 11:10:37 +00:00
|
|
|
void writeFeatureEF(SafeWriter* w);
|
2022-11-20 08:24:23 +00:00
|
|
|
|
2022-12-24 23:03:57 +00:00
|
|
|
void readFeatureNA(SafeReader& reader, short version);
|
|
|
|
void readFeatureFM(SafeReader& reader, short version);
|
|
|
|
void readFeatureMA(SafeReader& reader, short version);
|
2023-10-29 07:25:35 +00:00
|
|
|
void readFeature64(SafeReader& reader, bool& volIsCutoff, short version);
|
2022-12-24 23:03:57 +00:00
|
|
|
void readFeatureGB(SafeReader& reader, short version);
|
|
|
|
void readFeatureSM(SafeReader& reader, short version);
|
|
|
|
void readFeatureOx(SafeReader& reader, int op, short version);
|
|
|
|
void readFeatureLD(SafeReader& reader, short version);
|
|
|
|
void readFeatureSN(SafeReader& reader, short version);
|
|
|
|
void readFeatureN1(SafeReader& reader, short version);
|
|
|
|
void readFeatureFD(SafeReader& reader, short version);
|
|
|
|
void readFeatureWS(SafeReader& reader, short version);
|
2022-11-21 00:19:24 +00:00
|
|
|
void readFeatureSL(SafeReader& reader, DivSong* song, short version);
|
|
|
|
void readFeatureWL(SafeReader& reader, DivSong* song, short version);
|
2022-12-24 23:03:57 +00:00
|
|
|
void readFeatureMP(SafeReader& reader, short version);
|
|
|
|
void readFeatureSU(SafeReader& reader, short version);
|
|
|
|
void readFeatureES(SafeReader& reader, short version);
|
|
|
|
void readFeatureX1(SafeReader& reader, short version);
|
2023-10-13 00:52:44 +00:00
|
|
|
void readFeatureNE(SafeReader& reader, short version);
|
2023-10-14 11:10:37 +00:00
|
|
|
void readFeatureEF(SafeReader& reader, short version);
|
2022-11-20 09:01:14 +00:00
|
|
|
|
2022-11-20 08:24:23 +00:00
|
|
|
DivDataErrors readInsDataOld(SafeReader& reader, short version);
|
2022-11-20 09:01:14 +00:00
|
|
|
DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song);
|
2023-10-29 07:43:38 +00:00
|
|
|
|
|
|
|
void convertC64SpecialMacro();
|
2022-01-22 05:14:48 +00:00
|
|
|
|
2022-03-16 03:05:55 +00:00
|
|
|
/**
|
|
|
|
* save the instrument to a SafeWriter.
|
|
|
|
* @param w the SafeWriter in question.
|
|
|
|
*/
|
2022-01-19 08:28:29 +00:00
|
|
|
void putInsData(SafeWriter* w);
|
2022-03-16 03:05:55 +00:00
|
|
|
|
2022-11-18 00:07:40 +00:00
|
|
|
/**
|
|
|
|
* save the instrument to a SafeWriter using new format.
|
|
|
|
* @param w the SafeWriter in question.
|
|
|
|
*/
|
2023-09-16 23:15:03 +00:00
|
|
|
void putInsData2(SafeWriter* w, bool fui=false, const DivSong* song=NULL, bool insName=true);
|
2022-11-18 00:07:40 +00:00
|
|
|
|
2022-03-16 03:05:55 +00:00
|
|
|
/**
|
|
|
|
* read instrument data in .fui format.
|
|
|
|
* @param reader the reader.
|
|
|
|
* @param version the format version.
|
|
|
|
* @return a DivDataErrors.
|
|
|
|
*/
|
2022-11-20 09:01:14 +00:00
|
|
|
DivDataErrors readInsData(SafeReader& reader, short version, DivSong* song=NULL);
|
2022-03-16 03:05:55 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* save this instrument to a file.
|
|
|
|
* @param path file path.
|
2022-11-21 00:19:24 +00:00
|
|
|
* @param oldFormat whether to save in legacy Furnace ins format.
|
|
|
|
* @param song if new format, a DivSong to read wavetables and samples.
|
2023-09-16 23:15:03 +00:00
|
|
|
* @param writeInsName whether to write the instrument name or not. ignored if old format.
|
2022-03-16 03:05:55 +00:00
|
|
|
* @return whether it was successful.
|
|
|
|
*/
|
2023-09-16 23:15:03 +00:00
|
|
|
bool save(const char* path, bool oldFormat=false, DivSong* song=NULL, bool writeInsName=true);
|
2022-08-13 20:43:13 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* save this instrument to a file in .dmp format.
|
|
|
|
* @param path file path.
|
|
|
|
* @return whether it was successful.
|
|
|
|
*/
|
|
|
|
bool saveDMP(const char* path);
|
2021-05-17 01:49:54 +00:00
|
|
|
DivInstrument():
|
|
|
|
name(""),
|
2022-03-31 06:51:57 +00:00
|
|
|
type(DIV_INS_FM) {
|
2021-05-17 01:49:54 +00:00
|
|
|
}
|
2021-05-11 20:08:08 +00:00
|
|
|
};
|
2021-05-15 21:42:48 +00:00
|
|
|
#endif
|