mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-19 23:10:23 +00:00
parent
0c1e2ddcb0
commit
5bd076d13e
9 changed files with 162 additions and 72 deletions
|
@ -579,6 +579,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
} else {
|
} else {
|
||||||
wave->data[j]=reader.readI();
|
wave->data[j]=reader.readI();
|
||||||
}
|
}
|
||||||
|
wave->data[j]&=wave->max;
|
||||||
}
|
}
|
||||||
// #FDS4Bit
|
// #FDS4Bit
|
||||||
if (ds.system[0]==DIV_SYSTEM_NES_FDS && ds.version<0x1a) {
|
if (ds.system[0]==DIV_SYSTEM_NES_FDS && ds.version<0x1a) {
|
||||||
|
|
|
@ -516,7 +516,7 @@ struct DivInstrumentWaveSynth {
|
||||||
oneShot(false),
|
oneShot(false),
|
||||||
enabled(false),
|
enabled(false),
|
||||||
global(false),
|
global(false),
|
||||||
speed(1),
|
speed(0),
|
||||||
param1(0),
|
param1(0),
|
||||||
param2(0),
|
param2(0),
|
||||||
param3(0),
|
param3(0),
|
||||||
|
|
|
@ -91,22 +91,13 @@ void DivPlatformGB::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformGB::updateWave() {
|
void DivPlatformGB::updateWave() {
|
||||||
DivWavetable* wt=parent->getWave(chan[2].wave);
|
|
||||||
rWrite(0x1a,0);
|
rWrite(0x1a,0);
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
if (wt->max<1 || wt->len<1) {
|
int nibble1=15-ws.output[i<<1];
|
||||||
rWrite(0x30+i,0);
|
int nibble2=15-ws.output[1+(i<<1)];
|
||||||
} else {
|
|
||||||
int nibble1=15-((wt->data[(i*2)*wt->len/32]*15)/wt->max);
|
|
||||||
int nibble2=15-((wt->data[(1+i*2)*wt->len/32]*15)/wt->max);
|
|
||||||
if (nibble1<0) nibble1=0;
|
|
||||||
if (nibble1>15) nibble1=15;
|
|
||||||
if (nibble2<0) nibble2=0;
|
|
||||||
if (nibble2>15) nibble2=15;
|
|
||||||
rWrite(0x30+i,(nibble1<<4)|nibble2);
|
rWrite(0x30+i,(nibble1<<4)|nibble2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char chanMuteMask[4]={
|
static unsigned char chanMuteMask[4]={
|
||||||
0xee, 0xdd, 0xbb, 0x77
|
0xee, 0xdd, 0xbb, 0x77
|
||||||
|
@ -194,10 +185,16 @@ void DivPlatformGB::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.hadWave) {
|
if (i==2 && chan[i].std.hadWave) {
|
||||||
if (chan[i].wave!=chan[i].std.wave) {
|
if (chan[i].wave!=chan[i].std.wave || ws.activeChanged()) {
|
||||||
chan[i].wave=chan[i].std.wave;
|
chan[i].wave=chan[i].std.wave;
|
||||||
|
ws.changeWave1(chan[i].wave);
|
||||||
|
if (!chan[i].keyOff) chan[i].keyOn=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (i==2) {
|
if (i==2) {
|
||||||
|
if (chan[i].active) {
|
||||||
|
if (ws.tick()) {
|
||||||
updateWave();
|
updateWave();
|
||||||
if (!chan[i].keyOff) chan[i].keyOn=true;
|
if (!chan[i].keyOff) chan[i].keyOn=true;
|
||||||
}
|
}
|
||||||
|
@ -222,10 +219,6 @@ void DivPlatformGB::tick() {
|
||||||
}
|
}
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
if (i==2) { // wave
|
if (i==2) { // wave
|
||||||
if (chan[i].wave<0) {
|
|
||||||
chan[i].wave=0;
|
|
||||||
updateWave();
|
|
||||||
}
|
|
||||||
rWrite(16+i*5,0x80);
|
rWrite(16+i*5,0x80);
|
||||||
rWrite(16+i*5+2,gbVolMap[chan[i].vol]);
|
rWrite(16+i*5+2,gbVolMap[chan[i].vol]);
|
||||||
} else {
|
} else {
|
||||||
|
@ -261,7 +254,8 @@ void DivPlatformGB::muteChannel(int ch, bool mute) {
|
||||||
|
|
||||||
int DivPlatformGB::dispatch(DivCommand c) {
|
int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
switch (c.cmd) {
|
switch (c.cmd) {
|
||||||
case DIV_CMD_NOTE_ON:
|
case DIV_CMD_NOTE_ON: {
|
||||||
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
if (c.chan==3) { // noise
|
if (c.chan==3) { // noise
|
||||||
chan[c.chan].baseFreq=c.value;
|
chan[c.chan].baseFreq=c.value;
|
||||||
|
@ -273,8 +267,17 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
chan[c.chan].active=true;
|
chan[c.chan].active=true;
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
chan[c.chan].std.init(parent->getIns(chan[c.chan].ins));
|
chan[c.chan].std.init(ins);
|
||||||
|
if (c.chan==2) {
|
||||||
|
if (chan[c.chan].wave<0) {
|
||||||
|
chan[c.chan].wave=0;
|
||||||
|
ws.changeWave1(chan[c.chan].wave);
|
||||||
|
}
|
||||||
|
ws.init(ins,32,15,chan[c.chan].insChanged);
|
||||||
|
}
|
||||||
|
chan[c.chan].insChanged=false;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_NOTE_OFF:
|
case DIV_CMD_NOTE_OFF:
|
||||||
chan[c.chan].active=false;
|
chan[c.chan].active=false;
|
||||||
chan[c.chan].keyOff=true;
|
chan[c.chan].keyOff=true;
|
||||||
|
@ -287,6 +290,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_INSTRUMENT:
|
case DIV_CMD_INSTRUMENT:
|
||||||
if (chan[c.chan].ins!=c.value || c.value2==1) {
|
if (chan[c.chan].ins!=c.value || c.value2==1) {
|
||||||
chan[c.chan].ins=c.value;
|
chan[c.chan].ins=c.value;
|
||||||
|
chan[c.chan].insChanged=true;
|
||||||
if (c.chan!=2) {
|
if (c.chan!=2) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins);
|
||||||
chan[c.chan].vol=ins->gb.envVol;
|
chan[c.chan].vol=ins->gb.envVol;
|
||||||
|
@ -312,7 +316,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_WAVE:
|
case DIV_CMD_WAVE:
|
||||||
if (c.chan!=2) break;
|
if (c.chan!=2) break;
|
||||||
chan[c.chan].wave=c.value;
|
chan[c.chan].wave=c.value;
|
||||||
updateWave();
|
ws.changeWave1(chan[c.chan].wave);
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
|
@ -415,6 +419,8 @@ void DivPlatformGB::reset() {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
chan[i]=DivPlatformGB::Channel();
|
chan[i]=DivPlatformGB::Channel();
|
||||||
}
|
}
|
||||||
|
ws.setEngine(parent);
|
||||||
|
ws.init(NULL,32,15,false);
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
}
|
}
|
||||||
|
@ -445,6 +451,7 @@ void DivPlatformGB::notifyInsChange(int ins) {
|
||||||
|
|
||||||
void DivPlatformGB::notifyWaveChange(int wave) {
|
void DivPlatformGB::notifyWaveChange(int wave) {
|
||||||
if (chan[2].wave==wave) {
|
if (chan[2].wave==wave) {
|
||||||
|
ws.changeWave1(wave);
|
||||||
updateWave();
|
updateWave();
|
||||||
if (!chan[2].keyOff) chan[2].keyOn=true;
|
if (!chan[2].keyOff) chan[2].keyOn=true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "../dispatch.h"
|
#include "../dispatch.h"
|
||||||
#include "../macroInt.h"
|
#include "../macroInt.h"
|
||||||
|
#include "../waveSynth.h"
|
||||||
#include "sound/gb/gb.h"
|
#include "sound/gb/gb.h"
|
||||||
|
|
||||||
class DivPlatformGB: public DivDispatch {
|
class DivPlatformGB: public DivDispatch {
|
||||||
|
@ -53,6 +54,7 @@ class DivPlatformGB: public DivDispatch {
|
||||||
Channel chan[4];
|
Channel chan[4];
|
||||||
bool isMuted[4];
|
bool isMuted[4];
|
||||||
unsigned char lastPan;
|
unsigned char lastPan;
|
||||||
|
DivWaveSynth ws;
|
||||||
|
|
||||||
GB_gameboy_t* gb;
|
GB_gameboy_t* gb;
|
||||||
unsigned char regPool[128];
|
unsigned char regPool[128];
|
||||||
|
|
|
@ -131,18 +131,10 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformPCE::updateWave(int ch) {
|
void DivPlatformPCE::updateWave(int ch) {
|
||||||
DivWavetable* wt=parent->getWave(chan[ch].wave);
|
|
||||||
chWrite(ch,0x04,0x5f);
|
chWrite(ch,0x04,0x5f);
|
||||||
chWrite(ch,0x04,0x1f);
|
chWrite(ch,0x04,0x1f);
|
||||||
for (int i=0; i<32; i++) {
|
for (int i=0; i<32; i++) {
|
||||||
if (wt->max<1 || wt->len<1) {
|
chWrite(ch,0x06,chan[ch].ws.output[i]);
|
||||||
chWrite(ch,0x06,0);
|
|
||||||
} else {
|
|
||||||
int data=wt->data[i*wt->len/32]*31/wt->max;
|
|
||||||
if (data<0) data=0;
|
|
||||||
if (data>31) data=31;
|
|
||||||
chWrite(ch,0x06,data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (chan[ch].active) {
|
if (chan[ch].active) {
|
||||||
chWrite(ch,0x04,0x80|chan[ch].outVol);
|
chWrite(ch,0x04,0x80|chan[ch].outVol);
|
||||||
|
@ -198,12 +190,17 @@ void DivPlatformPCE::tick() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chan[i].std.hadWave && !chan[i].pcm) {
|
if (chan[i].std.hadWave && !chan[i].pcm) {
|
||||||
if (chan[i].wave!=chan[i].std.wave) {
|
if (chan[i].wave!=chan[i].std.wave || chan[i].ws.activeChanged()) {
|
||||||
chan[i].wave=chan[i].std.wave;
|
chan[i].wave=chan[i].std.wave;
|
||||||
updateWave(i);
|
chan[i].ws.changeWave1(chan[i].wave);
|
||||||
if (!chan[i].keyOff) chan[i].keyOn=true;
|
if (!chan[i].keyOff) chan[i].keyOn=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (chan[i].active) {
|
||||||
|
if (chan[i].ws.tick()) {
|
||||||
|
updateWave(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
|
||||||
//DivInstrument* ins=parent->getIns(chan[i].ins);
|
//DivInstrument* ins=parent->getIns(chan[i].ins);
|
||||||
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true);
|
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true);
|
||||||
|
@ -224,10 +221,6 @@ void DivPlatformPCE::tick() {
|
||||||
chWrite(i,0x02,chan[i].freq&0xff);
|
chWrite(i,0x02,chan[i].freq&0xff);
|
||||||
chWrite(i,0x03,chan[i].freq>>8);
|
chWrite(i,0x03,chan[i].freq>>8);
|
||||||
if (chan[i].keyOn) {
|
if (chan[i].keyOn) {
|
||||||
if (chan[i].wave<0) {
|
|
||||||
chan[i].wave=0;
|
|
||||||
updateWave(i);
|
|
||||||
}
|
|
||||||
//rWrite(16+i*5,0x80);
|
//rWrite(16+i*5,0x80);
|
||||||
//chWrite(i,0x04,0x80|chan[i].vol);
|
//chWrite(i,0x04,0x80|chan[i].vol);
|
||||||
}
|
}
|
||||||
|
@ -310,6 +303,12 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
chWrite(c.chan,0x04,0x80|chan[c.chan].vol);
|
chWrite(c.chan,0x04,0x80|chan[c.chan].vol);
|
||||||
chan[c.chan].std.init(ins);
|
chan[c.chan].std.init(ins);
|
||||||
|
if (chan[c.chan].wave<0) {
|
||||||
|
chan[c.chan].wave=0;
|
||||||
|
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||||
|
}
|
||||||
|
chan[c.chan].ws.init(ins,32,31,chan[c.chan].insChanged);
|
||||||
|
chan[c.chan].insChanged=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_NOTE_OFF:
|
case DIV_CMD_NOTE_OFF:
|
||||||
|
@ -327,6 +326,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_INSTRUMENT:
|
case DIV_CMD_INSTRUMENT:
|
||||||
if (chan[c.chan].ins!=c.value || c.value2==1) {
|
if (chan[c.chan].ins!=c.value || c.value2==1) {
|
||||||
chan[c.chan].ins=c.value;
|
chan[c.chan].ins=c.value;
|
||||||
|
chan[c.chan].insChanged=true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_VOLUME:
|
case DIV_CMD_VOLUME:
|
||||||
|
@ -350,7 +350,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_WAVE:
|
case DIV_CMD_WAVE:
|
||||||
chan[c.chan].wave=c.value;
|
chan[c.chan].wave=c.value;
|
||||||
updateWave(c.chan);
|
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_PCE_LFO_MODE:
|
case DIV_CMD_PCE_LFO_MODE:
|
||||||
|
@ -462,6 +462,8 @@ void DivPlatformPCE::reset() {
|
||||||
memset(regPool,0,128);
|
memset(regPool,0,128);
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
chan[i]=DivPlatformPCE::Channel();
|
chan[i]=DivPlatformPCE::Channel();
|
||||||
|
chan[i].ws.setEngine(parent);
|
||||||
|
chan[i].ws.init(NULL,32,31,false);
|
||||||
}
|
}
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
|
@ -499,6 +501,7 @@ bool DivPlatformPCE::keyOffAffectsArp(int ch) {
|
||||||
void DivPlatformPCE::notifyWaveChange(int wave) {
|
void DivPlatformPCE::notifyWaveChange(int wave) {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (chan[i].wave==wave) {
|
if (chan[i].wave==wave) {
|
||||||
|
chan[i].ws.changeWave1(wave);
|
||||||
updateWave(i);
|
updateWave(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "../dispatch.h"
|
#include "../dispatch.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include "../macroInt.h"
|
#include "../macroInt.h"
|
||||||
|
#include "../waveSynth.h"
|
||||||
#include "sound/pce_psg.h"
|
#include "sound/pce_psg.h"
|
||||||
|
|
||||||
class DivPlatformPCE: public DivDispatch {
|
class DivPlatformPCE: public DivDispatch {
|
||||||
|
@ -35,6 +36,7 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise, pcm, furnaceDac;
|
bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise, pcm, furnaceDac;
|
||||||
signed char vol, outVol, wave;
|
signed char vol, outVol, wave;
|
||||||
DivMacroInt std;
|
DivMacroInt std;
|
||||||
|
DivWaveSynth ws;
|
||||||
Channel():
|
Channel():
|
||||||
freq(0),
|
freq(0),
|
||||||
baseFreq(0),
|
baseFreq(0),
|
||||||
|
|
|
@ -1,52 +1,99 @@
|
||||||
#include "waveSynth.h"
|
#include "waveSynth.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
#include "instrument.h"
|
||||||
|
|
||||||
|
bool DivWaveSynth::activeChanged() {
|
||||||
|
if (activeChangedB) {
|
||||||
|
activeChangedB=false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool DivWaveSynth::tick() {
|
bool DivWaveSynth::tick() {
|
||||||
bool updated=first;
|
bool updated=first;
|
||||||
first=false;
|
first=false;
|
||||||
|
if (!state.enabled) return updated;
|
||||||
|
|
||||||
|
if (--divCounter<=0) {
|
||||||
|
// run effect
|
||||||
|
switch (state.effect) {
|
||||||
|
case DIV_WS_INVERT:
|
||||||
|
for (int i=0; i<=state.speed; i++) {
|
||||||
|
output[pos]=height-output[pos];
|
||||||
|
if (++pos>=width) pos=0;
|
||||||
|
}
|
||||||
|
updated=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
divCounter=state.rateDivider;
|
||||||
|
}
|
||||||
|
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivWaveSynth::changeWave1(int num) {
|
||||||
|
DivWavetable* w1=e->getWave(num);
|
||||||
|
for (int i=0; i<width; i++) {
|
||||||
|
if (w1->max<1 || w1->len<1) {
|
||||||
|
wave1[i]=0;
|
||||||
|
output[i]=0;
|
||||||
|
} else {
|
||||||
|
int data=w1->data[i*w1->len/width]*height/w1->max;
|
||||||
|
if (data<0) data=0;
|
||||||
|
if (data>height) data=height;
|
||||||
|
wave1[i]=data;
|
||||||
|
output[i]=data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DivWaveSynth::changeWave2(int num) {
|
||||||
|
DivWavetable* w2=e->getWave(num);
|
||||||
|
for (int i=0; i<width; i++) {
|
||||||
|
if (w2->max<1 || w2->len<1) {
|
||||||
|
wave2[i]=0;
|
||||||
|
} else {
|
||||||
|
int data=w2->data[i*w2->len/width]*height/w2->max;
|
||||||
|
if (data<0) data=0;
|
||||||
|
if (data>height) data=height;
|
||||||
|
wave2[i]=data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
first=true;
|
||||||
|
}
|
||||||
|
|
||||||
void DivWaveSynth::setEngine(DivEngine* engine) {
|
void DivWaveSynth::setEngine(DivEngine* engine) {
|
||||||
e=engine;
|
e=engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) {
|
void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) {
|
||||||
if (e==NULL) return;
|
|
||||||
if (which==NULL) {
|
|
||||||
state=DivInstrumentWaveSynth();
|
|
||||||
}
|
|
||||||
state=which->ws;
|
|
||||||
width=w;
|
width=w;
|
||||||
height=h;
|
height=h;
|
||||||
|
if (width<0) width=0;
|
||||||
|
if (width>256) width=256;
|
||||||
|
if (e==NULL) return;
|
||||||
|
if (which==NULL) {
|
||||||
|
if (state.enabled) activeChangedB=true;
|
||||||
|
state=DivInstrumentWaveSynth();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!which->ws.enabled) {
|
||||||
|
if (state.enabled) activeChangedB=true;
|
||||||
|
state=DivInstrumentWaveSynth();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (!state.enabled) activeChangedB=true;
|
||||||
|
}
|
||||||
|
state=which->ws;
|
||||||
|
if (insChanged || !state.global) {
|
||||||
pos=0;
|
pos=0;
|
||||||
stage=0;
|
stage=0;
|
||||||
divCounter=0;
|
divCounter=1+state.rateDivider;
|
||||||
first=true;
|
first=true;
|
||||||
|
|
||||||
DivWavetable* w1=e->getWave(state.wave1);
|
changeWave1(state.wave1);
|
||||||
DivWavetable* w2=e->getWave(state.wave2);
|
changeWave2(state.wave2);
|
||||||
for (int i=0; i<width; i++) {
|
|
||||||
if (w1->max<1 || w1->len<1) {
|
|
||||||
wave1[i]=0;
|
|
||||||
} else {
|
|
||||||
int data=w1->data[i*w1->len/width]*height/w1->max;
|
|
||||||
if (data<0) data=0;
|
|
||||||
if (data>31) data=31;
|
|
||||||
wave1[i]=data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i=0; i<width; i++) {
|
|
||||||
if (w2->max<1 || w2->len<1) {
|
|
||||||
wave2[i]=0;
|
|
||||||
} else {
|
|
||||||
int data=w2->data[i*w2->len/width]*height/w2->max;
|
|
||||||
if (data<0) data=0;
|
|
||||||
if (data>31) data=31;
|
|
||||||
wave2[i]=data;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -29,16 +29,41 @@ class DivWaveSynth {
|
||||||
DivEngine* e;
|
DivEngine* e;
|
||||||
DivInstrumentWaveSynth state;
|
DivInstrumentWaveSynth state;
|
||||||
int pos, stage, divCounter, width, height;
|
int pos, stage, divCounter, width, height;
|
||||||
bool first;
|
bool first, activeChangedB;
|
||||||
unsigned char wave1[256];
|
unsigned char wave1[256];
|
||||||
unsigned char wave2[256];
|
unsigned char wave2[256];
|
||||||
int output[256];
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* the output.
|
||||||
|
*/
|
||||||
|
int output[256];
|
||||||
|
/**
|
||||||
|
* check whether the "active" status has changed.
|
||||||
|
* @return truth.
|
||||||
|
*/
|
||||||
|
bool activeChanged();
|
||||||
/**
|
/**
|
||||||
* tick this DivWaveSynth.
|
* tick this DivWaveSynth.
|
||||||
* @return whether the wave has changed.
|
* @return whether the wave has changed.
|
||||||
*/
|
*/
|
||||||
bool tick();
|
bool tick();
|
||||||
|
/**
|
||||||
|
* change the first wave.
|
||||||
|
* @param num wavetable number.
|
||||||
|
*/
|
||||||
|
void changeWave1(int num);
|
||||||
|
/**
|
||||||
|
* change the second wave.
|
||||||
|
* @param num wavetable number.
|
||||||
|
*/
|
||||||
|
void changeWave2(int num);
|
||||||
|
/**
|
||||||
|
* initialize this DivWaveSynth.
|
||||||
|
* @param which the instrument.
|
||||||
|
* @param width the system's wave width.
|
||||||
|
* @param height the system's wave height.
|
||||||
|
* @param insChanged whether the instrument has changed.
|
||||||
|
*/
|
||||||
void init(DivInstrument* which, int width, int height, bool insChanged=false);
|
void init(DivInstrument* which, int width, int height, bool insChanged=false);
|
||||||
void setEngine(DivEngine* engine);
|
void setEngine(DivEngine* engine);
|
||||||
DivWaveSynth():
|
DivWaveSynth():
|
||||||
|
@ -48,7 +73,8 @@ class DivWaveSynth {
|
||||||
divCounter(0),
|
divCounter(0),
|
||||||
width(32),
|
width(32),
|
||||||
height(31),
|
height(31),
|
||||||
first(false) {
|
first(false),
|
||||||
|
activeChangedB(false) {
|
||||||
memset(wave1,0,sizeof(int)*256);
|
memset(wave1,0,sizeof(int)*256);
|
||||||
memset(wave2,0,sizeof(int)*256);
|
memset(wave2,0,sizeof(int)*256);
|
||||||
memset(output,0,sizeof(int)*256);
|
memset(output,0,sizeof(int)*256);
|
||||||
|
|
|
@ -2418,6 +2418,8 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
|
|
||||||
ImGui::InputScalar("Amount",ImGuiDataType_U8,&ins->ws.param1,&_ONE,&_SEVEN);
|
ImGui::InputScalar("Amount",ImGuiDataType_U8,&ins->ws.param1,&_ONE,&_SEVEN);
|
||||||
|
|
||||||
|
ImGui::Checkbox("Global",&ins->ws.global);
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue