furnace/src/engine/song.h

628 lines
16 KiB
C
Raw Normal View History

2022-02-14 22:12:20 -05:00
/**
* Furnace Tracker - multi-system chiptune tracker
2024-01-16 21:26:57 -05:00
* Copyright (C) 2021-2024 tildearrow and contributors
2022-02-14 22:12:20 -05: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.
*/
2022-01-27 00:29:16 -05:00
#ifndef _SONG_H
#define _SONG_H
#include <stdio.h>
2023-09-20 01:24:55 -04:00
#include "../pch.h"
2022-01-08 01:57:37 -05:00
#include "defines.h"
#include "../ta-utils.h"
#include "config.h"
#include "orders.h"
#include "instrument.h"
#include "pattern.h"
#include "wavetable.h"
#include "sample.h"
enum DivSystem {
DIV_SYSTEM_NULL=0,
DIV_SYSTEM_YMU759,
DIV_SYSTEM_GENESIS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GENESIS_EXT, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_SMS,
DIV_SYSTEM_SMS_OPLL, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_GB,
DIV_SYSTEM_PCE,
DIV_SYSTEM_NES,
2022-02-23 21:53:07 -05:00
DIV_SYSTEM_NES_VRC7, // ** COMPOUND SYSTEM - DO NOT USE! **
2022-04-03 18:14:12 -04:00
DIV_SYSTEM_NES_FDS, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_C64_6581,
DIV_SYSTEM_C64_8580,
DIV_SYSTEM_ARCADE, // ** COMPOUND SYSTEM - DO NOT USE! **
DIV_SYSTEM_YM2610,
2022-01-12 22:58:51 -05:00
DIV_SYSTEM_YM2610_EXT,
DIV_SYSTEM_AY8910,
DIV_SYSTEM_AMIGA,
DIV_SYSTEM_YM2151,
2022-12-20 17:55:05 -05:00
DIV_SYSTEM_YM2612,
2022-01-12 22:58:51 -05:00
DIV_SYSTEM_TIA,
2022-01-14 00:02:10 -05:00
DIV_SYSTEM_SAA1099,
2022-02-02 15:29:20 -05:00
DIV_SYSTEM_AY8930,
DIV_SYSTEM_VIC20,
DIV_SYSTEM_PET,
DIV_SYSTEM_SNES,
2022-02-02 18:24:33 -05:00
DIV_SYSTEM_VRC6,
2022-02-02 15:29:20 -05:00
DIV_SYSTEM_OPLL,
DIV_SYSTEM_FDS,
DIV_SYSTEM_MMC5,
DIV_SYSTEM_N163,
DIV_SYSTEM_YM2203,
DIV_SYSTEM_YM2203_EXT,
DIV_SYSTEM_YM2608,
DIV_SYSTEM_YM2608_EXT,
2022-02-02 15:29:20 -05:00
DIV_SYSTEM_OPL,
DIV_SYSTEM_OPL2,
DIV_SYSTEM_OPL3,
DIV_SYSTEM_MULTIPCM,
DIV_SYSTEM_PCSPKR,
DIV_SYSTEM_POKEY,
DIV_SYSTEM_RF5C68,
DIV_SYSTEM_SWAN,
DIV_SYSTEM_OPZ,
DIV_SYSTEM_POKEMINI,
DIV_SYSTEM_SEGAPCM,
DIV_SYSTEM_VBOY,
DIV_SYSTEM_VRC7,
DIV_SYSTEM_YM2610B,
DIV_SYSTEM_SFX_BEEPER,
2023-03-05 12:58:27 -05:00
DIV_SYSTEM_SFX_BEEPER_QUADTONE,
2022-12-20 17:55:05 -05:00
DIV_SYSTEM_YM2612_EXT,
2022-02-02 18:24:33 -05:00
DIV_SYSTEM_SCC,
DIV_SYSTEM_OPL_DRUMS,
DIV_SYSTEM_OPL2_DRUMS,
DIV_SYSTEM_OPL3_DRUMS,
DIV_SYSTEM_YM2610_FULL,
DIV_SYSTEM_YM2610_FULL_EXT,
2022-02-02 18:24:33 -05:00
DIV_SYSTEM_OPLL_DRUMS,
DIV_SYSTEM_LYNX,
DIV_SYSTEM_QSOUND,
2022-03-04 06:13:49 -05:00
DIV_SYSTEM_VERA,
DIV_SYSTEM_YM2610B_EXT,
2022-03-04 06:13:49 -05:00
DIV_SYSTEM_SEGAPCM_COMPAT,
DIV_SYSTEM_X1_010,
DIV_SYSTEM_BUBSYS_WSG,
DIV_SYSTEM_OPL4,
DIV_SYSTEM_OPL4_DRUMS,
DIV_SYSTEM_ES5506,
DIV_SYSTEM_Y8950,
DIV_SYSTEM_Y8950_DRUMS,
DIV_SYSTEM_SCC_PLUS,
DIV_SYSTEM_SOUND_UNIT,
DIV_SYSTEM_MSM6295,
DIV_SYSTEM_MSM6258,
2022-05-18 02:55:33 -04:00
DIV_SYSTEM_YMZ280B,
DIV_SYSTEM_NAMCO,
DIV_SYSTEM_NAMCO_15XX,
DIV_SYSTEM_NAMCO_CUS30,
2022-12-20 17:55:05 -05:00
DIV_SYSTEM_YM2612_DUALPCM,
DIV_SYSTEM_YM2612_DUALPCM_EXT,
2022-10-01 00:22:26 -04:00
DIV_SYSTEM_MSM5232,
DIV_SYSTEM_T6W28,
DIV_SYSTEM_K007232,
DIV_SYSTEM_GA20,
DIV_SYSTEM_PCM_DAC,
2022-10-24 04:19:42 -04:00
DIV_SYSTEM_PONG,
2022-12-20 17:40:45 -05:00
DIV_SYSTEM_DUMMY,
2022-12-20 17:55:05 -05:00
DIV_SYSTEM_YM2612_CSM,
2022-12-20 17:40:45 -05:00
DIV_SYSTEM_YM2610_CSM,
DIV_SYSTEM_YM2610B_CSM,
DIV_SYSTEM_YM2203_CSM,
2023-02-11 07:37:11 -05:00
DIV_SYSTEM_YM2608_CSM,
DIV_SYSTEM_SM8521,
2023-04-02 01:32:47 -04:00
DIV_SYSTEM_PV1000,
2023-07-23 05:42:38 -04:00
DIV_SYSTEM_K053260,
2023-08-09 07:30:00 -04:00
DIV_SYSTEM_TED,
2023-08-27 19:46:10 -04:00
DIV_SYSTEM_C140,
DIV_SYSTEM_C219,
2024-01-21 06:44:29 -05:00
DIV_SYSTEM_ESFM,
2024-01-24 03:15:41 -05:00
DIV_SYSTEM_POWERNOISE,
DIV_SYSTEM_DAVE,
DIV_SYSTEM_NDS,
2024-03-16 03:59:02 -04:00
DIV_SYSTEM_GBA_DMA,
DIV_SYSTEM_GBA_MINMOD,
2024-03-18 15:22:05 -04:00
DIV_SYSTEM_5E01,
2024-04-01 05:29:43 -04:00
DIV_SYSTEM_BIFURCATOR,
2024-04-21 04:54:34 -04:00
DIV_SYSTEM_SID2,
2024-08-15 12:27:30 -04:00
DIV_SYSTEM_MAX
};
2023-05-21 05:39:36 -04:00
enum DivEffectType: unsigned short {
DIV_EFFECT_NULL=0,
DIV_EFFECT_DUMMY,
DIV_EFFECT_EXTERNAL,
DIV_EFFECT_VOLUME,
DIV_EFFECT_FILTER
};
2023-02-05 02:56:39 -05:00
struct DivGroovePattern {
unsigned char val[16];
unsigned char len;
DivGroovePattern():
len(1) {
memset(val,6,16);
}
};
struct DivSubSong {
String name, notes;
unsigned char hilightA, hilightB;
2023-02-05 02:56:39 -05:00
unsigned char timeBase, arpLen;
DivGroovePattern speeds;
2022-05-18 01:05:25 -04:00
short virtualTempoN, virtualTempoD;
float hz;
int patLen, ordersLen;
DivOrders orders;
DivChannelData pat[DIV_MAX_CHANS];
bool chanShow[DIV_MAX_CHANS];
2023-11-15 09:21:01 -05:00
bool chanShowChanOsc[DIV_MAX_CHANS];
unsigned char chanCollapse[DIV_MAX_CHANS];
String chanName[DIV_MAX_CHANS];
String chanShortName[DIV_MAX_CHANS];
2024-06-26 05:03:49 -04:00
/**
* walk through the song and determine loop position.
*/
bool walk(int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0);
/**
* find song length in rows (up to specified loop point). Also find length of every row
*/
2024-08-20 15:08:24 -04:00
void findLength(bool& hasFFxx, std::vector<int>& orders, int& length, int& loopOrder, int& loopRow, int& loopEnd, int chans, int jumpTreatment, int ignoreJumpAtEnd, int firstPat=0);
void clearData();
2022-08-16 04:19:16 -04:00
void optimizePatterns();
void rearrangePatterns();
void sortOrders();
void makePatUnique();
DivSubSong():
hilightA(4),
hilightB(16),
timeBase(0),
arpLen(1),
2022-05-18 01:05:25 -04:00
virtualTempoN(150),
virtualTempoD(150),
hz(60.0),
patLen(64),
ordersLen(1) {
for (int i=0; i<DIV_MAX_CHANS; i++) {
chanShow[i]=true;
chanShowChanOsc[i]=true;
chanCollapse[i]=0;
}
}
};
2023-03-12 05:10:46 -04:00
struct DivAssetDir {
String name;
std::vector<int> entries;
DivAssetDir():
name("New Directory") {}
DivAssetDir(String n):
name(n) {}
};
2023-05-21 05:39:36 -04:00
struct DivEffectStorage {
DivEffectType id;
unsigned short slot, storageVer;
float dryWet;
unsigned char* storage;
size_t storageLen;
DivEffectStorage():
id(DIV_EFFECT_NULL),
slot(0),
storageVer(0),
dryWet(1.0f),
storage(NULL),
storageLen(0) {}
};
struct DivSong {
unsigned short version;
bool isDMF;
// system
DivSystem system[DIV_MAX_CHIPS];
unsigned char systemLen;
float systemVol[DIV_MAX_CHIPS];
float systemPan[DIV_MAX_CHIPS];
float systemPanFR[DIV_MAX_CHIPS];
DivConfig systemFlags[DIV_MAX_CHIPS];
// song information
String name, author, systemName;
// legacy song information
2022-04-12 16:39:01 -04:00
// those will be stored in .fur and mapped to VGM as:
// category -> game name
// writer -> ripper
// createdDate -> year
String carrier, composer, vendor, category, writer, arranger, copyright, manGroup, manInfo, createdDate, revisionDate;
2022-04-12 16:39:01 -04:00
// more VGM specific stuff
String nameJ, authorJ, categoryJ, systemNameJ;
2022-04-12 16:39:01 -04:00
// other things
String notes;
// module details
int insLen, waveLen, sampleLen;
float masterVol;
float tuning;
2022-01-22 15:30:23 -05:00
// compatibility flags
bool limitSlides;
// linear pitch
// 0: not linear
// 1: only pitch changes (04xy/E5xx) linear
// 2: full linear
unsigned char linearPitch;
unsigned char pitchSlideSpeed;
// loop behavior
// 0: reset on loop
// 1: fake reset on loop
// 2: don't do anything on loop
unsigned char loopModality;
// cut/delay effect behavior
// 0: strict (don't allow value higher than or equal to speed)
// 1: broken (don't allow value higher than speed)
// 2: lax (allow value higher than speed)
unsigned char delayBehavior;
2022-09-10 02:39:42 -04:00
// 0B/0D treatment
// 0: normal (0B/0D accepted)
// 1: old Furnace (first one accepted)
// 2: DefleMask (0D takes priority over 0B)
unsigned char jumpTreatment;
bool properNoiseLayout;
bool waveDutyIsVol;
bool resetMacroOnPorta;
bool legacyVolumeSlides;
bool compatibleArpeggio;
bool noteOffResetsSlides;
bool targetResetsSlides;
bool arpNonPorta;
bool algMacroBehavior;
2022-02-18 01:27:26 -05:00
bool brokenShortcutSlides;
bool ignoreDuplicateSlides;
bool stopPortaOnNoteOff;
bool continuousVibrato;
bool brokenDACMode;
2022-03-11 23:01:18 -05:00
bool oneTickCut;
2022-03-14 02:23:31 -04:00
bool newInsTriggersInPorta;
bool arp0Reset;
bool brokenSpeedSel;
bool noSlidesOnFirstTick;
bool rowResetsArpPos;
bool ignoreJumpAtEnd;
2022-03-26 23:15:15 -04:00
bool buggyPortaAfterSlide;
bool gbInsAffectsEnvelope;
bool sharedExtStat;
bool ignoreDACModeOutsideIntendedChannel;
bool e1e2AlsoTakePriority;
bool newSegaPCM;
2022-04-24 15:40:07 -04:00
bool fbPortaPause;
2022-04-24 19:12:18 -04:00
bool snDutyReset;
2022-04-28 01:26:21 -04:00
bool pitchMacroIsLinear;
bool oldOctaveBoundary;
bool noOPN2Vol;
bool newVolumeScaling;
bool volMacroLinger;
bool brokenOutVol;
bool brokenOutVol2;
bool e1e2StopOnSameNote;
2022-07-04 02:43:59 -04:00
bool brokenPortaArp;
bool snNoLowPeriods;
bool disableSampleMacro;
2022-09-21 20:27:42 -04:00
bool autoSystem;
2022-12-17 01:21:08 -05:00
bool oldArpStrategy;
2023-01-10 15:58:15 -05:00
bool patchbayAuto;
2023-01-17 01:58:59 -05:00
bool brokenPortaLegato;
bool brokenFMOff;
2023-08-23 13:50:22 -04:00
bool preNoteNoEffect;
2023-10-13 20:57:36 -04:00
bool oldDPCM;
bool resetArpPhaseOnNewNote;
bool ceilVolumeScaling;
bool oldAlwaysSetVolume;
bool oldSampleOffset;
2022-01-22 15:30:23 -05:00
std::vector<DivInstrument*> ins;
std::vector<DivWavetable*> wave;
std::vector<DivSample*> sample;
std::vector<DivSubSong*> subsong;
std::vector<unsigned int> patchbay;
2023-02-05 02:56:39 -05:00
std::vector<DivGroovePattern> grooves;
2023-03-12 05:10:46 -04:00
std::vector<DivAssetDir> insDir;
std::vector<DivAssetDir> waveDir;
std::vector<DivAssetDir> sampleDir;
2023-05-21 05:39:36 -04:00
std::vector<DivEffectStorage> effects;
DivInstrument nullIns, nullInsOPLL, nullInsOPL, nullInsOPLDrums, nullInsQSound, nullInsESFM;
DivWavetable nullWave;
2022-02-24 22:52:20 -05:00
DivSample nullSample;
/**
* find data past 0Bxx effects and place that into new sub-songs.
*/
2024-06-26 05:03:49 -04:00
void findSubSongs(int chans);
2022-04-24 18:39:18 -04:00
/**
* clear orders and patterns.
*/
void clearSongData();
/**
* clear instruments.
*/
void clearInstruments();
/**
* clear wavetables.
*/
void clearWavetables();
/**
* clear samples.
*/
void clearSamples();
2022-03-15 23:05:55 -04:00
/**
* unloads the song, freeing all memory associated with it.
* use before destroying the object.
*/
void unload();
DivSong():
version(0),
isDMF(false),
systemLen(2),
name(""),
author(""),
systemName(""),
carrier(""),
composer(""),
vendor(""),
category(""),
writer(""),
arranger(""),
copyright(""),
manGroup(""),
manInfo(""),
createdDate(""),
revisionDate(""),
insLen(0),
waveLen(0),
2022-01-22 15:30:23 -05:00
sampleLen(0),
masterVol(1.0f),
tuning(440.0f),
limitSlides(false),
linearPitch(2),
pitchSlideSpeed(4),
2022-08-25 17:06:10 -04:00
loopModality(2),
delayBehavior(2),
2022-09-10 02:39:42 -04:00
jumpTreatment(0),
2022-08-11 03:05:05 -04:00
properNoiseLayout(true),
waveDutyIsVol(false),
resetMacroOnPorta(false),
legacyVolumeSlides(false),
compatibleArpeggio(false),
noteOffResetsSlides(true),
targetResetsSlides(true),
arpNonPorta(false),
2022-02-18 01:27:26 -05:00
algMacroBehavior(false),
brokenShortcutSlides(false),
ignoreDuplicateSlides(false),
stopPortaOnNoteOff(false),
continuousVibrato(false),
2022-03-11 23:01:18 -05:00
brokenDACMode(false),
2022-03-14 02:23:31 -04:00
oneTickCut(false),
newInsTriggersInPorta(true),
arp0Reset(true),
brokenSpeedSel(false),
noSlidesOnFirstTick(false),
rowResetsArpPos(false),
2022-03-26 23:15:15 -04:00
ignoreJumpAtEnd(false),
buggyPortaAfterSlide(false),
gbInsAffectsEnvelope(true),
sharedExtStat(true),
ignoreDACModeOutsideIntendedChannel(false),
e1e2AlsoTakePriority(false),
2022-04-24 15:40:07 -04:00
newSegaPCM(true),
2022-04-24 19:12:18 -04:00
fbPortaPause(false),
2022-04-28 01:26:21 -04:00
snDutyReset(false),
pitchMacroIsLinear(true),
oldOctaveBoundary(false),
noOPN2Vol(false),
newVolumeScaling(true),
volMacroLinger(true),
brokenOutVol(false),
brokenOutVol2(false),
2022-07-04 02:43:59 -04:00
e1e2StopOnSameNote(false),
brokenPortaArp(false),
2022-09-21 20:27:42 -04:00
snNoLowPeriods(false),
disableSampleMacro(false),
2022-12-17 01:21:08 -05:00
autoSystem(true),
2023-01-10 15:58:15 -05:00
oldArpStrategy(false),
2023-01-17 01:58:59 -05:00
patchbayAuto(true),
brokenPortaLegato(false),
2023-08-23 13:50:22 -04:00
brokenFMOff(false),
2023-10-13 20:57:36 -04:00
preNoteNoEffect(false),
oldDPCM(false),
resetArpPhaseOnNewNote(false),
ceilVolumeScaling(false),
oldAlwaysSetVolume(false),
oldSampleOffset(false) {
for (int i=0; i<DIV_MAX_CHIPS; i++) {
system[i]=DIV_SYSTEM_NULL;
systemVol[i]=1.0;
systemPan[i]=0.0;
systemPanFR[i]=0.0;
}
subsong.push_back(new DivSubSong);
2022-12-20 17:55:05 -05:00
system[0]=DIV_SYSTEM_YM2612;
system[1]=DIV_SYSTEM_SMS;
// OPLL default instrument contest winner - piano_guitar_idk by Weeppiko
nullInsOPLL.type=DIV_INS_OPLL;
2022-05-02 15:51:06 -04:00
nullInsOPLL.fm.opllPreset=0;
nullInsOPLL.fm.alg=0;
nullInsOPLL.fm.fb=7;
nullInsOPLL.fm.fms=1;
nullInsOPLL.fm.ams=0;
nullInsOPLL.fm.op[0].ar=15;
nullInsOPLL.fm.op[0].dr=5;
nullInsOPLL.fm.op[0].sl=3;
nullInsOPLL.fm.op[0].rr=3;
nullInsOPLL.fm.op[0].tl=40;
nullInsOPLL.fm.op[0].ksl=0;
nullInsOPLL.fm.op[0].mult=5;
nullInsOPLL.fm.op[0].am=0;
nullInsOPLL.fm.op[0].vib=1;
nullInsOPLL.fm.op[0].ksr=0;
nullInsOPLL.fm.op[0].ssgEnv=8;
nullInsOPLL.fm.op[1].ar=15;
nullInsOPLL.fm.op[1].dr=1;
nullInsOPLL.fm.op[1].sl=11;
nullInsOPLL.fm.op[1].rr=6;
nullInsOPLL.fm.op[1].tl=0;
nullInsOPLL.fm.op[1].ksl=0;
nullInsOPLL.fm.op[1].mult=1;
nullInsOPLL.fm.op[1].am=0;
nullInsOPLL.fm.op[1].vib=0;
nullInsOPLL.fm.op[1].ksr=0;
nullInsOPLL.fm.op[1].ssgEnv=8;
nullInsOPLL.name="This is a bug! Report!";
nullInsOPL.type=DIV_INS_OPL;
nullInsOPL.fm.alg=0;
nullInsOPL.fm.fb=7;
nullInsOPL.fm.op[0].dr=2;
nullInsOPL.fm.op[0].rr=7;
nullInsOPL.fm.op[0].tl=22;
nullInsOPL.fm.op[0].ksl=1;
nullInsOPL.fm.op[0].mult=3;
nullInsOPL.fm.op[1].tl=0;
nullInsOPL.fm.op[1].dr=3;
nullInsOPL.fm.op[1].rr=12;
nullInsOPL.fm.op[1].mult=1;
nullInsOPL.name="This is a bug! Report!";
nullInsOPL.fm.kickFreq=(1<<10)|576;
nullInsOPL.fm.snareHatFreq=(1<<10)|672;
nullInsOPL.fm.tomTopFreq=896;
nullInsOPLDrums=nullInsOPL;
nullInsOPLDrums.type=DIV_INS_OPL_DRUMS;
nullInsOPLDrums.fm.fixedDrums=true;
for (int i=0; i<4; i++) {
nullInsOPLDrums.fm.op[i].am=0;
nullInsOPLDrums.fm.op[i].vib=0;
nullInsOPLDrums.fm.op[i].ksr=0;
nullInsOPLDrums.fm.op[i].sus=0;
nullInsOPLDrums.fm.op[i].ws=0;
nullInsOPLDrums.fm.op[i].ksl=0;
nullInsOPLDrums.fm.op[i].tl=0;
}
// snare
nullInsOPLDrums.fm.op[0].ar=13;
nullInsOPLDrums.fm.op[0].dr=8;
nullInsOPLDrums.fm.op[0].sl=4;
nullInsOPLDrums.fm.op[0].rr=8;
nullInsOPLDrums.fm.op[0].mult=1;
// tom
nullInsOPLDrums.fm.op[1].ar=15;
nullInsOPLDrums.fm.op[1].dr=8;
nullInsOPLDrums.fm.op[1].sl=5;
nullInsOPLDrums.fm.op[1].rr=9;
nullInsOPLDrums.fm.op[1].mult=5;
// top
nullInsOPLDrums.fm.op[2].ar=10;
nullInsOPLDrums.fm.op[2].dr=10;
nullInsOPLDrums.fm.op[2].sl=5;
nullInsOPLDrums.fm.op[2].rr=5;
nullInsOPLDrums.fm.op[2].mult=1;
nullInsOPLDrums.fm.op[2].ksr=1;
// hi-hat
nullInsOPLDrums.fm.op[3].ar=12;
nullInsOPLDrums.fm.op[3].dr=8;
nullInsOPLDrums.fm.op[3].sl=10;
nullInsOPLDrums.fm.op[3].rr=7;
nullInsOPLDrums.fm.op[3].mult=2;
nullInsQSound.std.panLMacro.mode=true;
// ESFM default instrument - port of OPN default instrument
nullInsESFM.esfm.noise=0;
nullInsESFM.esfm.op[0].outLvl=0;
nullInsESFM.esfm.op[0].modIn=4;
nullInsESFM.esfm.op[0].dt=2;
nullInsESFM.fm.op[0].tl=42;
nullInsESFM.fm.op[0].ar=15;
nullInsESFM.fm.op[0].dr=3;
nullInsESFM.fm.op[0].sl=15;
nullInsESFM.fm.op[0].rr=3;
nullInsESFM.fm.op[0].mult=5;
nullInsESFM.esfm.op[1].outLvl=0;
nullInsESFM.esfm.op[1].modIn=7;
nullInsESFM.esfm.op[1].dt=-3;
nullInsESFM.fm.op[1].tl=18;
nullInsESFM.fm.op[1].ar=15;
nullInsESFM.fm.op[1].dr=3;
nullInsESFM.fm.op[1].sl=15;
nullInsESFM.fm.op[1].rr=4;
nullInsESFM.fm.op[1].mult=1;
nullInsESFM.esfm.op[2].outLvl=0;
nullInsESFM.esfm.op[2].modIn=7;
nullInsESFM.esfm.op[2].dt=2;
nullInsESFM.fm.op[2].tl=48;
nullInsESFM.fm.op[2].ar=15;
nullInsESFM.fm.op[2].dr=2;
nullInsESFM.fm.op[2].sl=11;
nullInsESFM.fm.op[2].rr=1;
nullInsESFM.fm.op[2].mult=1;
nullInsESFM.fm.op[2].sus=1;
nullInsESFM.esfm.op[3].outLvl=7;
nullInsESFM.esfm.op[3].modIn=7;
nullInsESFM.esfm.op[3].dt=-3;
nullInsESFM.fm.op[3].tl=0;
nullInsESFM.fm.op[3].ar=15;
nullInsESFM.fm.op[3].dr=3;
nullInsESFM.fm.op[3].sl=15;
nullInsESFM.fm.op[3].rr=9;
nullInsESFM.fm.op[3].mult=1;
}
};
2022-01-27 00:29:16 -05:00
2022-02-02 15:29:20 -05:00
#endif