add different clock speed, optimize channel processing, add quarter clock speed flag
This commit is contained in:
parent
802f55a26e
commit
6417da27e9
|
@ -90,16 +90,6 @@ void DivPlatformSID3::acquire(short** buf, size_t len)
|
|||
|
||||
int dacData=s->data16[chan[SID3_NUM_CHANNELS - 1].dacPos] + 32767;
|
||||
chan[SID3_NUM_CHANNELS - 1].dacOut=CLAMP(dacData,0,65535);
|
||||
/*if (!isMuted[SID3_NUM_CHANNELS - 1])
|
||||
{
|
||||
sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut >> 8);
|
||||
sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, chan[SID3_NUM_CHANNELS - 1].dacOut & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_HIGH + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 >> 8);
|
||||
sid3_write(sid3, SID3_REGISTER_STREAMED_SAMPLE_LOW + (SID3_NUM_CHANNELS - 1) * SID3_REGISTERS_PER_CHANNEL, 32768 & 0xff);
|
||||
}*/
|
||||
updateSample = true;
|
||||
sampleTick = 0;
|
||||
|
||||
|
@ -1121,7 +1111,16 @@ void DivPlatformSID3::poke(std::vector<DivRegWrite>& wlist) {
|
|||
void DivPlatformSID3::setFlags(const DivConfig& flags) {
|
||||
chipClock=1000000;
|
||||
CHECK_CUSTOM_CLOCK;
|
||||
|
||||
quarterClock=flags.getBool("quarterClock",false);
|
||||
|
||||
if(quarterClock && chipClock >= 1000000 && !parent->isExporting())
|
||||
{
|
||||
chipClock /= 4;
|
||||
}
|
||||
|
||||
rate=chipClock;
|
||||
sid3_set_clock_rate(sid3, chipClock);
|
||||
for (int i=0; i<SID3_NUM_CHANNELS; i++) {
|
||||
oscBuf[i]->rate=rate/8;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ class DivPlatformSID3: public DivDispatch {
|
|||
|
||||
unsigned char sampleTick; //used to update streamed sample and not clash with other reg writes at high rate samples
|
||||
bool updateSample;
|
||||
bool quarterClock;
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
|
|
@ -13,9 +13,9 @@ enum State { ATTACK, DECAY, SUSTAIN, RELEASE }; //for envelope
|
|||
#define envspd_factor_a_sr 10
|
||||
#define envspd_factor_dr 15
|
||||
|
||||
#define envspd_a(rate) ((uint64_t)0xff0000 / ((rate == 0 ? 1 : (rate * envspd_factor_a_sr)) * (rate == 0 ? 1 : (rate * envspd_factor_a_sr))))
|
||||
#define envspd_dr(rate) ((uint64_t)0xff0000 / ((rate == 0 ? 1 : (rate * envspd_factor_dr)) * (rate == 0 ? 1 : (rate * envspd_factor_dr))))
|
||||
#define envspd_sr(rate) (rate == 0 ? 0 : ((uint64_t)0xff0000 / ((256 - rate) * (256 - rate) * envspd_factor_a_sr * envspd_factor_a_sr)))
|
||||
#define envspd_a(rate) ((uint64_t)0xff0000 / ((rate == 0 ? 1 : (rate * envspd_factor_a_sr)) * (rate == 0 ? 1 : (rate * envspd_factor_a_sr * ((float)sid3->clock_rate / 1000000.0)))))
|
||||
#define envspd_dr(rate) ((uint64_t)0xff0000 / ((rate == 0 ? 1 : (rate * envspd_factor_dr)) * (rate == 0 ? 1 : (rate * envspd_factor_dr * ((float)sid3->clock_rate / 1000000.0)))))
|
||||
#define envspd_sr(rate) (rate == 0 ? 0 : ((uint64_t)0xff0000 / ((256 - rate) * (256 - rate) * envspd_factor_a_sr * envspd_factor_a_sr * ((float)sid3->clock_rate / 1000000.0))))
|
||||
|
||||
//these 4 ones are util only
|
||||
double square(double x) {
|
||||
|
@ -2352,21 +2352,27 @@ void sid3_reset(SID3* sid3)
|
|||
for(int32_t i = 0; i < SID3_NUM_CHANNELS - 1; i++)
|
||||
{
|
||||
memset(&sid3->chan[i], 0, sizeof(sid3_channel));
|
||||
/*sid3->chan[i].accumulator = 0;
|
||||
sid3->chan[i].adsr.a = 0x20;
|
||||
sid3->chan[i].adsr.d = 0x20;
|
||||
sid3->chan[i].adsr.s = 0x80;
|
||||
sid3->chan[i].adsr.r = 0x17;
|
||||
sid3->chan[i].adsr.vol = 0xf0;*/
|
||||
sid3->chan[i].adsr.hold_zero = true;
|
||||
sid3->chan[i].lfsr = 0x1;
|
||||
sid3->chan[i].lfsr_taps = (1 << 29) | (1 << 5) | (1 << 3) | 1; //https://docs.amd.com/v/u/en-US/xapp052 for 30 bits: 30, 6, 4, 1
|
||||
//....
|
||||
|
||||
for(int j = 0; j < SID3_NUM_FILTERS; j++)
|
||||
{
|
||||
sid3->chan[i].filt.filt[j].Vlp = 0;
|
||||
sid3->chan[i].filt.filt[j].Vbp = 0;
|
||||
sid3->chan[i].filt.filt[j].Vhp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: wavetable chan
|
||||
memset(&sid3->wave_chan, 0, sizeof(sid3_wavetable_chan));
|
||||
sid3->wave_chan.adsr.hold_zero = true;
|
||||
|
||||
for(int j = 0; j < SID3_NUM_FILTERS; j++)
|
||||
{
|
||||
sid3->wave_chan.filt.filt[j].Vlp = 0;
|
||||
sid3->wave_chan.filt.filt[j].Vbp = 0;
|
||||
sid3->wave_chan.filt.filt[j].Vhp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sid3_gate_bit(SID3* sid3, uint8_t gate, sid3_channel_adsr* adsr)
|
||||
|
@ -2404,7 +2410,7 @@ void sid3_gate_bit(SID3* sid3, uint8_t gate, sid3_channel_adsr* adsr)
|
|||
if(adsr->envelope_counter > 0xff0000) adsr->envelope_counter = 0xff0000;
|
||||
}
|
||||
|
||||
void sid3_adsr_clock(sid3_channel_adsr* adsr)
|
||||
void sid3_adsr_clock(SID3* sid3, sid3_channel_adsr* adsr)
|
||||
{
|
||||
// Check whether the envelope counter is frozen at zero.
|
||||
if (adsr->hold_zero)
|
||||
|
@ -2478,16 +2484,16 @@ int32_t sid3_adsr_output(SID3* sid3, sid3_channel_adsr* adsr, int32_t input)
|
|||
}
|
||||
}
|
||||
|
||||
void sid3_set_filter_settings(sid3_filter* filt)
|
||||
void sid3_set_filter_settings(SID3* sid3, sid3_filter* filt)
|
||||
{
|
||||
const double pi = 3.1415926535897932385;
|
||||
|
||||
// Multiply with 1.048576 to facilitate division by 1 000 000 by right-
|
||||
// shifting 20 times (2 ^ 20 = 1048576).
|
||||
filt->w0 = (2.0*pi*(float)filt->cutoff) / 500000.0 / 5.0; // "/ 5.0" bc we have 16 bit cutoff instead of 12-bit
|
||||
filt->w0 = (2.0*pi*(float)filt->cutoff) / ((double)sid3->clock_rate / 2.0) / 5.0; // "/ 5.0" bc we have 16 bit cutoff instead of 12-bit
|
||||
|
||||
// Limit f0 to 16kHz to keep 1 cycle filter stable.
|
||||
const float w0_max_1 = (2.0*pi*20000.0) / 500000.0;
|
||||
const float w0_max_1 = (2.0*pi*20000.0) / ((double)sid3->clock_rate / 2.0);
|
||||
filt->w0_ceil_1 = filt->w0 <= w0_max_1 ? filt->w0 : w0_max_1;
|
||||
|
||||
filt->_1024_div_Q = (1.0/(0.707 + 4.0*(float)filt->resonance/(float)0x0ff));
|
||||
|
@ -3052,67 +3058,100 @@ void sid3_clock(SID3* sid3)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t acc_state = ch->accumulator;
|
||||
uint32_t noise_acc_state = ch->noise_accumulator;
|
||||
int32_t waveform = 0;
|
||||
|
||||
if(ch->flags & SID3_CHAN_ENABLE_PHASE_MOD)
|
||||
if(!ch->adsr.hold_zero)
|
||||
{
|
||||
ch->accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
ch->noise_accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
}
|
||||
uint32_t acc_state = ch->accumulator;
|
||||
uint32_t noise_acc_state = ch->noise_accumulator;
|
||||
|
||||
if(ch->feedback)
|
||||
{
|
||||
ch->accumulator += (ch->prev_output + ch->prev_output2) * ch->feedback;
|
||||
}
|
||||
if(ch->flags & SID3_CHAN_ENABLE_PHASE_MOD)
|
||||
{
|
||||
ch->accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
ch->noise_accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
}
|
||||
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
if(ch->feedback)
|
||||
{
|
||||
ch->accumulator += (ch->prev_output + ch->prev_output2) * ch->feedback;
|
||||
}
|
||||
|
||||
if((prev_noise_acc & ((uint32_t)1 << (SID3_ACC_BITS - 6))) != (ch->noise_accumulator & ((uint32_t)1 << (SID3_ACC_BITS - 6))))
|
||||
{
|
||||
sid3_clock_lfsr(ch);
|
||||
}
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
ch->noise_accumulator &= SID3_ACC_MASK;
|
||||
|
||||
int32_t waveform = sid3_get_waveform(sid3, ch);
|
||||
if((prev_noise_acc & ((uint32_t)1 << (SID3_ACC_BITS - 6))) != (ch->noise_accumulator & ((uint32_t)1 << (SID3_ACC_BITS - 6))))
|
||||
{
|
||||
sid3_clock_lfsr(ch);
|
||||
}
|
||||
|
||||
ch->accumulator = acc_state & SID3_ACC_MASK;
|
||||
ch->noise_accumulator = noise_acc_state & SID3_ACC_MASK;
|
||||
waveform = sid3_get_waveform(sid3, ch);
|
||||
|
||||
sid3->channel_signals_before_ADSR[i] = waveform;
|
||||
ch->accumulator = acc_state & SID3_ACC_MASK;
|
||||
ch->noise_accumulator = noise_acc_state & SID3_ACC_MASK;
|
||||
|
||||
if(ch->flags & SID3_CHAN_ENABLE_RING_MOD)
|
||||
{
|
||||
uint8_t ring_mod_src = ch->ring_mod_src == SID3_NUM_CHANNELS ? i : ch->ring_mod_src; //SID3_NUM_CHANNELS = self-mod
|
||||
sid3->channel_signals_before_ADSR[i] = waveform;
|
||||
|
||||
waveform = waveform * (ch->ring_mod_src == (SID3_NUM_CHANNELS - 1) ? sid3->wave_channel_signal_before_ADSR : sid3->channel_signals_before_ADSR[ring_mod_src]) / (int32_t)0xffff; //ring modulation is just multiplication of two signals!
|
||||
}
|
||||
if(ch->flags & SID3_CHAN_ENABLE_RING_MOD)
|
||||
{
|
||||
uint8_t ring_mod_src = ch->ring_mod_src == SID3_NUM_CHANNELS ? i : ch->ring_mod_src; //SID3_NUM_CHANNELS = self-mod
|
||||
|
||||
sid3_adsr_clock(&ch->adsr);
|
||||
|
||||
ch->output_before_filter = sid3_adsr_output(sid3, &ch->adsr, waveform);
|
||||
|
||||
int32_t output = 0;
|
||||
|
||||
if((ch->filt.filt[0].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[1].mode & SID3_FILTER_ENABLE) ||
|
||||
(ch->filt.filt[2].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[3].mode & SID3_FILTER_ENABLE))
|
||||
{
|
||||
output = sid3_process_filters_block(ch);
|
||||
waveform = waveform * (ch->ring_mod_src == (SID3_NUM_CHANNELS - 1) ? sid3->wave_channel_signal_before_ADSR : sid3->channel_signals_before_ADSR[ring_mod_src]) / (int32_t)0xffff; //ring modulation is just multiplication of two signals!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = ch->output_before_filter;
|
||||
}
|
||||
|
||||
if(ch->feedback)
|
||||
{
|
||||
ch->prev_output2 = ch->prev_output;
|
||||
ch->prev_output = output + 0xffff;
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
ch->noise_accumulator &= SID3_ACC_MASK;
|
||||
}
|
||||
|
||||
if(!sid3->muted[i])
|
||||
sid3_adsr_clock(sid3, &ch->adsr);
|
||||
|
||||
int32_t output = 0;
|
||||
|
||||
if(!ch->adsr.hold_zero)
|
||||
{
|
||||
sid3->output_l += output * ch->panning_left / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_LEFT) ? -1 : 1);
|
||||
sid3->output_r += output * ch->panning_right / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_RIGHT) ? -1 : 1);
|
||||
ch->output_before_filter = sid3_adsr_output(sid3, &ch->adsr, waveform);
|
||||
|
||||
if((ch->filt.filt[0].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[1].mode & SID3_FILTER_ENABLE) ||
|
||||
(ch->filt.filt[2].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[3].mode & SID3_FILTER_ENABLE))
|
||||
{
|
||||
output = sid3_process_filters_block(ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = ch->output_before_filter;
|
||||
}
|
||||
|
||||
if(ch->feedback)
|
||||
{
|
||||
ch->prev_output2 = ch->prev_output;
|
||||
ch->prev_output = output + 0xffff;
|
||||
}
|
||||
|
||||
if(!sid3->muted[i])
|
||||
{
|
||||
sid3->output_l += output * ch->panning_left / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_LEFT) ? -1 : 1);
|
||||
sid3->output_r += output * ch->panning_right / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_RIGHT) ? -1 : 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ch->output_before_filter = 0;
|
||||
|
||||
for(int j = 0; j < SID3_NUM_FILTERS; j++)
|
||||
{
|
||||
if(ch->filt.filt[j].mode & SID3_FILTER_ENABLE)
|
||||
{
|
||||
if(ch->filt.filt[j].output > 0)
|
||||
{
|
||||
ch->filt.filt[j].output--;
|
||||
}
|
||||
if(ch->filt.filt[j].output < 0)
|
||||
{
|
||||
ch->filt.filt[j].output++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sid3->channel_output[i] = output;
|
||||
|
@ -3151,57 +3190,86 @@ void sid3_clock(SID3* sid3)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t acc_state = ch->accumulator;
|
||||
int32_t waveform = 0;
|
||||
|
||||
if(ch->flags & SID3_CHAN_ENABLE_PHASE_MOD)
|
||||
if(!ch->adsr.hold_zero)
|
||||
{
|
||||
ch->accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
}
|
||||
uint32_t acc_state = ch->accumulator;
|
||||
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
if(ch->flags & SID3_CHAN_ENABLE_PHASE_MOD)
|
||||
{
|
||||
ch->accumulator += ch->phase_mod_source == SID3_NUM_CHANNELS - 1 ? ((uint64_t)sid3->wave_channel_output << 18) : ((uint64_t)sid3->channel_output[ch->phase_mod_source] << 18);
|
||||
}
|
||||
|
||||
int32_t waveform;
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
|
||||
if(ch->mode)
|
||||
{
|
||||
waveform = (int32_t)ch->streamed_sample - 0x7fff;
|
||||
if(ch->mode)
|
||||
{
|
||||
waveform = (int32_t)ch->streamed_sample - 0x7fff;
|
||||
}
|
||||
else
|
||||
{
|
||||
waveform = ((int32_t)ch->wavetable[(ch->accumulator & SID3_ACC_MASK) >> (SID3_ACC_BITS - 8)] << 8) - 0x7fff;
|
||||
}
|
||||
|
||||
ch->accumulator = acc_state & SID3_ACC_MASK;
|
||||
|
||||
sid3->wave_channel_signal_before_ADSR = waveform;
|
||||
|
||||
if(ch->flags & SID3_CHAN_ENABLE_RING_MOD)
|
||||
{
|
||||
uint8_t ring_mod_src = ch->ring_mod_src == SID3_NUM_CHANNELS ? 0xff : ch->ring_mod_src; //SID3_NUM_CHANNELS = self-mod
|
||||
|
||||
waveform = waveform * (ch->ring_mod_src == 0xff ? sid3->wave_channel_signal_before_ADSR : sid3->channel_signals_before_ADSR[ring_mod_src]) / (int32_t)0xffff; //ring modulation is just multiplication of two signals!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waveform = ((int32_t)ch->wavetable[(ch->accumulator & SID3_ACC_MASK) >> (SID3_ACC_BITS - 8)] << 8) - 0x7fff;
|
||||
ch->accumulator &= SID3_ACC_MASK;
|
||||
}
|
||||
|
||||
ch->accumulator = acc_state & SID3_ACC_MASK;
|
||||
|
||||
sid3->wave_channel_signal_before_ADSR = waveform;
|
||||
|
||||
if(ch->flags & SID3_CHAN_ENABLE_RING_MOD)
|
||||
{
|
||||
uint8_t ring_mod_src = ch->ring_mod_src == SID3_NUM_CHANNELS ? 0xff : ch->ring_mod_src; //SID3_NUM_CHANNELS = self-mod
|
||||
|
||||
waveform = waveform * (ch->ring_mod_src == 0xff ? sid3->wave_channel_signal_before_ADSR : sid3->channel_signals_before_ADSR[ring_mod_src]) / (int32_t)0xffff; //ring modulation is just multiplication of two signals!
|
||||
}
|
||||
|
||||
sid3_adsr_clock(&ch->adsr);
|
||||
|
||||
ch->output_before_filter = sid3_adsr_output(sid3, &ch->adsr, waveform);
|
||||
sid3_adsr_clock(sid3, &ch->adsr);
|
||||
|
||||
int32_t output = 0;
|
||||
|
||||
if((ch->filt.filt[0].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[1].mode & SID3_FILTER_ENABLE) ||
|
||||
(ch->filt.filt[2].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[3].mode & SID3_FILTER_ENABLE))
|
||||
|
||||
if(!ch->adsr.hold_zero)
|
||||
{
|
||||
output = sid3_process_wave_channel_filters_block(ch);
|
||||
ch->output_before_filter = sid3_adsr_output(sid3, &ch->adsr, waveform);
|
||||
|
||||
if((ch->filt.filt[0].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[1].mode & SID3_FILTER_ENABLE) ||
|
||||
(ch->filt.filt[2].mode & SID3_FILTER_ENABLE) || (ch->filt.filt[3].mode & SID3_FILTER_ENABLE))
|
||||
{
|
||||
output = sid3_process_wave_channel_filters_block(ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = ch->output_before_filter;
|
||||
}
|
||||
|
||||
if(!sid3->muted[SID3_NUM_CHANNELS - 1])
|
||||
{
|
||||
sid3->output_l += output * ch->panning_left / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_LEFT) ? -1 : 1);
|
||||
sid3->output_r += output * ch->panning_right / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_RIGHT) ? -1 : 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = ch->output_before_filter;
|
||||
}
|
||||
ch->output_before_filter = 0;
|
||||
|
||||
if(!sid3->muted[SID3_NUM_CHANNELS - 1])
|
||||
{
|
||||
sid3->output_l += output * ch->panning_left / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_LEFT) ? -1 : 1);
|
||||
sid3->output_r += output * ch->panning_right / 0x8f0 * ((ch->phase_inv & SID3_INV_SIGNAL_RIGHT) ? -1 : 1);
|
||||
for(int j = 0; j < SID3_NUM_FILTERS; j++)
|
||||
{
|
||||
if(ch->filt.filt[j].mode & SID3_FILTER_ENABLE)
|
||||
{
|
||||
if(ch->filt.filt[j].output > 0)
|
||||
{
|
||||
ch->filt.filt[j].output--;
|
||||
}
|
||||
if(ch->filt.filt[j].output < 0)
|
||||
{
|
||||
ch->filt.filt[j].output++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sid3->wave_channel_output = output;
|
||||
|
@ -3501,12 +3569,10 @@ void sid3_write(SID3* sid3, uint16_t address, uint8_t data)
|
|||
if(channel != SID3_NUM_CHANNELS - 1)
|
||||
{
|
||||
sid3->chan[channel].filt.filt[filter].mode = data;
|
||||
//sid3_set_filter_settings(&sid3->chan[channel].filt.filt[filter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3->wave_chan.filt.filt[filter].mode = data;
|
||||
//sid3_set_filter_settings(&sid3->wave_chan.filt.filt[filter]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3521,13 +3587,13 @@ void sid3_write(SID3* sid3, uint16_t address, uint8_t data)
|
|||
{
|
||||
sid3->chan[channel].filt.filt[filter].cutoff &= 0x00ff;
|
||||
sid3->chan[channel].filt.filt[filter].cutoff |= data << 8;
|
||||
sid3_set_filter_settings(&sid3->chan[channel].filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->chan[channel].filt.filt[filter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3->wave_chan.filt.filt[filter].cutoff &= 0x00ff;
|
||||
sid3->wave_chan.filt.filt[filter].cutoff |= data << 8;
|
||||
sid3_set_filter_settings(&sid3->wave_chan.filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->wave_chan.filt.filt[filter]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3542,13 +3608,13 @@ void sid3_write(SID3* sid3, uint16_t address, uint8_t data)
|
|||
{
|
||||
sid3->chan[channel].filt.filt[filter].cutoff &= 0xff00;
|
||||
sid3->chan[channel].filt.filt[filter].cutoff |= data;
|
||||
sid3_set_filter_settings(&sid3->chan[channel].filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->chan[channel].filt.filt[filter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3->wave_chan.filt.filt[filter].cutoff &= 0xff00;
|
||||
sid3->wave_chan.filt.filt[filter].cutoff |= data;
|
||||
sid3_set_filter_settings(&sid3->wave_chan.filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->wave_chan.filt.filt[filter]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3562,12 +3628,12 @@ void sid3_write(SID3* sid3, uint16_t address, uint8_t data)
|
|||
if(channel != SID3_NUM_CHANNELS - 1)
|
||||
{
|
||||
sid3->chan[channel].filt.filt[filter].resonance = data;
|
||||
sid3_set_filter_settings(&sid3->chan[channel].filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->chan[channel].filt.filt[filter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3->wave_chan.filt.filt[filter].resonance = data;
|
||||
sid3_set_filter_settings(&sid3->wave_chan.filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->wave_chan.filt.filt[filter]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3581,12 +3647,12 @@ void sid3_write(SID3* sid3, uint16_t address, uint8_t data)
|
|||
if(channel != SID3_NUM_CHANNELS - 1)
|
||||
{
|
||||
sid3->chan[channel].filt.filt[filter].distortion_level = data;
|
||||
sid3_set_filter_settings(&sid3->chan[channel].filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->chan[channel].filt.filt[filter]);
|
||||
}
|
||||
else
|
||||
{
|
||||
sid3->wave_chan.filt.filt[filter].distortion_level = data;
|
||||
sid3_set_filter_settings(&sid3->wave_chan.filt.filt[filter]);
|
||||
sid3_set_filter_settings(sid3, &sid3->wave_chan.filt.filt[filter]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -3768,6 +3834,11 @@ void sid3_set_is_muted(SID3* sid3, uint8_t ch, bool mute)
|
|||
sid3->muted[ch] = mute;
|
||||
}
|
||||
|
||||
void sid3_set_clock_rate(SID3* sid3, uint32_t clock)
|
||||
{
|
||||
sid3->clock_rate = clock;
|
||||
}
|
||||
|
||||
void sid3_free(SID3* sid3)
|
||||
{
|
||||
SAFETY_HEADER
|
||||
|
|
|
@ -268,6 +268,7 @@ typedef struct
|
|||
|
||||
//emulation-only helpers
|
||||
bool muted[SID3_NUM_CHANNELS];
|
||||
uint32_t clock_rate; //in Hz. 1 MHz default
|
||||
} SID3;
|
||||
|
||||
SID3* sid3_create();
|
||||
|
@ -275,6 +276,7 @@ void sid3_reset(SID3* sid3);
|
|||
void sid3_write(SID3* sid3, uint16_t address, uint8_t data);
|
||||
void sid3_clock(SID3* sid3);
|
||||
void sid3_set_is_muted(SID3* sid3, uint8_t ch, bool mute);
|
||||
void sid3_set_clock_rate(SID3* sid3, uint32_t clock);
|
||||
void sid3_free(SID3* sid3);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -2517,6 +2517,29 @@ bool FurnaceGUI::drawSysConf(int chan, int sysPos, DivSystem type, DivConfig& fl
|
|||
supportsCustomRate=false;
|
||||
ImGui::Text(_("nothing to configure"));
|
||||
break;
|
||||
case DIV_SYSTEM_SID3:
|
||||
{
|
||||
bool quarterClock=flags.getBool("quarterClock",false);
|
||||
if (ImGui::Checkbox(_("Quarter clock speed"),&quarterClock)) {
|
||||
altered=true;
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("Decreases clock speed and CPU audio load by 4 times.\nCan be used if your CPU is too slow for the chip."
|
||||
"\nDoes not affect clock speed during export!\n\n"
|
||||
|
||||
"Warning! Filters may become unstable at high cutoff and resonance\nif this option or lower clock speed are used!\n"
|
||||
"Also filters' timbre may be different near these values.\n\n"
|
||||
|
||||
"Default clock speed is 1MHz (1000000Hz)."));
|
||||
}
|
||||
|
||||
if (altered) {
|
||||
e->lockSave([&]() {
|
||||
flags.set("quarterClock",(int)quarterClock);
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
bool sysPal=flags.getInt("clockSel",0);
|
||||
|
||||
|
|
Loading…
Reference in a new issue