Merge branch 'master' of https://github.com/tildearrow/furnace into nmk112
This commit is contained in:
commit
e5b6f0b373
445 changed files with 8611 additions and 1776 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -233,6 +233,7 @@ bool DivCSPlayer::tick() {
|
|||
case DIV_CMD_AMIGA_PM:
|
||||
case DIV_CMD_MACRO_OFF:
|
||||
case DIV_CMD_MACRO_ON:
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
arg0=(unsigned char)stream.readC();
|
||||
break;
|
||||
case DIV_CMD_FM_TL:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -153,6 +153,7 @@ void writePackedCommandValues(SafeWriter* w, const DivCommand& c) {
|
|||
case DIV_CMD_AMIGA_PM:
|
||||
case DIV_CMD_MACRO_OFF:
|
||||
case DIV_CMD_MACRO_ON:
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
case DIV_CMD_HINT_ARP_TIME:
|
||||
w->writeC(1); // length
|
||||
w->writeC(c.value);
|
||||
|
|
@ -312,8 +313,6 @@ SafeWriter* DivEngine::saveCommand(bool binary) {
|
|||
for (DivCommand& i: cmdStream) {
|
||||
switch (i.cmd) {
|
||||
// strip away hinted/useless commands
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
break;
|
||||
case DIV_CMD_GET_VOLUME:
|
||||
break;
|
||||
case DIV_CMD_VOLUME:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -167,4 +167,8 @@ void DivEngine::setConf(String key, String value) {
|
|||
|
||||
bool DivEngine::hasConf(String key) {
|
||||
return conf.has(key);
|
||||
}
|
||||
}
|
||||
|
||||
DivConfig& DivEngine::getConfObject() {
|
||||
return conf;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -243,7 +243,12 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_C64_AD, // (value)
|
||||
DIV_CMD_C64_SR, // (value)
|
||||
|
||||
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
||||
DIV_CMD_ESFM_OP_PANNING, // (op, value)
|
||||
DIV_CMD_ESFM_OUTLVL, // (op, value)
|
||||
DIV_CMD_ESFM_MODIN, // (op, value)
|
||||
DIV_CMD_ESFM_ENV_DELAY, // (op, value)
|
||||
|
||||
DIV_CMD_MACRO_RESTART, // (which)
|
||||
|
||||
DIV_CMD_MAX
|
||||
};
|
||||
|
|
@ -594,10 +599,10 @@ class DivDispatch {
|
|||
/**
|
||||
* map MIDI velocity (from 0 to 127) to chip volume.
|
||||
* @param ch the chip channel. -1 means N/A.
|
||||
* @param vel input velocity.
|
||||
* @param vel input velocity, from 0.0 to 1.0.
|
||||
* @return output volume.
|
||||
*/
|
||||
virtual int mapVelocity(int ch, unsigned char vel);
|
||||
virtual int mapVelocity(int ch, float vel);
|
||||
|
||||
/**
|
||||
* get the lowest note in a portamento.
|
||||
|
|
@ -606,6 +611,13 @@ class DivDispatch {
|
|||
*/
|
||||
virtual int getPortaFloor(int ch);
|
||||
|
||||
/**
|
||||
* check whether to always set volume on volume change (even when same volume).
|
||||
* only for compatibility purposes!
|
||||
* @return truth.
|
||||
*/
|
||||
virtual bool getLegacyAlwaysSetVolume();
|
||||
|
||||
/**
|
||||
* get the required amplification level of this dispatch's output.
|
||||
* @return the amplification level.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -82,6 +82,7 @@
|
|||
#include "platform/ted.h"
|
||||
#include "platform/c140.h"
|
||||
#include "platform/pcmdac.h"
|
||||
#include "platform/esfm.h"
|
||||
#include "platform/dummy.h"
|
||||
#include "../ta-log.h"
|
||||
#include "song.h"
|
||||
|
|
@ -644,6 +645,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
|
|||
case DIV_SYSTEM_PCM_DAC:
|
||||
dispatch=new DivPlatformPCMDAC;
|
||||
break;
|
||||
case DIV_SYSTEM_ESFM:
|
||||
dispatch=new DivPlatformESFM;
|
||||
break;
|
||||
case DIV_SYSTEM_DUMMY:
|
||||
dispatch=new DivPlatformDummy;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -83,7 +83,7 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
case 0x82:
|
||||
return "82xx: Set panning (right channel)";
|
||||
case 0x88:
|
||||
return "88xx: Set panning (rear channels; x: left; y: right)";
|
||||
return "88xy: Set panning (rear channels; x: left; y: right)";
|
||||
break;
|
||||
case 0x89:
|
||||
return "89xx: Set panning (rear left channel)";
|
||||
|
|
@ -129,6 +129,8 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
return "F5xx: Disable macro (see manual)";
|
||||
case 0xf6:
|
||||
return "F6xx: Enable macro (see manual)";
|
||||
case 0xf7:
|
||||
return "F7xx: Restart macro (see manual)";
|
||||
case 0xf8:
|
||||
return "F8xx: Single tick volume slide up";
|
||||
case 0xf9:
|
||||
|
|
@ -1371,6 +1373,9 @@ DivInstrument* DivEngine::getIns(int index, DivInstrumentType fallbackType) {
|
|||
case DIV_INS_OPL_DRUMS:
|
||||
return &song.nullInsOPLDrums;
|
||||
break;
|
||||
case DIV_INS_ESFM:
|
||||
return &song.nullInsESFM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -2185,6 +2190,13 @@ int DivEngine::getMaxVolumeChan(int ch) {
|
|||
return chan[ch].volMax>>8;
|
||||
}
|
||||
|
||||
int DivEngine::mapVelocity(int ch, float vel) {
|
||||
if (ch<0) return 0;
|
||||
if (ch>=chans) return 0;
|
||||
if (disCont[dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->mapVelocity(dispatchChanOfChan[ch],vel);
|
||||
}
|
||||
|
||||
unsigned char DivEngine::getOrder() {
|
||||
return prevOrder;
|
||||
}
|
||||
|
|
@ -2402,6 +2414,9 @@ int DivEngine::addInstrument(int refChan, DivInstrumentType fallbackType) {
|
|||
case DIV_INS_OPL_DRUMS:
|
||||
*ins=song.nullInsOPLDrums;
|
||||
break;
|
||||
case DIV_INS_ESFM:
|
||||
*ins=song.nullInsESFM;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -3385,6 +3400,14 @@ void DivEngine::setMidiDirect(bool value) {
|
|||
midiIsDirect=value;
|
||||
}
|
||||
|
||||
void DivEngine::setMidiDirectProgram(bool value) {
|
||||
midiIsDirectProgram=value;
|
||||
}
|
||||
|
||||
void DivEngine::setMidiVolExp(float value) {
|
||||
midiVolExp=value;
|
||||
}
|
||||
|
||||
void DivEngine::setMidiCallback(std::function<int(const TAMidiMessage&)> what) {
|
||||
midiCallback=what;
|
||||
}
|
||||
|
|
@ -3449,6 +3472,12 @@ void DivEngine::rescanAudioDevices() {
|
|||
audioDevs.clear();
|
||||
if (output!=NULL) {
|
||||
audioDevs=output->listAudioDevices();
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::rescanMidiDevices() {
|
||||
if (output!=NULL) {
|
||||
logV("re-scanning midi...");
|
||||
if (output->midiIn!=NULL) {
|
||||
midiIns=output->midiIn->listDevices();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -54,8 +54,8 @@ class DivWorkPool;
|
|||
|
||||
#define DIV_UNSTABLE
|
||||
|
||||
#define DIV_VERSION "dev189"
|
||||
#define DIV_ENGINE_VERSION 189
|
||||
#define DIV_VERSION "dev191"
|
||||
#define DIV_ENGINE_VERSION 191
|
||||
// for imports
|
||||
#define DIV_VERSION_MOD 0xff01
|
||||
#define DIV_VERSION_FC 0xff02
|
||||
|
|
@ -176,16 +176,16 @@ struct DivNoteEvent {
|
|||
signed char channel;
|
||||
unsigned char ins;
|
||||
signed char note, volume;
|
||||
bool on, nop, pad1, pad2;
|
||||
DivNoteEvent(int c, int i, int n, int v, bool o):
|
||||
bool on, nop, insChange, fromMIDI;
|
||||
DivNoteEvent(int c, int i, int n, int v, bool o, bool ic=false, bool fm=false):
|
||||
channel(c),
|
||||
ins(i),
|
||||
note(n),
|
||||
volume(v),
|
||||
on(o),
|
||||
nop(false),
|
||||
pad1(false),
|
||||
pad2(false) {}
|
||||
insChange(ic),
|
||||
fromMIDI(fm) {}
|
||||
DivNoteEvent():
|
||||
channel(-1),
|
||||
ins(0),
|
||||
|
|
@ -193,8 +193,8 @@ struct DivNoteEvent {
|
|||
volume(-1),
|
||||
on(false),
|
||||
nop(true),
|
||||
pad1(false),
|
||||
pad2(false) {}
|
||||
insChange(false),
|
||||
fromMIDI(false) {}
|
||||
};
|
||||
|
||||
struct DivDispatchContainer {
|
||||
|
|
@ -415,6 +415,7 @@ class DivEngine {
|
|||
bool firstTick;
|
||||
bool skipping;
|
||||
bool midiIsDirect;
|
||||
bool midiIsDirectProgram;
|
||||
bool lowLatency;
|
||||
bool systemsRegistered;
|
||||
bool hasLoadedSomething;
|
||||
|
|
@ -423,6 +424,7 @@ class DivEngine {
|
|||
bool midiOutProgramChange;
|
||||
int midiOutMode;
|
||||
int midiOutTimeRate;
|
||||
float midiVolExp;
|
||||
int softLockCount;
|
||||
int subticks, ticks, curRow, curOrder, prevRow, prevOrder, remainingLoops, totalLoops, lastLoopPos, exportLoopCount, nextSpeed, elapsedBars, elapsedBeats, curSpeed;
|
||||
size_t curSubSongIndex;
|
||||
|
|
@ -700,6 +702,9 @@ class DivEngine {
|
|||
double getConfDouble(String key, double fallback);
|
||||
String getConfString(String key, String fallback);
|
||||
|
||||
// get config object
|
||||
DivConfig& getConfObject();
|
||||
|
||||
// set a config value
|
||||
void setConf(String key, bool value);
|
||||
void setConf(String key, int value);
|
||||
|
|
@ -850,6 +855,9 @@ class DivEngine {
|
|||
// get channel max volume
|
||||
int getMaxVolumeChan(int chan);
|
||||
|
||||
// map MIDI velocity to volume
|
||||
int mapVelocity(int ch, float vel);
|
||||
|
||||
// get current order
|
||||
unsigned char getOrder();
|
||||
|
||||
|
|
@ -946,7 +954,7 @@ class DivEngine {
|
|||
DivSample* sampleFromFile(const char* path);
|
||||
|
||||
// get raw sample
|
||||
DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles);
|
||||
DivSample* sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate);
|
||||
|
||||
// delete sample
|
||||
void delSample(int index);
|
||||
|
|
@ -1069,6 +1077,9 @@ class DivEngine {
|
|||
// rescan audio devices
|
||||
void rescanAudioDevices();
|
||||
|
||||
/** rescan midi devices */
|
||||
void rescanMidiDevices();
|
||||
|
||||
// set the console mode.
|
||||
void setConsoleMode(bool enable);
|
||||
|
||||
|
|
@ -1184,6 +1195,12 @@ class DivEngine {
|
|||
// set MIDI direct channel map
|
||||
void setMidiDirect(bool value);
|
||||
|
||||
// set MIDI direct program change
|
||||
void setMidiDirectProgram(bool value);
|
||||
|
||||
// set MIDI volume curve exponent
|
||||
void setMidiVolExp(float value);
|
||||
|
||||
// set MIDI input callback
|
||||
// if the specified function returns -2, note feedback will be inhibited.
|
||||
void setMidiCallback(std::function<int(const TAMidiMessage&)> what);
|
||||
|
|
@ -1253,6 +1270,7 @@ class DivEngine {
|
|||
firstTick(false),
|
||||
skipping(false),
|
||||
midiIsDirect(false),
|
||||
midiIsDirectProgram(false),
|
||||
lowLatency(false),
|
||||
systemsRegistered(false),
|
||||
hasLoadedSomething(false),
|
||||
|
|
@ -1261,6 +1279,7 @@ class DivEngine {
|
|||
midiOutProgramChange(false),
|
||||
midiOutMode(DIV_MIDI_MODE_NOTE),
|
||||
midiOutTimeRate(0),
|
||||
midiVolExp(2.0f), // General MIDI standard
|
||||
softLockCount(0),
|
||||
subticks(0),
|
||||
ticks(0),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -187,6 +187,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
ds.oldDPCM=true;
|
||||
ds.delayBehavior=0;
|
||||
ds.jumpTreatment=2;
|
||||
ds.oldAlwaysSetVolume=true;
|
||||
|
||||
// 1.1 compat flags
|
||||
if (ds.version>24) {
|
||||
|
|
@ -1876,6 +1877,9 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
if (ds.version<188) {
|
||||
ds.ceilVolumeScaling=false;
|
||||
}
|
||||
if (ds.version<191) {
|
||||
ds.oldAlwaysSetVolume=true;
|
||||
}
|
||||
ds.isDMF=false;
|
||||
|
||||
reader.readS(); // reserved
|
||||
|
|
@ -2424,7 +2428,12 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
|||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<2; i++) {
|
||||
if (ds.version>=191) {
|
||||
ds.oldAlwaysSetVolume=reader.readC();
|
||||
} else {
|
||||
reader.readC();
|
||||
}
|
||||
for (int i=0; i<1; i++) {
|
||||
reader.readC();
|
||||
}
|
||||
}
|
||||
|
|
@ -5522,7 +5531,8 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
|||
w->writeC(song.oldDPCM);
|
||||
w->writeC(song.resetArpPhaseOnNewNote);
|
||||
w->writeC(song.ceilVolumeScaling);
|
||||
for (int i=0; i<2; i++) {
|
||||
w->writeC(song.oldAlwaysSetVolume);
|
||||
for (int i=0; i<1; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
|
|
@ -6445,7 +6455,7 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
|
|||
|
||||
w->writeText(fmt::sprintf("- type: %d\n",(int)ins->type));
|
||||
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM) {
|
||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_OPL || ins->type==DIV_INS_OPLL || ins->type==DIV_INS_OPZ || ins->type==DIV_INS_OPL_DRUMS || ins->type==DIV_INS_OPM || ins->type==DIV_INS_ESFM) {
|
||||
w->writeText("- FM parameters:\n");
|
||||
w->writeText(fmt::sprintf(" - ALG: %d\n",ins->fm.alg));
|
||||
w->writeText(fmt::sprintf(" - FB: %d\n",ins->fm.fb));
|
||||
|
|
@ -6489,10 +6499,29 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_ESFM) {
|
||||
w->writeText("- ESFM parameters:\n");
|
||||
w->writeText(fmt::sprintf(" - noise mode: %d\n",ins->esfm.noise));
|
||||
|
||||
for (int j=0; j<ins->fm.ops; j++) {
|
||||
DivInstrumentESFM::Operator& opE=ins->esfm.op[j];
|
||||
|
||||
w->writeText(fmt::sprintf(" - operator %d:\n",j));
|
||||
w->writeText(fmt::sprintf(" - DL: %d\n",opE.delay));
|
||||
w->writeText(fmt::sprintf(" - OL: %d\n",opE.outLvl));
|
||||
w->writeText(fmt::sprintf(" - MI: %d\n",opE.modIn));
|
||||
w->writeText(fmt::sprintf(" - output left: %s\n",trueFalse[opE.left?1:0]));
|
||||
w->writeText(fmt::sprintf(" - output right: %s\n",trueFalse[opE.right?1:0]));
|
||||
w->writeText(fmt::sprintf(" - CT: %d\n",opE.ct));
|
||||
w->writeText(fmt::sprintf(" - DT: %d\n",opE.dt));
|
||||
w->writeText(fmt::sprintf(" - fixed frequency: %s\n",trueFalse[opE.fixed?1:0]));
|
||||
}
|
||||
}
|
||||
|
||||
if (ins->type==DIV_INS_GB) {
|
||||
w->writeText("- Game Boy parameters:\n");
|
||||
w->writeText(fmt::sprintf(" - volume: %d\n",ins->gb.envVol));
|
||||
w->writeText(fmt::sprintf(" - direction: %d\n",gbEnvDir[ins->gb.envDir?1:0]));
|
||||
w->writeText(fmt::sprintf(" - direction: %s\n",gbEnvDir[ins->gb.envDir?1:0]));
|
||||
w->writeText(fmt::sprintf(" - length: %d\n",ins->gb.envLen));
|
||||
w->writeText(fmt::sprintf(" - sound length: %d\n",ins->gb.soundLen));
|
||||
w->writeText(fmt::sprintf(" - use software envelope: %s\n",trueFalse[ins->gb.softEnv?1:0]));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -302,7 +302,7 @@ DivSample* DivEngine::sampleFromFile(const char* path) {
|
|||
#endif
|
||||
}
|
||||
|
||||
DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles) {
|
||||
DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth, int channels, bool bigEndian, bool unsign, bool swapNibbles, int rate) {
|
||||
if (song.sample.size()>=256) {
|
||||
lastError="too many samples!";
|
||||
return NULL;
|
||||
|
|
@ -420,8 +420,8 @@ DivSample* DivEngine::sampleFromFileRaw(const char* path, DivSampleDepth depth,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
sample->rate=32000;
|
||||
sample->centerRate=32000;
|
||||
sample->rate=rate;
|
||||
sample->centerRate=rate;
|
||||
sample->depth=depth;
|
||||
sample->init(samples);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -230,6 +230,29 @@ bool DivInstrumentSNES::operator==(const DivInstrumentSNES& other) {
|
|||
);
|
||||
}
|
||||
|
||||
bool DivInstrumentESFM::operator==(const DivInstrumentESFM& other) {
|
||||
return (
|
||||
_C(noise) &&
|
||||
_C(op[0]) &&
|
||||
_C(op[1]) &&
|
||||
_C(op[2]) &&
|
||||
_C(op[3])
|
||||
);
|
||||
}
|
||||
|
||||
bool DivInstrumentESFM::Operator::operator==(const DivInstrumentESFM::Operator& other) {
|
||||
return (
|
||||
_C(delay) &&
|
||||
_C(outLvl) &&
|
||||
_C(modIn) &&
|
||||
_C(left) &&
|
||||
_C(right) &&
|
||||
_C(fixed) &&
|
||||
_C(ct) &&
|
||||
_C(dt)
|
||||
);
|
||||
}
|
||||
|
||||
#undef _C
|
||||
|
||||
#define FEATURE_BEGIN(x) \
|
||||
|
|
@ -743,6 +766,22 @@ void DivInstrument::writeFeatureNE(SafeWriter* w) {
|
|||
FEATURE_END;
|
||||
}
|
||||
|
||||
void DivInstrument::writeFeatureEF(SafeWriter* w) {
|
||||
FEATURE_BEGIN("EF");
|
||||
|
||||
w->writeC(esfm.noise&3);
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentESFM::Operator& op=esfm.op[i];
|
||||
|
||||
w->writeC(((op.delay&7)<<5)|((op.outLvl&7)<<2)|((op.right&1)<<1)|(op.left&1));
|
||||
w->writeC((op.fixed&1)<<3|(op.modIn&7));
|
||||
w->writeC(op.ct);
|
||||
w->writeC(op.dt);
|
||||
}
|
||||
|
||||
FEATURE_END;
|
||||
}
|
||||
|
||||
void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bool insName) {
|
||||
size_t blockStartSeek=0;
|
||||
size_t blockEndSeek=0;
|
||||
|
|
@ -786,6 +825,7 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
bool featureES=false;
|
||||
bool featureX1=false;
|
||||
bool featureNE=false;
|
||||
bool featureEF=false;
|
||||
|
||||
bool checkForWL=false;
|
||||
|
||||
|
|
@ -999,7 +1039,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
featureSM=true;
|
||||
featureSL=true;
|
||||
break;
|
||||
|
||||
case DIV_INS_ESFM:
|
||||
featureFM=true;
|
||||
featureEF=true;
|
||||
break;
|
||||
case DIV_INS_MAX:
|
||||
break;
|
||||
case DIV_INS_NULL:
|
||||
|
|
@ -1047,6 +1090,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
if (x1_010!=defaultIns.x1_010) {
|
||||
featureX1=true;
|
||||
}
|
||||
if (esfm!=defaultIns.esfm) {
|
||||
featureEF=true;
|
||||
}
|
||||
}
|
||||
|
||||
// check ins name
|
||||
|
|
@ -1189,6 +1235,9 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
|||
if (featureNE) {
|
||||
writeFeatureNE(w);
|
||||
}
|
||||
if (featureEF) {
|
||||
writeFeatureEF(w);
|
||||
}
|
||||
|
||||
if (fui && (featureSL || featureWL)) {
|
||||
w->write("EN",2);
|
||||
|
|
@ -2598,6 +2647,32 @@ void DivInstrument::readFeatureNE(SafeReader& reader, short version) {
|
|||
READ_FEAT_END;
|
||||
}
|
||||
|
||||
void DivInstrument::readFeatureEF(SafeReader& reader, short version) {
|
||||
READ_FEAT_BEGIN;
|
||||
|
||||
unsigned char next=reader.readC();
|
||||
esfm.noise=next&3;
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
DivInstrumentESFM::Operator& op=esfm.op[i];
|
||||
|
||||
next=reader.readC();
|
||||
op.delay=(next>>5)&7;
|
||||
op.outLvl=(next>>2)&7;
|
||||
op.right=(next>>1)&1;
|
||||
op.left=next&1;
|
||||
|
||||
next=reader.readC();
|
||||
op.modIn=next&7;
|
||||
op.fixed=(next>>3)&1;
|
||||
|
||||
op.ct=reader.readC();
|
||||
op.dt=reader.readC();
|
||||
}
|
||||
|
||||
READ_FEAT_END;
|
||||
}
|
||||
|
||||
DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song) {
|
||||
unsigned char featCode[2];
|
||||
bool volIsCutoff=false;
|
||||
|
|
@ -2666,6 +2741,8 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
|
|||
readFeatureX1(reader,version);
|
||||
} else if (memcmp(featCode,"NE",2)==0) { // NES (DPCM)
|
||||
readFeatureNE(reader,version);
|
||||
} else if (memcmp(featCode,"EF",2)==0) { // ESFM
|
||||
readFeatureEF(reader,version);
|
||||
} else {
|
||||
if (song==NULL && (memcmp(featCode,"SL",2)==0 || (memcmp(featCode,"WL",2)==0))) {
|
||||
// nothing
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -85,6 +85,7 @@ enum DivInstrumentType: unsigned short {
|
|||
DIV_INS_TED=52,
|
||||
DIV_INS_C140=53,
|
||||
DIV_INS_C219=54,
|
||||
DIV_INS_ESFM=55,
|
||||
DIV_INS_MAX,
|
||||
DIV_INS_NULL
|
||||
};
|
||||
|
|
@ -771,6 +772,56 @@ struct DivInstrumentSNES {
|
|||
d2(0) {}
|
||||
};
|
||||
|
||||
// ESFM operator structure:
|
||||
// - DELAY, OUT, MOD, L, R, NOISE
|
||||
// - Virtual: CT, DT, FIXED
|
||||
// - 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 {
|
||||
unsigned char delay, outLvl, modIn, left, right, fixed;
|
||||
signed char ct, dt;
|
||||
|
||||
bool operator==(const Operator& other);
|
||||
bool operator!=(const Operator& other) {
|
||||
return !(*this==other);
|
||||
}
|
||||
Operator():
|
||||
delay(0),
|
||||
outLvl(0),
|
||||
modIn(0),
|
||||
left(1),
|
||||
right(1),
|
||||
fixed(0),
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
struct DivInstrument {
|
||||
String name;
|
||||
DivInstrumentType type;
|
||||
|
|
@ -787,6 +838,7 @@ struct DivInstrument {
|
|||
DivInstrumentSoundUnit su;
|
||||
DivInstrumentES5506 es5506;
|
||||
DivInstrumentSNES snes;
|
||||
DivInstrumentESFM esfm;
|
||||
|
||||
/**
|
||||
* these are internal functions.
|
||||
|
|
@ -811,6 +863,7 @@ struct DivInstrument {
|
|||
void writeFeatureES(SafeWriter* w);
|
||||
void writeFeatureX1(SafeWriter* w);
|
||||
void writeFeatureNE(SafeWriter* w);
|
||||
void writeFeatureEF(SafeWriter* w);
|
||||
|
||||
void readFeatureNA(SafeReader& reader, short version);
|
||||
void readFeatureFM(SafeReader& reader, short version);
|
||||
|
|
@ -831,6 +884,7 @@ struct DivInstrument {
|
|||
void readFeatureES(SafeReader& reader, short version);
|
||||
void readFeatureX1(SafeReader& reader, short version);
|
||||
void readFeatureNE(SafeReader& reader, short version);
|
||||
void readFeatureEF(SafeReader& reader, short version);
|
||||
|
||||
DivDataErrors readInsDataOld(SafeReader& reader, short version);
|
||||
DivDataErrors readInsDataNew(SafeReader& reader, short version, bool fui, DivSong* song);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -245,6 +245,81 @@ void DivMacroInt::mask(unsigned char id, bool enabled) {
|
|||
#undef CONSIDER_OP
|
||||
#undef CONSIDER
|
||||
|
||||
#define CONSIDER(x,y,z) \
|
||||
case z: \
|
||||
macroState=&x; \
|
||||
macro=&ins->std.y; \
|
||||
break;
|
||||
|
||||
#define CONSIDER_OP(oi,o) \
|
||||
CONSIDER(op[oi].am,opMacros[oi].amMacro,0+o) \
|
||||
CONSIDER(op[oi].ar,opMacros[oi].arMacro,1+o) \
|
||||
CONSIDER(op[oi].dr,opMacros[oi].drMacro,2+o) \
|
||||
CONSIDER(op[oi].mult,opMacros[oi].multMacro,3+o) \
|
||||
CONSIDER(op[oi].rr,opMacros[oi].rrMacro,4+o) \
|
||||
CONSIDER(op[oi].sl,opMacros[oi].slMacro,5+o) \
|
||||
CONSIDER(op[oi].tl,opMacros[oi].tlMacro,6+o) \
|
||||
CONSIDER(op[oi].dt2,opMacros[oi].dt2Macro,7+o) \
|
||||
CONSIDER(op[oi].rs,opMacros[oi].rsMacro,8+o) \
|
||||
CONSIDER(op[oi].dt,opMacros[oi].dtMacro,9+o) \
|
||||
CONSIDER(op[oi].d2r,opMacros[oi].d2rMacro,10+o) \
|
||||
CONSIDER(op[oi].ssg,opMacros[oi].ssgMacro,11+o) \
|
||||
CONSIDER(op[oi].dam,opMacros[oi].damMacro,12+o) \
|
||||
CONSIDER(op[oi].dvb,opMacros[oi].dvbMacro,13+o) \
|
||||
CONSIDER(op[oi].egt,opMacros[oi].egtMacro,14+o) \
|
||||
CONSIDER(op[oi].ksl,opMacros[oi].kslMacro,15+o) \
|
||||
CONSIDER(op[oi].sus,opMacros[oi].susMacro,16+o) \
|
||||
CONSIDER(op[oi].vib,opMacros[oi].vibMacro,17+o) \
|
||||
CONSIDER(op[oi].ws,opMacros[oi].wsMacro,18+o) \
|
||||
CONSIDER(op[oi].ksr,opMacros[oi].ksrMacro,19+o)
|
||||
|
||||
void DivMacroInt::restart(unsigned char id) {
|
||||
DivMacroStruct* macroState=NULL;
|
||||
DivInstrumentMacro* macro=NULL;
|
||||
|
||||
if (e==NULL) return;
|
||||
if (ins==NULL) return;
|
||||
|
||||
switch (id) {
|
||||
CONSIDER(vol,volMacro,0)
|
||||
CONSIDER(arp,arpMacro,1)
|
||||
CONSIDER(duty,dutyMacro,2)
|
||||
CONSIDER(wave,waveMacro,3)
|
||||
CONSIDER(pitch,pitchMacro,4)
|
||||
CONSIDER(ex1,ex1Macro,5)
|
||||
CONSIDER(ex2,ex2Macro,6)
|
||||
CONSIDER(ex3,ex3Macro,7)
|
||||
CONSIDER(alg,algMacro,8)
|
||||
CONSIDER(fb,fbMacro,9)
|
||||
CONSIDER(fms,fmsMacro,10)
|
||||
CONSIDER(ams,amsMacro,11)
|
||||
CONSIDER(panL,panLMacro,12)
|
||||
CONSIDER(panR,panRMacro,13)
|
||||
CONSIDER(phaseReset,phaseResetMacro,14)
|
||||
CONSIDER(ex4,ex4Macro,15)
|
||||
CONSIDER(ex5,ex5Macro,16)
|
||||
CONSIDER(ex6,ex6Macro,17)
|
||||
CONSIDER(ex7,ex7Macro,18)
|
||||
CONSIDER(ex8,ex8Macro,19)
|
||||
|
||||
CONSIDER_OP(0,0x20)
|
||||
CONSIDER_OP(2,0x40)
|
||||
CONSIDER_OP(1,0x60)
|
||||
CONSIDER_OP(3,0x80)
|
||||
}
|
||||
|
||||
if (macroState==NULL || macro==NULL) return;
|
||||
|
||||
if (macro->len<=0) return;
|
||||
if (macroState->masked) return;
|
||||
|
||||
macroState->init();
|
||||
macroState->prepare(*macro,e);
|
||||
}
|
||||
|
||||
#undef CONSIDER_OP
|
||||
#undef CONSIDER
|
||||
|
||||
void DivMacroInt::release() {
|
||||
released=true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -119,6 +119,11 @@ class DivMacroInt {
|
|||
*/
|
||||
void release();
|
||||
|
||||
/**
|
||||
* restart macro.
|
||||
*/
|
||||
void restart(unsigned char id);
|
||||
|
||||
/**
|
||||
* trigger next macro tick.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -102,15 +102,19 @@ bool DivDispatch::isVolGlobal() {
|
|||
return false;
|
||||
}
|
||||
|
||||
int DivDispatch::mapVelocity(int ch, unsigned char vel) {
|
||||
int DivDispatch::mapVelocity(int ch, float vel) {
|
||||
const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0))));
|
||||
return (vel*volMax)/127;
|
||||
return round(vel*volMax);
|
||||
}
|
||||
|
||||
int DivDispatch::getPortaFloor(int ch) {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
bool DivDispatch::getLegacyAlwaysSetVolume() {
|
||||
return true;
|
||||
}
|
||||
|
||||
float DivDispatch::getPostAmp() {
|
||||
return 1.0f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -721,8 +721,8 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -783,8 +783,8 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 127;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -651,8 +651,8 @@ int DivPlatformAY8910::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 15;
|
||||
|
|
@ -719,6 +719,10 @@ DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformAY8910::mapVelocity(int ch, float vel) {
|
||||
return round(15.0*pow(vel,0.33));
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformAY8910::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
@ -775,6 +779,10 @@ bool DivPlatformAY8910::keyOffAffectsArp(int ch) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DivPlatformAY8910::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivPlatformAY8910::notifyInsDeletion(void* ins) {
|
||||
for (int i=0; i<3; i++) {
|
||||
chan[i].std.notifyInsDeletion((DivInstrument*)ins);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -131,6 +131,7 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void flushWrites();
|
||||
|
|
@ -143,6 +144,7 @@ class DivPlatformAY8910: public DivDispatch {
|
|||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
bool getDCOffRequired();
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -653,8 +653,8 @@ int DivPlatformAY8930::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 31;
|
||||
|
|
@ -718,6 +718,10 @@ DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformAY8930::mapVelocity(int ch, float vel) {
|
||||
return round(31.0*pow(vel,0.22));
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformAY8930::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
@ -774,6 +778,10 @@ bool DivPlatformAY8930::keyOffAffectsArp(int ch) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DivPlatformAY8930::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivPlatformAY8930::notifyInsDeletion(void* ins) {
|
||||
for (int i=0; i<3; i++) {
|
||||
chan[i].std.notifyInsDeletion((DivInstrument*)ins);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -132,6 +132,7 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void reset();
|
||||
|
|
@ -143,6 +144,7 @@ class DivPlatformAY8930: public DivDispatch {
|
|||
bool keyOffAffectsArp(int ch);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -246,8 +246,8 @@ int DivPlatformBubSysWSG::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -441,8 +441,8 @@ int DivPlatformC140::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -536,8 +536,8 @@ int DivPlatformC64::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -1022,8 +1022,8 @@ int DivPlatformES5506::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
1077
src/engine/platform/esfm.cpp
Normal file
1077
src/engine/platform/esfm.cpp
Normal file
File diff suppressed because it is too large
Load diff
207
src/engine/platform/esfm.h
Normal file
207
src/engine/platform/esfm.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "../dispatch.h"
|
||||
#include "../../fixedQueue.h"
|
||||
#include "../../../extern/ESFMu/esfm.h"
|
||||
|
||||
// ESFM register address space technically spans 0x800 (2048) bytes,
|
||||
// but we only need the first 0x254 (596) during normal use.
|
||||
// Rounding it up to 0x400 bytes, the nearest power of 2.
|
||||
#define ESFM_REG_POOL_SIZE 0x400
|
||||
|
||||
class DivPlatformESFM: public DivDispatch {
|
||||
struct Channel: public SharedChannel<int> {
|
||||
struct {
|
||||
DivInstrumentFM fm;
|
||||
DivInstrumentESFM esfm;
|
||||
} state;
|
||||
unsigned char freqL[4], freqH[4];
|
||||
bool hardReset;
|
||||
unsigned char globalPan;
|
||||
int macroVolMul;
|
||||
struct {
|
||||
int baseNoteOverride;
|
||||
bool fixedArp;
|
||||
int arpOff;
|
||||
int pitch2;
|
||||
bool hasOpArp;
|
||||
bool hasOpPitch;
|
||||
} opsState[4];
|
||||
|
||||
void handleArpFmOp(int offset=0, int o=0) {
|
||||
DivMacroInt::IntOp& m=this->std.op[o];
|
||||
if (m.ssg.had) {
|
||||
opsState[o].hasOpArp=true;
|
||||
|
||||
if (m.ssg.val<0) {
|
||||
if (!(m.ssg.val&0x40000000)) {
|
||||
opsState[o].baseNoteOverride=(m.ssg.val|0x40000000)+offset;
|
||||
opsState[o].fixedArp=true;
|
||||
} else {
|
||||
opsState[o].arpOff=m.ssg.val;
|
||||
opsState[o].fixedArp=false;
|
||||
}
|
||||
} else {
|
||||
if (m.ssg.val&0x40000000) {
|
||||
opsState[o].baseNoteOverride=(m.ssg.val&(~0x40000000))+offset;
|
||||
opsState[o].fixedArp=true;
|
||||
} else {
|
||||
opsState[o].arpOff=m.ssg.val;
|
||||
opsState[o].fixedArp=false;
|
||||
}
|
||||
}
|
||||
freqChanged=true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
opsState[o].hasOpArp=false;
|
||||
}
|
||||
}
|
||||
|
||||
void handlePitchFmOp(int o)
|
||||
{
|
||||
DivMacroInt::IntOp& m=this->std.op[o];
|
||||
|
||||
if (m.dt.had) {
|
||||
opsState[o].hasOpPitch=true;
|
||||
|
||||
if (m.dt.mode) {
|
||||
opsState[o].pitch2+=m.dt.val;
|
||||
CLAMP_VAR(opsState[o].pitch2,-131071,131071);
|
||||
} else {
|
||||
opsState[o].pitch2=m.dt.val;
|
||||
}
|
||||
this->freqChanged=true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
opsState[o].hasOpPitch=false;
|
||||
}
|
||||
}
|
||||
|
||||
Channel():
|
||||
SharedChannel<int>(0),
|
||||
freqL{0, 0, 0, 0},
|
||||
freqH{0, 0, 0, 0},
|
||||
hardReset(false),
|
||||
globalPan(3),
|
||||
macroVolMul(64) {
|
||||
memset(opsState, 0, sizeof(opsState));
|
||||
}
|
||||
};
|
||||
Channel chan[18];
|
||||
DivDispatchOscBuffer* oscBuf[18];
|
||||
bool isMuted[18];
|
||||
struct QueuedWrite {
|
||||
unsigned short addr;
|
||||
unsigned char val;
|
||||
bool addrOrVal;
|
||||
QueuedWrite(): addr(0), val(0), addrOrVal(false) {}
|
||||
QueuedWrite(unsigned short a, unsigned char v): addr(a), val(v), addrOrVal(false) {}
|
||||
};
|
||||
FixedQueue<QueuedWrite,2048> writes;
|
||||
esfm_chip chip;
|
||||
|
||||
unsigned char regPool[ESFM_REG_POOL_SIZE];
|
||||
short oldWrites[ESFM_REG_POOL_SIZE];
|
||||
short pendingWrites[ESFM_REG_POOL_SIZE];
|
||||
|
||||
int octave(int freq);
|
||||
int toFreq(int freq);
|
||||
void commitState(int ch, DivInstrument* ins);
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
inline void rWrite(unsigned short a, short v) {
|
||||
if (!skipRegisterWrites && a<ESFM_REG_POOL_SIZE) {
|
||||
pendingWrites[a]=v;
|
||||
}
|
||||
}
|
||||
|
||||
inline void immWrite(unsigned short a, unsigned char v) {
|
||||
if (!skipRegisterWrites) {
|
||||
writes.push_back(QueuedWrite(a,v));
|
||||
if (dumpWrites) {
|
||||
addWrite(a,v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ESFM doesn't have predef algorithms, so a custom KVS heuristic for auto mode is needed.
|
||||
* This is a bit too complex for a macro.
|
||||
* The heuristic for auto mode is expressed as:
|
||||
* true for an operator o
|
||||
* where op[o].outLvl = 7,
|
||||
* or op[o].outLvl > 0 and o == 3 (last operator),
|
||||
* or op[o].outLvl > 0 and (op[o].outLvl - op[o + 1].modIn) >= 2,
|
||||
* or op[o].outLvl > 0 and op[o + 1].modIn == 0.
|
||||
*/
|
||||
inline bool KVS_ES(int c, int o) {
|
||||
if (c<0 || c>=18 || o<0 || o>=4) return false;
|
||||
|
||||
if (chan[c].state.fm.op[o].kvs==1) return true;
|
||||
|
||||
if (chan[c].state.fm.op[o].kvs==2) {
|
||||
if (chan[c].state.esfm.op[o].outLvl==7) return true;
|
||||
else if (chan[c].state.esfm.op[o].outLvl>0) {
|
||||
if (o==3) return true;
|
||||
else if ((chan[c].state.esfm.op[o].outLvl-chan[c].state.esfm.op[o+1].modIn)>=2) {
|
||||
return true;
|
||||
}
|
||||
else if (chan[c].state.esfm.op[o+1].modIn==0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
void acquire(short** buf, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
int getOutputCount();
|
||||
void reset();
|
||||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
void toggleRegisterDump(bool enable);
|
||||
void notifyInsChange(int ins);
|
||||
void notifyInsDeletion(void* ins);
|
||||
int mapVelocity(int ch, float vel);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
void poke(std::vector<DivRegWrite>& wlist);
|
||||
void setFlags(const DivConfig& flags);
|
||||
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
|
||||
void quit();
|
||||
~DivPlatformESFM();
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -387,8 +387,8 @@ int DivPlatformFDS::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -186,6 +186,17 @@ class DivPlatformOPN: public DivPlatformFMBase {
|
|||
void setCombo(bool combo) {
|
||||
useCombo=combo;
|
||||
}
|
||||
virtual int mapVelocity(int ch, float vel) {
|
||||
if (ch==csmChan) return vel*127.0;
|
||||
if (ch==adpcmBChanOffs) return vel*255.0;
|
||||
if (ch>=adpcmAChanOffs) {
|
||||
if (vel==0) return 0;
|
||||
if (vel>=1.0) return 31;
|
||||
return CLAMP(round(32.0-(56.0-log2(vel*127.0)*8.0)),0,31);
|
||||
}
|
||||
if (ch>=psgChanOffs) return round(15.0*pow(vel,0.33));
|
||||
return DivPlatformFMBase::mapVelocity(ch,vel);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -121,6 +121,24 @@ class DivPlatformFMBase: public DivDispatch {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual int mapVelocity(int ch, float vel) {
|
||||
// -0.75dB per step
|
||||
// -6: 64: 8
|
||||
// -12: 32: 16
|
||||
// -18: 16: 24
|
||||
// -24: 8: 32
|
||||
// -30: 4: 40
|
||||
// -36: 2: 48
|
||||
// -42: 1: 56
|
||||
if (vel==0) return 0;
|
||||
if (vel>=1.0) return 127;
|
||||
return CLAMP(round(128.0-(56.0-log2(vel*127.0)*8.0)),0,127);
|
||||
}
|
||||
|
||||
bool getLegacyAlwaysSetVolume() {
|
||||
return true;
|
||||
}
|
||||
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -311,8 +311,8 @@ int DivPlatformGA20::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -553,8 +553,8 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -348,7 +348,7 @@ void DivPlatformGenesis::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
|
||||
if (i>=5 && chan[i].furnaceDac) {
|
||||
if (i>=5 && chan[i].furnaceDac && chan[i].dacMode) {
|
||||
if (NEW_ARP_STRAT) {
|
||||
chan[i].handleArp();
|
||||
} else if (chan[i].std.arp.had) {
|
||||
|
|
@ -1183,8 +1183,8 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 127;
|
||||
|
|
@ -1300,6 +1300,12 @@ DivDispatchOscBuffer* DivPlatformGenesis::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformGenesis::mapVelocity(int ch, float vel) {
|
||||
if (ch==csmChan) return DivPlatformOPN::mapVelocity(ch,vel);
|
||||
if (ch>5) return DivPlatformOPN::mapVelocity(5,vel);
|
||||
return DivPlatformOPN::mapVelocity(ch,vel);
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformGenesis::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -112,6 +112,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
|
|||
virtual unsigned short getPan(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
virtual int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void reset();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -418,9 +418,6 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
opChan[ch].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
break;
|
||||
case DIV_CMD_PRE_PORTA:
|
||||
break;
|
||||
default:
|
||||
|
|
@ -818,6 +815,12 @@ DivDispatchOscBuffer* DivPlatformGenesisExt::getOscBuffer(int ch) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int DivPlatformGenesisExt::mapVelocity(int ch, float vel) {
|
||||
if (ch>=extChanOffs+4) return DivPlatformGenesis::mapVelocity(ch-3,vel);
|
||||
if (ch>=extChanOffs) return DivPlatformGenesis::mapVelocity(extChanOffs,vel);
|
||||
return DivPlatformGenesis::mapVelocity(ch,vel);
|
||||
}
|
||||
|
||||
void DivPlatformGenesisExt::reset() {
|
||||
DivPlatformGenesis::reset();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -36,6 +36,7 @@ class DivPlatformGenesisExt: public DivPlatformGenesis {
|
|||
DivMacroInt* getChanMacroInt(int ch);
|
||||
unsigned short getPan(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
void reset();
|
||||
void forceIns();
|
||||
void tick(bool sysTick=true);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -395,8 +395,8 @@ int DivPlatformK007232::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -345,8 +345,8 @@ int DivPlatformK053260::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -353,8 +353,8 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -438,6 +438,10 @@ bool DivPlatformLynx::keyOffAffectsPorta(int ch) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DivPlatformLynx::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
//int DivPlatformLynx::getPortaFloor(int ch) {
|
||||
// return 12;
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -84,6 +84,7 @@ class DivPlatformLynx: public DivDispatch {
|
|||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
//int getPortaFloor(int ch);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -327,8 +327,8 @@ int DivPlatformMMC5::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -297,8 +297,8 @@ int DivPlatformMSM5232::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -268,8 +268,8 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 8;
|
||||
|
|
@ -371,6 +371,10 @@ bool DivPlatformMSM6258::keyOffAffectsArp(int ch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DivPlatformMSM6258::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivPlatformMSM6258::notifyInsChange(int ins) {
|
||||
for (int i=0; i<1; i++) {
|
||||
if (chan[i].ins==ins) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -75,6 +75,7 @@ class DivPlatformMSM6258: public DivDispatch {
|
|||
void muteChannel(int ch, bool mute);
|
||||
int getOutputCount();
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
void notifyInsChange(int ins);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -241,8 +241,8 @@ int DivPlatformMSM6295::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 8;
|
||||
|
|
@ -330,6 +330,10 @@ bool DivPlatformMSM6295::keyOffAffectsArp(int ch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DivPlatformMSM6295::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
float DivPlatformMSM6295::getPostAmp() {
|
||||
return 3.0f;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -87,6 +87,7 @@ class DivPlatformMSM6295: public DivDispatch, public vgsound_emu_mem_intf {
|
|||
virtual void tick(bool sysTick=true) override;
|
||||
virtual void muteChannel(int ch, bool mute) override;
|
||||
virtual bool keyOffAffectsArp(int ch) override;
|
||||
virtual bool getLegacyAlwaysSetVolume() override;
|
||||
virtual float getPostAmp() override;
|
||||
virtual void notifyInsChange(int ins) override;
|
||||
virtual void notifyInsDeletion(void* ins) override;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -452,8 +452,8 @@ int DivPlatformN163::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -199,7 +199,7 @@ void DivPlatformNamcoWSG::tick(bool sysTick) {
|
|||
for (int i=0; i<chans; i++) {
|
||||
chan[i].std.next();
|
||||
if (chan[i].std.vol.had) {
|
||||
chan[i].outVol=((chan[i].vol&15)*MIN(15,chan[i].std.vol.val))>>4;
|
||||
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol,chan[i].std.vol.val,15);
|
||||
}
|
||||
if (chan[i].std.duty.had) {
|
||||
chan[i].noise=chan[i].std.duty.val;
|
||||
|
|
@ -445,8 +445,8 @@ int DivPlatformNamcoWSG::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -659,8 +659,8 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -1343,7 +1343,7 @@ void DivPlatformOPL::commitState(int ch, DivInstrument* ins) {
|
|||
int DivPlatformOPL::dispatch(DivCommand c) {
|
||||
if (c.chan>=totalChans && c.chan!=adpcmChan) return 0;
|
||||
// ineffective in 4-op mode
|
||||
if (oplType==3 && c.chan!=adpcmChan && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX && c.cmd!=DIV_ALWAYS_SET_VOLUME) {
|
||||
if (oplType==3 && c.chan!=adpcmChan && c.chan<14 && (c.chan&1) && c.cmd!=DIV_CMD_GET_VOLMAX) {
|
||||
if (chan[c.chan-1].fourOp) return 0;
|
||||
}
|
||||
switch (c.cmd) {
|
||||
|
|
@ -1970,8 +1970,8 @@ int DivPlatformOPL::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
if (c.chan==adpcmChan) return 255;
|
||||
|
|
@ -2104,6 +2104,21 @@ DivDispatchOscBuffer* DivPlatformOPL::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformOPL::mapVelocity(int ch, float vel) {
|
||||
if (ch==adpcmChan) return vel*255.0;
|
||||
// -0.75dB per step
|
||||
// -6: 64: 8
|
||||
// -12: 32: 16
|
||||
// -18: 16: 24
|
||||
// -24: 8: 32
|
||||
// -30: 4: 40
|
||||
// -36: 2: 48
|
||||
// -42: 1: 56
|
||||
if (vel==0) return 0;
|
||||
if (vel>=1.0) return 63;
|
||||
return CLAMP(round(64.0-(56.0-log2(vel*127.0)*8.0)),0,63);
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformOPL::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
@ -2264,6 +2279,10 @@ bool DivPlatformOPL::keyOffAffectsPorta(int ch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DivPlatformOPL::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivPlatformOPL::notifyInsChange(int ins) {
|
||||
for (int i=0; i<totalChans; i++) {
|
||||
if (chan[i].ins==ins) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -150,6 +150,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
unsigned short getPan(int chan);
|
||||
DivChannelPair getPaired(int chan);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void reset();
|
||||
|
|
@ -161,6 +162,7 @@ class DivPlatformOPL: public DivDispatch {
|
|||
void setOPLType(int type, bool drums);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
void toggleRegisterDump(bool enable);
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsChange(int ins);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -853,8 +853,8 @@ int DivPlatformOPLL::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 0;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
case DIV_CMD_GET_VOLMAX:
|
||||
return 15;
|
||||
|
|
@ -962,6 +962,13 @@ DivDispatchOscBuffer* DivPlatformOPLL::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformOPLL::mapVelocity(int ch, float vel) {
|
||||
// -3dB per step
|
||||
if (vel==0) return 0;
|
||||
if (vel>=1.0) return 15;
|
||||
return CLAMP(round(16.0-(14.0-log2(vel*127.0)*2.0)),0,15);
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformOPLL::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
@ -1036,6 +1043,10 @@ bool DivPlatformOPLL::keyOffAffectsPorta(int ch) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool DivPlatformOPLL::getLegacyAlwaysSetVolume() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DivPlatformOPLL::notifyInsChange(int ins) {
|
||||
for (int i=0; i<11; i++) {
|
||||
if (chan[i].ins==ins) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -95,6 +95,7 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void reset();
|
||||
|
|
@ -104,6 +105,7 @@ class DivPlatformOPLL: public DivDispatch {
|
|||
void setYMFM(bool use);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool keyOffAffectsPorta(int ch);
|
||||
bool getLegacyAlwaysSetVolume();
|
||||
float getPostAmp();
|
||||
void toggleRegisterDump(bool enable);
|
||||
void setVRC7(bool vrc);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -474,8 +474,8 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -539,6 +539,10 @@ DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) {
|
|||
return oscBuf[ch];
|
||||
}
|
||||
|
||||
int DivPlatformPCE::mapVelocity(int ch, float vel) {
|
||||
return round(31.0*pow(vel,0.22));
|
||||
}
|
||||
|
||||
unsigned char* DivPlatformPCE::getRegisterPool() {
|
||||
return regPool;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -86,6 +86,7 @@ class DivPlatformPCE: public DivDispatch {
|
|||
DivChannelModeHints getModeHints(int chan);
|
||||
DivSamplePos getSamplePos(int ch);
|
||||
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||
int mapVelocity(int ch, float vel);
|
||||
unsigned char* getRegisterPool();
|
||||
int getRegisterPoolSize();
|
||||
void reset();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
@ -452,8 +452,8 @@ int DivPlatformPCMDAC::dispatch(DivCommand c) {
|
|||
case DIV_CMD_MACRO_ON:
|
||||
chan[c.chan].std.mask(c.value,false);
|
||||
break;
|
||||
case DIV_ALWAYS_SET_VOLUME:
|
||||
return 1;
|
||||
case DIV_CMD_MACRO_RESTART:
|
||||
chan[c.chan].std.restart(c.value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Furnace Tracker - multi-system chiptune tracker
|
||||
* Copyright (C) 2021-2023 tildearrow and contributors
|
||||
* Copyright (C) 2021-2024 tildearrow and contributors
|
||||
*
|
||||
* 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
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue