MSM5232: more options
This commit is contained in:
parent
76f0cceb55
commit
7b55ba4e77
|
@ -63,7 +63,7 @@ void DivPlatformMSM5232::acquire(short* bufL, short* bufR, size_t start, size_t
|
||||||
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
||||||
bufL[h]=0;
|
bufL[h]=0;
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
bufL[h]+=temp[i];
|
bufL[h]+=(temp[i]*partVolume[i])>>8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,6 +79,9 @@ const int decayMap[16]={
|
||||||
void DivPlatformMSM5232::tick(bool sysTick) {
|
void DivPlatformMSM5232::tick(bool sysTick) {
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
if (chan[i].std.vol.had) {
|
||||||
|
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&127,MIN(127,chan[i].std.vol.val),127);
|
||||||
|
}
|
||||||
if (chan[i].std.arp.had) {
|
if (chan[i].std.arp.had) {
|
||||||
if (!chan[i].inPorta) {
|
if (!chan[i].inPorta) {
|
||||||
chan[i].baseFreq=NOTE_LINEAR(parent->calcArp(chan[i].note,chan[i].std.arp.val));
|
chan[i].baseFreq=NOTE_LINEAR(parent->calcArp(chan[i].note,chan[i].std.arp.val));
|
||||||
|
@ -86,18 +89,39 @@ void DivPlatformMSM5232::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.duty.had) {
|
if (chan[i].std.duty.had) {
|
||||||
rWrite(12+(i>>2),chan[i].std.duty.val);
|
groupControl[i>>2]=(chan[i].std.duty.val&0x1f)|(groupEnv[i>>2]?0x20:0);
|
||||||
|
updateGroup[i>>2]=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.ex1.had) { // attack
|
if (chan[i].std.ex1.had) { // attack
|
||||||
rWrite(8+(i>>2),attackMap[chan[i].std.ex1.val&7]);
|
groupAR[i>>2]=attackMap[chan[i].std.ex1.val&7];
|
||||||
|
updateGroupAR[i>>2]=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.ex2.had) { // decay
|
if (chan[i].std.ex2.had) { // decay
|
||||||
rWrite(10+(i>>2),decayMap[chan[i].std.ex2.val&15]);
|
groupDR[i>>2]=decayMap[chan[i].std.ex2.val&15];
|
||||||
|
updateGroupDR[i>>2]=true;
|
||||||
}
|
}
|
||||||
if (chan[i].std.ex3.had) { // noise
|
if (chan[i].std.ex3.had) { // noise
|
||||||
chan[i].noise=chan[i].std.ex3.val;
|
chan[i].noise=chan[i].std.ex3.val;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<2; i++) {
|
||||||
|
if (updateGroup[i]) {
|
||||||
|
rWrite(12+i,groupControl[i]);
|
||||||
|
updateGroup[i]=false;
|
||||||
|
}
|
||||||
|
if (updateGroupAR[i]) {
|
||||||
|
rWrite(8+i,groupAR[i]);
|
||||||
|
updateGroupAR[i]=false;
|
||||||
|
}
|
||||||
|
if (updateGroupDR[i]) {
|
||||||
|
rWrite(10+i,groupDR[i]);
|
||||||
|
updateGroupDR[i]=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<8; 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,DIV_INS_PCE);
|
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE);
|
||||||
chan[i].freq=chan[i].baseFreq+chan[i].pitch+chan[i].pitch2-(12<<7);
|
chan[i].freq=chan[i].baseFreq+chan[i].pitch+chan[i].pitch2-(12<<7);
|
||||||
|
@ -118,6 +142,17 @@ void DivPlatformMSM5232::tick(bool sysTick) {
|
||||||
chan[i].freqChanged=false;
|
chan[i].freqChanged=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msm->set_vol_input(
|
||||||
|
chan[0].active?((double)chan[0].outVol/127.0):0.0,
|
||||||
|
chan[1].active?((double)chan[1].outVol/127.0):0.0,
|
||||||
|
chan[2].active?((double)chan[2].outVol/127.0):0.0,
|
||||||
|
chan[3].active?((double)chan[3].outVol/127.0):0.0,
|
||||||
|
chan[4].active?((double)chan[4].outVol/127.0):0.0,
|
||||||
|
chan[5].active?((double)chan[5].outVol/127.0):0.0,
|
||||||
|
chan[6].active?((double)chan[6].outVol/127.0):0.0,
|
||||||
|
chan[7].active?((double)chan[7].outVol/127.0):0.0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivPlatformMSM5232::dispatch(DivCommand c) {
|
int DivPlatformMSM5232::dispatch(DivCommand c) {
|
||||||
|
@ -158,9 +193,6 @@ int DivPlatformMSM5232::dispatch(DivCommand c) {
|
||||||
chan[c.chan].vol=c.value;
|
chan[c.chan].vol=c.value;
|
||||||
if (!chan[c.chan].std.vol.has) {
|
if (!chan[c.chan].std.vol.has) {
|
||||||
chan[c.chan].outVol=c.value;
|
chan[c.chan].outVol=c.value;
|
||||||
if (chan[c.chan].active) {
|
|
||||||
//chWrite(c.chan,0x04,0x80|chan[c.chan].outVol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -199,6 +231,7 @@ int DivPlatformMSM5232::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
case DIV_CMD_STD_NOISE_MODE:
|
case DIV_CMD_STD_NOISE_MODE:
|
||||||
chan[c.chan].noise=c.value;
|
chan[c.chan].noise=c.value;
|
||||||
|
chan[c.chan].freqChanged=true;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_LEGATO:
|
case DIV_CMD_LEGATO:
|
||||||
chan[c.chan].baseFreq=NOTE_LINEAR(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0)));
|
chan[c.chan].baseFreq=NOTE_LINEAR(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0)));
|
||||||
|
@ -213,7 +246,7 @@ int DivPlatformMSM5232::dispatch(DivCommand c) {
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 1;
|
return 127;
|
||||||
break;
|
break;
|
||||||
case DIV_ALWAYS_SET_VOLUME:
|
case DIV_ALWAYS_SET_VOLUME:
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -234,6 +267,11 @@ void DivPlatformMSM5232::forceIns() {
|
||||||
chan[i].insChanged=true;
|
chan[i].insChanged=true;
|
||||||
chan[i].freqChanged=true;
|
chan[i].freqChanged=true;
|
||||||
}
|
}
|
||||||
|
for (int i=0; i<2; i++) {
|
||||||
|
updateGroup[i]=true;
|
||||||
|
updateGroupAR[i]=true;
|
||||||
|
updateGroupDR[i]=true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* DivPlatformMSM5232::getChanState(int ch) {
|
void* DivPlatformMSM5232::getChanState(int ch) {
|
||||||
|
@ -272,15 +310,20 @@ void DivPlatformMSM5232::reset() {
|
||||||
cycles=0;
|
cycles=0;
|
||||||
curChan=-1;
|
curChan=-1;
|
||||||
delay=500;
|
delay=500;
|
||||||
rWrite(8,0);
|
|
||||||
rWrite(9,0);
|
for (int i=0; i<2; i++) {
|
||||||
rWrite(10,5);
|
groupControl[i]=15|(groupEnv[i]?0x20:0);
|
||||||
rWrite(11,5);
|
groupAR[i]=0;
|
||||||
rWrite(12,0x2f);
|
groupDR[i]=5;
|
||||||
rWrite(13,0x2f);
|
|
||||||
|
updateGroup[i]=true;
|
||||||
|
updateGroupAR[i]=true;
|
||||||
|
updateGroupDR[i]=true;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
rWrite(i,0);
|
rWrite(i,0);
|
||||||
|
partVolume[i]=initPartVolume[i];
|
||||||
msm->mute(i,isMuted[i]);
|
msm->mute(i,isMuted[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,6 +350,37 @@ void DivPlatformMSM5232::setFlags(const DivConfig& flags) {
|
||||||
for (int i=0; i<8; i++) {
|
for (int i=0; i<8; i++) {
|
||||||
oscBuf[i]->rate=rate;
|
oscBuf[i]->rate=rate;
|
||||||
}
|
}
|
||||||
|
initPartVolume[0]=flags.getInt("partVolume0",255);
|
||||||
|
initPartVolume[1]=flags.getInt("partVolume1",255);
|
||||||
|
initPartVolume[2]=flags.getInt("partVolume2",255);
|
||||||
|
initPartVolume[3]=flags.getInt("partVolume3",255);
|
||||||
|
initPartVolume[4]=flags.getInt("partVolume4",255);
|
||||||
|
initPartVolume[5]=flags.getInt("partVolume5",255);
|
||||||
|
initPartVolume[6]=flags.getInt("partVolume6",255);
|
||||||
|
initPartVolume[7]=flags.getInt("partVolume7",255);
|
||||||
|
|
||||||
|
capacitance[0]=flags.getFloat("capValue0",390.0f);
|
||||||
|
capacitance[1]=flags.getFloat("capValue1",390.0f);
|
||||||
|
capacitance[2]=flags.getFloat("capValue2",390.0f);
|
||||||
|
capacitance[3]=flags.getFloat("capValue3",390.0f);
|
||||||
|
capacitance[4]=flags.getFloat("capValue4",390.0f);
|
||||||
|
capacitance[5]=flags.getFloat("capValue5",390.0f);
|
||||||
|
capacitance[6]=flags.getFloat("capValue6",390.0f);
|
||||||
|
capacitance[7]=flags.getFloat("capValue7",390.0f);
|
||||||
|
|
||||||
|
groupEnv[0]=flags.getBool("groupEnv0",true);
|
||||||
|
groupEnv[1]=flags.getBool("groupEnv1",true);
|
||||||
|
|
||||||
|
msm->set_capacitors(
|
||||||
|
capacitance[0]*0.000000001,
|
||||||
|
capacitance[1]*0.000000001,
|
||||||
|
capacitance[2]*0.000000001,
|
||||||
|
capacitance[3]*0.000000001,
|
||||||
|
capacitance[4]*0.000000001,
|
||||||
|
capacitance[5]*0.000000001,
|
||||||
|
capacitance[6]*0.000000001,
|
||||||
|
capacitance[7]*0.000000001
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformMSM5232::poke(unsigned int addr, unsigned short val) {
|
void DivPlatformMSM5232::poke(unsigned int addr, unsigned short val) {
|
||||||
|
@ -326,7 +400,6 @@ int DivPlatformMSM5232::init(DivEngine* p, int channels, int sugRate, const DivC
|
||||||
oscBuf[i]=new DivDispatchOscBuffer;
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
msm=new msm5232_device(2119040);
|
msm=new msm5232_device(2119040);
|
||||||
msm->set_capacitors(0.39e-6,0.39e-6,0.39e-6,0.39e-6,0.39e-6,0.39e-6,0.39e-6,0.39e-6);
|
|
||||||
msm->device_start();
|
msm->device_start();
|
||||||
setFlags(flags);
|
setFlags(flags);
|
||||||
reset();
|
reset();
|
||||||
|
|
|
@ -50,12 +50,22 @@ class DivPlatformMSM5232: public DivDispatch {
|
||||||
keyOff(false),
|
keyOff(false),
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
noise(false),
|
noise(false),
|
||||||
vol(1),
|
vol(127),
|
||||||
outVol(1) {}
|
outVol(127) {}
|
||||||
};
|
};
|
||||||
Channel chan[8];
|
Channel chan[8];
|
||||||
DivDispatchOscBuffer* oscBuf[8];
|
DivDispatchOscBuffer* oscBuf[8];
|
||||||
|
int partVolume[8];
|
||||||
|
int initPartVolume[8];
|
||||||
|
double capacitance[8];
|
||||||
bool isMuted[8];
|
bool isMuted[8];
|
||||||
|
bool updateGroup[2];
|
||||||
|
bool updateGroupAR[2];
|
||||||
|
bool updateGroupDR[2];
|
||||||
|
bool groupEnv[2];
|
||||||
|
unsigned char groupControl[2];
|
||||||
|
unsigned char groupAR[2];
|
||||||
|
unsigned char groupDR[2];
|
||||||
struct QueuedWrite {
|
struct QueuedWrite {
|
||||||
unsigned char addr;
|
unsigned char addr;
|
||||||
unsigned char val;
|
unsigned char val;
|
||||||
|
|
|
@ -79,6 +79,18 @@ void msm5232_device::set_capacitors(double cap1, double cap2, double cap3, doubl
|
||||||
m_external_capacity[7] = cap8;
|
m_external_capacity[7] = cap8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void msm5232_device::set_vol_input(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8)
|
||||||
|
{
|
||||||
|
m_external_input[0] = v1;
|
||||||
|
m_external_input[1] = v2;
|
||||||
|
m_external_input[2] = v3;
|
||||||
|
m_external_input[3] = v4;
|
||||||
|
m_external_input[4] = v5;
|
||||||
|
m_external_input[5] = v6;
|
||||||
|
m_external_input[6] = v7;
|
||||||
|
m_external_input[7] = v8;
|
||||||
|
}
|
||||||
|
|
||||||
/* Default chip clock is 2119040 Hz */
|
/* Default chip clock is 2119040 Hz */
|
||||||
/* At this clock chip generates exactly 440.0 Hz signal on 8' output when pitch data=0x21 */
|
/* At this clock chip generates exactly 440.0 Hz signal on 8' output when pitch data=0x21 */
|
||||||
|
|
||||||
|
@ -224,6 +236,7 @@ void msm5232_device::init_voice(int i)
|
||||||
m_voi[i].eg_sect= -1;
|
m_voi[i].eg_sect= -1;
|
||||||
m_voi[i].eg = 0.0;
|
m_voi[i].eg = 0.0;
|
||||||
m_voi[i].eg_arm = 0;
|
m_voi[i].eg_arm = 0;
|
||||||
|
m_voi[i].eg_ext = 0;
|
||||||
m_voi[i].pitch = -1.0;
|
m_voi[i].pitch = -1.0;
|
||||||
m_voi[i].mute = false;
|
m_voi[i].mute = false;
|
||||||
}
|
}
|
||||||
|
@ -366,6 +379,7 @@ void msm5232_device::write(unsigned int offset, uint8_t data)
|
||||||
if ( (data&0x10) && (m_voi[i].eg_sect == 1) )
|
if ( (data&0x10) && (m_voi[i].eg_sect == 1) )
|
||||||
m_voi[i].eg_sect = 0;
|
m_voi[i].eg_sect = 0;
|
||||||
m_voi[i].eg_arm = data&0x10;
|
m_voi[i].eg_arm = data&0x10;
|
||||||
|
m_voi[i].eg_ext = !(data&0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EN_out16[0] = (data&1) ? ~0:0;
|
m_EN_out16[0] = (data&1) ? ~0:0;
|
||||||
|
@ -391,6 +405,7 @@ void msm5232_device::write(unsigned int offset, uint8_t data)
|
||||||
if ( (data&0x10) && (m_voi[i+4].eg_sect == 1) )
|
if ( (data&0x10) && (m_voi[i+4].eg_sect == 1) )
|
||||||
m_voi[i+4].eg_sect = 0;
|
m_voi[i+4].eg_sect = 0;
|
||||||
m_voi[i+4].eg_arm = data&0x10;
|
m_voi[i+4].eg_arm = data&0x10;
|
||||||
|
m_voi[i+4].eg_ext = !(data&0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EN_out16[1] = (data&1) ? ~0:0;
|
m_EN_out16[1] = (data&1) ? ~0:0;
|
||||||
|
@ -418,90 +433,94 @@ void msm5232_device::EG_voices_advance()
|
||||||
i = 8;
|
i = 8;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
switch(voi->eg_sect)
|
if (voi->eg_ext) {
|
||||||
{
|
voi->egvol=m_external_input[8-i]*2048.0;
|
||||||
case 0: /* attack */
|
} else {
|
||||||
|
switch(voi->eg_sect)
|
||||||
|
{
|
||||||
|
case 0: /* attack */
|
||||||
|
|
||||||
/* capacitor charge */
|
/* capacitor charge */
|
||||||
if (voi->eg < VMAX)
|
if (voi->eg < VMAX)
|
||||||
{
|
{
|
||||||
voi->counter -= (int)((VMAX - voi->eg) / voi->ar_rate);
|
voi->counter -= (int)((VMAX - voi->eg) / voi->ar_rate);
|
||||||
if ( voi->counter <= 0 )
|
if ( voi->counter <= 0 )
|
||||||
{
|
{
|
||||||
int n = -voi->counter / samplerate + 1;
|
int n = -voi->counter / samplerate + 1;
|
||||||
voi->counter += n * samplerate;
|
voi->counter += n * samplerate;
|
||||||
if ( (voi->eg += n) > VMAX )
|
if ( (voi->eg += n) > VMAX )
|
||||||
voi->eg = VMAX;
|
voi->eg = VMAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when ARM=0, EG switches to decay as soon as cap is charged to VT (EG inversion voltage; about 80% of MAX) */
|
/* when ARM=0, EG switches to decay as soon as cap is charged to VT (EG inversion voltage; about 80% of MAX) */
|
||||||
if (!voi->eg_arm)
|
if (!voi->eg_arm)
|
||||||
{
|
{
|
||||||
if(voi->eg >= VMAX * 80/100 )
|
if(voi->eg >= VMAX * 80/100 )
|
||||||
{
|
{
|
||||||
voi->eg_sect = 1;
|
voi->eg_sect = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* ARM=1 */
|
/* ARM=1 */
|
||||||
{
|
{
|
||||||
/* when ARM=1, EG stays at maximum until key off */
|
/* when ARM=1, EG stays at maximum until key off */
|
||||||
}
|
}
|
||||||
|
|
||||||
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: /* decay */
|
case 1: /* decay */
|
||||||
|
|
||||||
/* capacitor discharge */
|
/* capacitor discharge */
|
||||||
if (voi->eg > VMIN)
|
if (voi->eg > VMIN)
|
||||||
{
|
{
|
||||||
voi->counter -= (int)((voi->eg - VMIN) / voi->dr_rate);
|
voi->counter -= (int)((voi->eg - VMIN) / voi->dr_rate);
|
||||||
if ( voi->counter <= 0 )
|
if ( voi->counter <= 0 )
|
||||||
{
|
{
|
||||||
int n = -voi->counter / samplerate + 1;
|
int n = -voi->counter / samplerate + 1;
|
||||||
voi->counter += n * samplerate;
|
voi->counter += n * samplerate;
|
||||||
if ( (voi->eg -= n) < VMIN )
|
if ( (voi->eg -= n) < VMIN )
|
||||||
voi->eg = VMIN;
|
voi->eg = VMIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* voi->eg <= VMIN */
|
else /* voi->eg <= VMIN */
|
||||||
{
|
{
|
||||||
voi->eg_sect =-1;
|
voi->eg_sect =-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* release */
|
case 2: /* release */
|
||||||
|
|
||||||
/* capacitor discharge */
|
/* capacitor discharge */
|
||||||
if (voi->eg > VMIN)
|
if (voi->eg > VMIN)
|
||||||
{
|
{
|
||||||
voi->counter -= (int)((voi->eg - VMIN) / voi->rr_rate);
|
voi->counter -= (int)((voi->eg - VMIN) / voi->rr_rate);
|
||||||
if ( voi->counter <= 0 )
|
if ( voi->counter <= 0 )
|
||||||
{
|
{
|
||||||
int n = -voi->counter / samplerate + 1;
|
int n = -voi->counter / samplerate + 1;
|
||||||
voi->counter += n * samplerate;
|
voi->counter += n * samplerate;
|
||||||
if ( (voi->eg -= n) < VMIN )
|
if ( (voi->eg -= n) < VMIN )
|
||||||
voi->eg = VMIN;
|
voi->eg = VMIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* voi->eg <= VMIN */
|
else /* voi->eg <= VMIN */
|
||||||
{
|
{
|
||||||
voi->eg_sect =-1;
|
voi->eg_sect =-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
voi->egvol = voi->eg / 16; /*32768/16 = 2048 max*/
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
voi++;
|
voi++;
|
||||||
i--;
|
i--;
|
||||||
|
|
|
@ -15,6 +15,7 @@ public:
|
||||||
msm5232_device(uint32_t clock);
|
msm5232_device(uint32_t clock);
|
||||||
|
|
||||||
void set_capacitors(double cap1, double cap2, double cap3, double cap4, double cap5, double cap6, double cap7, double cap8);
|
void set_capacitors(double cap1, double cap2, double cap3, double cap4, double cap5, double cap6, double cap7, double cap8);
|
||||||
|
void set_vol_input(double v1, double v2, double v3, double v4, double v5, double v6, double v7, double v8);
|
||||||
//auto gate() { return m_gate_handler_cb.bind(); }
|
//auto gate() { return m_gate_handler_cb.bind(); }
|
||||||
|
|
||||||
void write(unsigned int offset, uint8_t data);
|
void write(unsigned int offset, uint8_t data);
|
||||||
|
@ -52,6 +53,7 @@ private:
|
||||||
int eg;
|
int eg;
|
||||||
|
|
||||||
uint8_t eg_arm; /* attack/release mode */
|
uint8_t eg_arm; /* attack/release mode */
|
||||||
|
uint8_t eg_ext; /* inhibit envelope generator */
|
||||||
|
|
||||||
double ar_rate;
|
double ar_rate;
|
||||||
double dr_rate;
|
double dr_rate;
|
||||||
|
@ -90,6 +92,7 @@ private:
|
||||||
uint32_t m_clock;
|
uint32_t m_clock;
|
||||||
|
|
||||||
double m_external_capacity[8]; /* in Farads, eg 0.39e-6 = 0.36 uF (microFarads) */
|
double m_external_capacity[8]; /* in Farads, eg 0.39e-6 = 0.36 uF (microFarads) */
|
||||||
|
double m_external_input[8];
|
||||||
std::function<void(int)> m_gate_handler_cb;/* callback called when the GATE output pin changes state */
|
std::function<void(int)> m_gate_handler_cb;/* callback called when the GATE output pin changes state */
|
||||||
|
|
||||||
void init_tables();
|
void init_tables();
|
||||||
|
|
|
@ -243,7 +243,7 @@ const char* mikeyFeedbackBits[11] = {
|
||||||
"0", "1", "2", "3", "4", "5", "7", "10", "11", "int", NULL
|
"0", "1", "2", "3", "4", "5", "7", "10", "11", "int", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* msm5232ControlBits[6]={
|
const char* msm5232ControlBits[7]={
|
||||||
"2'", "4'", "8'", "16'", "sustain", NULL
|
"2'", "4'", "8'", "16'", "sustain", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4311,7 +4311,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY ||
|
if (ins->type==DIV_INS_FM || ins->type==DIV_INS_SEGAPCM || ins->type==DIV_INS_MIKEY ||
|
||||||
ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ ||
|
ins->type==DIV_INS_MULTIPCM || ins->type==DIV_INS_SU || ins->type==DIV_INS_OPZ ||
|
||||||
ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES) {
|
ins->type==DIV_INS_OPM || ins->type==DIV_INS_SNES || ins->type==DIV_INS_MSM5232) {
|
||||||
volMax=127;
|
volMax=127;
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_GB) {
|
if (ins->type==DIV_INS_GB) {
|
||||||
|
@ -4330,7 +4330,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
if (ins->type==DIV_INS_ES5506) {
|
if (ins->type==DIV_INS_ES5506) {
|
||||||
volMax=65535;
|
volMax=65535;
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_MSM6258 || ins->type==DIV_INS_MSM5232) {
|
if (ins->type==DIV_INS_MSM6258) {
|
||||||
volMax=0;
|
volMax=0;
|
||||||
}
|
}
|
||||||
if (ins->type==DIV_INS_MSM6295) {
|
if (ins->type==DIV_INS_MSM6295) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
|
||||||
bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool modifyOnChange) {
|
bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool modifyOnChange) {
|
||||||
bool altered=false;
|
bool altered=false;
|
||||||
|
@ -1292,6 +1293,28 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
}
|
}
|
||||||
case DIV_SYSTEM_MSM5232: {
|
case DIV_SYSTEM_MSM5232: {
|
||||||
int detune=flags.getInt("detune",0);
|
int detune=flags.getInt("detune",0);
|
||||||
|
bool groupEnv[2];
|
||||||
|
int groupVol[8];
|
||||||
|
float capValue[8];
|
||||||
|
char temp[64];
|
||||||
|
groupEnv[0]=flags.getBool("groupEnv0",true);
|
||||||
|
groupEnv[1]=flags.getBool("groupEnv1",true);
|
||||||
|
groupVol[0]=flags.getInt("partVolume0",255);
|
||||||
|
groupVol[1]=flags.getInt("partVolume1",255);
|
||||||
|
groupVol[2]=flags.getInt("partVolume2",255);
|
||||||
|
groupVol[3]=flags.getInt("partVolume3",255);
|
||||||
|
groupVol[4]=flags.getInt("partVolume4",255);
|
||||||
|
groupVol[5]=flags.getInt("partVolume5",255);
|
||||||
|
groupVol[6]=flags.getInt("partVolume6",255);
|
||||||
|
groupVol[7]=flags.getInt("partVolume7",255);
|
||||||
|
capValue[0]=flags.getFloat("capValue0",390.0f);
|
||||||
|
capValue[1]=flags.getFloat("capValue1",390.0f);
|
||||||
|
capValue[2]=flags.getFloat("capValue2",390.0f);
|
||||||
|
capValue[3]=flags.getFloat("capValue3",390.0f);
|
||||||
|
capValue[4]=flags.getFloat("capValue4",390.0f);
|
||||||
|
capValue[5]=flags.getFloat("capValue5",390.0f);
|
||||||
|
capValue[6]=flags.getFloat("capValue6",390.0f);
|
||||||
|
capValue[7]=flags.getFloat("capValue7",390.0f);
|
||||||
|
|
||||||
if (CWSliderInt("Detune",&detune,-127,127)) {
|
if (CWSliderInt("Detune",&detune,-127,127)) {
|
||||||
if (detune<-127) detune=-127;
|
if (detune<-127) detune=-127;
|
||||||
|
@ -1299,8 +1322,79 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
|
||||||
altered=true;
|
altered=true;
|
||||||
} rightClickable
|
} rightClickable
|
||||||
|
|
||||||
|
ImGui::Text("Capacitor values (nF):");
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
snprintf(temp,63,"%d##CAPV%d",i+1,i);
|
||||||
|
if (CWSliderFloat(temp,&capValue[i],1.0f,1000.0f)) {
|
||||||
|
if (capValue[i]<0) capValue[i]=0;
|
||||||
|
if (capValue[i]>1000) capValue[i]=1000;
|
||||||
|
altered=true;
|
||||||
|
} rightClickable
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Initial part volume (channel 1-4):");
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
snprintf(temp,63,"%d'##GRPV%d",16>>i,i);
|
||||||
|
if (CWSliderInt(temp,&groupVol[i],0,255)) {
|
||||||
|
if (groupVol[i]<0) groupVol[i]=0;
|
||||||
|
if (groupVol[i]>255) groupVol[i]=255;
|
||||||
|
altered=true;
|
||||||
|
} rightClickable
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Initial part volume (channel 5-8):");
|
||||||
|
for (int i=4; i<8; i++) {
|
||||||
|
snprintf(temp,63,"%d'##GRPV%d",16>>(i-4),i);
|
||||||
|
if (CWSliderInt(temp,&groupVol[i],0,255)) {
|
||||||
|
if (groupVol[i]<0) groupVol[i]=0;
|
||||||
|
if (groupVol[i]>255) groupVol[i]=255;
|
||||||
|
altered=true;
|
||||||
|
} rightClickable
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Envelope mode (channel 1-4):");
|
||||||
|
if (ImGui::RadioButton("Capacitor (attack/decay)##EM00",groupEnv[0])) {
|
||||||
|
groupEnv[0]=true;
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("External (volume macro)##EM01",!groupEnv[0])) {
|
||||||
|
groupEnv[0]=false;
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Envelope mode (channel 5-8):");
|
||||||
|
if (ImGui::RadioButton("Capacitor (attack/decay)##EM10",groupEnv[1])) {
|
||||||
|
groupEnv[1]=true;
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
if (ImGui::RadioButton("External (volume macro)##EM11",!groupEnv[1])) {
|
||||||
|
groupEnv[1]=false;
|
||||||
|
altered=true;
|
||||||
|
}
|
||||||
|
|
||||||
if (altered) {
|
if (altered) {
|
||||||
flags.set("detune",detune);
|
flags.set("detune",detune);
|
||||||
|
|
||||||
|
flags.set("capValue0",capValue[0]);
|
||||||
|
flags.set("capValue1",capValue[1]);
|
||||||
|
flags.set("capValue2",capValue[2]);
|
||||||
|
flags.set("capValue3",capValue[3]);
|
||||||
|
flags.set("capValue4",capValue[4]);
|
||||||
|
flags.set("capValue5",capValue[5]);
|
||||||
|
flags.set("capValue6",capValue[6]);
|
||||||
|
flags.set("capValue7",capValue[7]);
|
||||||
|
|
||||||
|
flags.set("partVolume0",groupVol[0]);
|
||||||
|
flags.set("partVolume1",groupVol[1]);
|
||||||
|
flags.set("partVolume2",groupVol[2]);
|
||||||
|
flags.set("partVolume3",groupVol[3]);
|
||||||
|
flags.set("partVolume4",groupVol[4]);
|
||||||
|
flags.set("partVolume5",groupVol[5]);
|
||||||
|
flags.set("partVolume6",groupVol[6]);
|
||||||
|
flags.set("partVolume7",groupVol[7]);
|
||||||
|
|
||||||
|
flags.set("groupEnv0",groupEnv[0]);
|
||||||
|
flags.set("groupEnv1",groupEnv[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue