giga-refactor, part 1
This commit is contained in:
parent
2f25acd017
commit
a654d33df2
13 changed files with 102 additions and 86 deletions
|
|
@ -2091,46 +2091,6 @@ const char** DivEngine::getRegisterSheet(int sys) {
|
|||
return disCont[sys].dispatch->getRegisterSheet();
|
||||
}
|
||||
|
||||
void DivEngine::recalcChans() {
|
||||
bool isInsTypePossible[DIV_INS_MAX];
|
||||
chans=0;
|
||||
int chanIndex=0;
|
||||
memset(isInsTypePossible,0,DIV_INS_MAX*sizeof(bool));
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
int chanCount=song.systemChans[i];
|
||||
int firstChan=chans;
|
||||
chans+=chanCount;
|
||||
for (int j=0; j<chanCount; j++) {
|
||||
sysOfChan[chanIndex]=song.system[i];
|
||||
dispatchOfChan[chanIndex]=i;
|
||||
dispatchChanOfChan[chanIndex]=j;
|
||||
dispatchFirstChan[chanIndex]=firstChan;
|
||||
chanIndex++;
|
||||
|
||||
if (sysDefs[song.system[i]]!=NULL) {
|
||||
if (sysDefs[song.system[i]]->chanInsType[j][0]!=DIV_INS_NULL) {
|
||||
isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][0]]=true;
|
||||
}
|
||||
|
||||
if (sysDefs[song.system[i]]->chanInsType[j][1]!=DIV_INS_NULL) {
|
||||
isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][1]]=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
possibleInsTypes.clear();
|
||||
for (int i=0; i<DIV_INS_MAX; i++) {
|
||||
if (isInsTypePossible[i]) possibleInsTypes.push_back((DivInstrumentType)i);
|
||||
}
|
||||
|
||||
checkAssetDir(song.insDir,song.ins.size());
|
||||
checkAssetDir(song.waveDir,song.wave.size());
|
||||
checkAssetDir(song.sampleDir,song.sample.size());
|
||||
|
||||
hasLoadedSomething=true;
|
||||
}
|
||||
|
||||
void DivEngine::reset() {
|
||||
if (output) if (output->midiOut!=NULL) {
|
||||
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));
|
||||
|
|
|
|||
|
|
@ -463,7 +463,6 @@ class DivEngine {
|
|||
TAAudioDesc want, got;
|
||||
String exportPath;
|
||||
std::thread* exportThread;
|
||||
int chans;
|
||||
bool configLoaded;
|
||||
bool active;
|
||||
bool lowQuality;
|
||||
|
|
@ -546,7 +545,6 @@ class DivEngine {
|
|||
std::vector<String> midiIns;
|
||||
std::vector<String> midiOuts;
|
||||
std::vector<DivCommand> cmdStream;
|
||||
std::vector<DivInstrumentType> possibleInsTypes;
|
||||
std::vector<DivEffectContainer> effectInst;
|
||||
std::vector<int> curChanMask;
|
||||
static DivSysDef* sysDefs[DIV_MAX_CHIP_DEFS];
|
||||
|
|
@ -625,7 +623,6 @@ class DivEngine {
|
|||
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
|
||||
bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal);
|
||||
bool perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal);
|
||||
void recalcChans();
|
||||
void reset();
|
||||
void playSub(bool preserveDrift, int goalRow=0);
|
||||
void runMidiClock(int totalCycles=1);
|
||||
|
|
@ -716,10 +713,6 @@ class DivEngine {
|
|||
DivChannelData* curPat;
|
||||
DivSubSong* curSubSong;
|
||||
DivInstrument* tempIns;
|
||||
DivSystem sysOfChan[DIV_MAX_CHANS];
|
||||
int dispatchOfChan[DIV_MAX_CHANS];
|
||||
int dispatchChanOfChan[DIV_MAX_CHANS];
|
||||
int dispatchFirstChan[DIV_MAX_CHANS];
|
||||
bool keyHit[DIV_MAX_CHANS];
|
||||
float* oscBuf[DIV_MAX_OUTPUTS];
|
||||
float oscSize;
|
||||
|
|
@ -953,7 +946,7 @@ class DivEngine {
|
|||
const char* getSystemNameJ(DivSystem sys);
|
||||
|
||||
// get sys definition
|
||||
const DivSysDef* getSystemDef(DivSystem sys);
|
||||
static const DivSysDef* getSystemDef(DivSystem sys);
|
||||
|
||||
// get ROM export definition
|
||||
const DivROMExportDef* getROMExportDef(DivROMExportOptions opt);
|
||||
|
|
@ -1456,7 +1449,6 @@ class DivEngine {
|
|||
DivEngine():
|
||||
output(NULL),
|
||||
exportThread(NULL),
|
||||
chans(0),
|
||||
configLoaded(false),
|
||||
active(false),
|
||||
lowQuality(false),
|
||||
|
|
@ -1591,10 +1583,6 @@ class DivEngine {
|
|||
mu5ROM(NULL) {
|
||||
memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool));
|
||||
memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool));
|
||||
memset(dispatchFirstChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(vibTable,0,64*sizeof(short));
|
||||
memset(tremTable,0,128*sizeof(short));
|
||||
memset(effectSlotMap,-1,4096*sizeof(short));
|
||||
|
|
|
|||
|
|
@ -1168,6 +1168,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0));
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
|
|
@ -1175,7 +1176,6 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
// always convert to normal sample mode (I have no idea how will I do export)
|
||||
convertLegacySampleMode();
|
||||
saveLock.unlock();
|
||||
|
|
@ -1289,7 +1289,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
lastError="maximum number of wavetables in .dmf is 64";
|
||||
return NULL;
|
||||
}
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (int j=0; j<curSubSong->ordersLen; j++) {
|
||||
if (curOrders->ord[i][j]>0x7f) {
|
||||
logE("order %d, %d is out of range (0-127)!",i,j);
|
||||
|
|
@ -1356,7 +1356,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
w->writeI(curSubSong->patLen);
|
||||
w->writeC(curSubSong->ordersLen);
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (int j=0; j<curSubSong->ordersLen; j++) {
|
||||
w->writeC(curOrders->ord[i][j]);
|
||||
if (version>=25) {
|
||||
|
|
|
|||
|
|
@ -664,6 +664,8 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
ds.subsong[0]->optimizePatterns();
|
||||
ds.subsong[0]->rearrangePatterns();
|
||||
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
|
|
|
|||
|
|
@ -2802,13 +2802,14 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
}
|
||||
}
|
||||
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -2129,6 +2129,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
} else if (ds.version<237 && ds.linearPitch!=0) {
|
||||
addWarning("this song used partial pitch linearity, which has been removed from Furnace. you may have to adjust your song.");
|
||||
}
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
|
|
@ -2136,7 +2137,6 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
// removal of legacy sample mode
|
||||
if (song.version<239) {
|
||||
if (convertLegacySampleMode()) {
|
||||
|
|
@ -2242,7 +2242,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
// low short is pattern number
|
||||
std::vector<PatToWrite> patsToWrite;
|
||||
if (getConfInt("saveUnusedPatterns",0)==1) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (size_t j=0; j<song.subsong.size(); j++) {
|
||||
DivSubSong* subs=song.subsong[j];
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
|
|
@ -2253,7 +2253,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
}
|
||||
} else {
|
||||
bool alreadyAdded[DIV_MAX_PATTERNS];
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (size_t j=0; j<song.subsong.size(); j++) {
|
||||
DivSubSong* subs=song.subsong[j];
|
||||
memset(alreadyAdded,0,DIV_MAX_PATTERNS*sizeof(bool));
|
||||
|
|
@ -2358,32 +2358,32 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeI(0);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (int j=0; j<subSong->ordersLen; j++) {
|
||||
w->writeC(subSong->orders.ord[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(subSong->pat[i].effectCols);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(
|
||||
(subSong->chanShow[i]?1:0)|
|
||||
(subSong->chanShowChanOsc[i]?2:0)
|
||||
);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(subSong->chanCollapse[i]);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeString(subSong->chanName[i],false);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeString(subSong->chanShortName[i],false);
|
||||
}
|
||||
|
||||
|
|
@ -2518,32 +2518,32 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
|||
w->writeString(subSong->name,false);
|
||||
w->writeString(subSong->notes,false);
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (int j=0; j<subSong->ordersLen; j++) {
|
||||
w->writeC(subSong->orders.ord[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(subSong->pat[i].effectCols);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(
|
||||
(subSong->chanShow[i]?1:0)|
|
||||
(subSong->chanShowChanOsc[i]?2:0)
|
||||
);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(subSong->chanCollapse[i]);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeString(subSong->chanName[i],false);
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeString(subSong->chanShortName[i],false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1675,7 +1675,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
ds.systemName="PC";
|
||||
|
||||
// find subsongs
|
||||
ds.findSubSongs(maxChan);
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
// populate subsongs with default panning values
|
||||
for (size_t i=0; i<ds.subsong.size(); i++) {
|
||||
|
|
@ -1708,7 +1709,6 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -431,7 +431,8 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
ds.insLen=ds.ins.size();
|
||||
|
||||
// find subsongs
|
||||
ds.findSubSongs(chCount);
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
|
|
@ -439,7 +440,6 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -1179,7 +1179,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
// find subsongs
|
||||
ds.findSubSongs(DIV_MAX_CHANS);
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
// populate subsongs with default panning values
|
||||
if (masterVol&128) { // only in stereo mode
|
||||
|
|
@ -1215,7 +1216,6 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -704,13 +704,14 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) {
|
|||
info.loopPos=loopPos;
|
||||
TFMParsePattern(info);
|
||||
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
@ -904,13 +905,14 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) {
|
|||
info.loopPos=loopPos;
|
||||
TFMParsePattern(info);
|
||||
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -1377,7 +1377,8 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
// find subsongs
|
||||
ds.findSubSongs(totalChans);
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
if (active) quitDispatch();
|
||||
BUSY_BEGIN_SOFT;
|
||||
|
|
@ -1385,7 +1386,6 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
|
|||
song.unload();
|
||||
song=ds;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ void DivSubSong::makePatUnique() {
|
|||
}
|
||||
}
|
||||
|
||||
void DivSong::findSubSongs(int chans) {
|
||||
void DivSong::findSubSongs() {
|
||||
std::vector<DivSubSong*> newSubSongs;
|
||||
for (DivSubSong* i: subsong) {
|
||||
std::vector<int> subSongStart;
|
||||
|
|
@ -689,9 +689,50 @@ void DivSong::findSubSongs(int chans) {
|
|||
for (DivSubSong* i: newSubSongs) {
|
||||
subsong.push_back(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DivSong::recalcChans() {
|
||||
bool isInsTypePossible[DIV_INS_MAX];
|
||||
chans=0;
|
||||
int chanIndex=0;
|
||||
memset(isInsTypePossible,0,DIV_INS_MAX*sizeof(bool));
|
||||
for (int i=0; i<systemLen; i++) {
|
||||
int chanCount=systemChans[i];
|
||||
int firstChan=chans;
|
||||
chans+=chanCount;
|
||||
for (int j=0; j<chanCount; j++) {
|
||||
sysOfChan[chanIndex]=system[i];
|
||||
dispatchOfChan[chanIndex]=i;
|
||||
dispatchChanOfChan[chanIndex]=j;
|
||||
dispatchFirstChan[chanIndex]=firstChan;
|
||||
chanIndex++;
|
||||
|
||||
DivSysDef* sysDef=DivEngine::getSystemDef(system[i]);
|
||||
if (sysDef!=NULL) {
|
||||
if (sysDef->chanInsType[j][0]!=DIV_INS_NULL) {
|
||||
isInsTypePossible[sysDef->chanInsType[j][0]]=true;
|
||||
}
|
||||
|
||||
if (sysDef->chanInsType[j][1]!=DIV_INS_NULL) {
|
||||
isInsTypePossible[sysDef->chanInsType[j][1]]=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
possibleInsTypes.clear();
|
||||
for (int i=0; i<DIV_INS_MAX; i++) {
|
||||
if (isInsTypePossible[i]) possibleInsTypes.push_back((DivInstrumentType)i);
|
||||
}
|
||||
|
||||
checkAssetDir(insDir,ins.size());
|
||||
checkAssetDir(waveDir,wave.size());
|
||||
checkAssetDir(sampleDir,sample.size());
|
||||
|
||||
hasLoadedSomething=true;
|
||||
}
|
||||
|
||||
|
||||
void DivSong::clearSongData() {
|
||||
for (DivSubSong* i: subsong) {
|
||||
i->clearData();
|
||||
|
|
@ -749,4 +790,4 @@ void DivSong::unload() {
|
|||
delete i;
|
||||
}
|
||||
subsong.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ struct DivSong {
|
|||
bool isDMF;
|
||||
|
||||
// system
|
||||
int chans;
|
||||
DivSystem system[DIV_MAX_CHIPS];
|
||||
unsigned short systemChans[DIV_MAX_CHIPS];
|
||||
unsigned char systemLen;
|
||||
|
|
@ -396,10 +397,17 @@ struct DivSong {
|
|||
DivWavetable nullWave;
|
||||
DivSample nullSample;
|
||||
|
||||
DivSystem sysOfChan[DIV_MAX_CHANS];
|
||||
int dispatchOfChan[DIV_MAX_CHANS];
|
||||
int dispatchChanOfChan[DIV_MAX_CHANS];
|
||||
int dispatchFirstChan[DIV_MAX_CHANS];
|
||||
|
||||
std::vector<DivInstrumentType> possibleInsTypes;
|
||||
|
||||
/**
|
||||
* find data past 0Bxx effects and place that into new sub-songs.
|
||||
*/
|
||||
void findSubSongs(int chans);
|
||||
void findSubSongs();
|
||||
|
||||
/**
|
||||
* clear orders and patterns.
|
||||
|
|
@ -421,6 +429,12 @@ struct DivSong {
|
|||
*/
|
||||
void clearSamples();
|
||||
|
||||
/**
|
||||
* recalculate channel count and internal state.
|
||||
" call after editing system[] or systemChans[].
|
||||
*/
|
||||
void recalcChans();
|
||||
|
||||
/**
|
||||
* unloads the song, freeing all memory associated with it.
|
||||
* use before destroying the object.
|
||||
|
|
@ -430,6 +444,7 @@ struct DivSong {
|
|||
DivSong():
|
||||
version(0),
|
||||
isDMF(false),
|
||||
chans(0),
|
||||
systemLen(2),
|
||||
name(""),
|
||||
author(""),
|
||||
|
|
@ -508,6 +523,11 @@ struct DivSong {
|
|||
oldAlwaysSetVolume(false),
|
||||
oldSampleOffset(false),
|
||||
oldCenterRate(true) {
|
||||
memset(dispatchFirstChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int));
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHIPS; i++) {
|
||||
system[i]=DIV_SYSTEM_NULL;
|
||||
systemChans[i]=0;
|
||||
|
|
@ -654,6 +674,8 @@ struct DivSong {
|
|||
nullInsESFM.fm.op[3].sl=15;
|
||||
nullInsESFM.fm.op[3].rr=9;
|
||||
nullInsESFM.fm.op[3].mult=1;
|
||||
|
||||
recalcChans();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue