emu2149
emu2149 copied to clipboard
noise channel mask
Very long ago, I have been requested to implement a masking feature for KSS-X (Mac) to support the ability to mask any psg channel, including the noise. Instead of having 3 channels, I have added 3 additional channels to the masking so one could disable the noise. Noise can be produce on top of any psg channel (0,1,2) therefore, to disable the noise on them, I had set them to be channel (3,4,5).
Here is a small description of how it works:
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,0); //No mask applied
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,1); //Channel 0 is masked
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,2); //Channel 1 is masked
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,4); //Channel 2 is masked
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,8); //noise of channel 0 is masked
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,16); //noise of channel 1 is masked
KSSPLAY_set_channel_mask(kssplay,EDSC_PSG,32); //noise of channel 2 is masked
I am not sure that I coded it the way it should be but feel free to take the update I made (long ago) and adjust if needed. Sorry, I do not have access to the proper source code, but will provide it as soon as I found it.
Greetings and thank a lot for those fantastic libs. ^_^
Hi, thank you for using emu2149 and your suggestion! The noise masking for each PSG channel is very interesting. Extending range of the mask argument is straightforward but I should think on backward-compatibility because higher bits of the mask argument has not been defined yet.
Anyway I will consider how to introduce this feature to the current emu2149 master so I labbelled this issue as enhancement.
Here is my modified version of the code to be able to use channelMask on PSG 1,2,4 = psg tone channel 0,1,2 8, 16 32 = noise 0,1,2
My programming skills are limitied so please review before using.
static inline void update_output (PSG * psg) {
int i, noise; uint32_t incr;
psg->base_count += psg->base_incr; incr = (psg->base_count >> GETA_BITS); psg->base_count &= (1 << GETA_BITS) - 1;
/* Envelope */ psg->env_count += incr; while (psg->env_count>=0x10000 && psg->env_freq!=0) { if (!psg->env_pause) { if(psg->env_face) psg->env_ptr = (psg->env_ptr + 1) & 0x3f ; else psg->env_ptr = (psg->env_ptr + 0x3f) & 0x3f; }
if (psg->env_ptr & 0x20) /* if carry or borrow */
{
if (psg->env_continue)
{
if (psg->env_alternate^psg->env_hold) psg->env_face ^= 1;
if (psg->env_hold) psg->env_pause = 1;
psg->env_ptr = psg->env_face?0:0x1f;
}
else
{
psg->env_pause = 1;
psg->env_ptr = 0;
}
}
psg->env_count -= psg->env_freq;
}
/* Noise */ psg->noise_count += incr; if (psg->noise_count & 0x40) { if (psg->noise_seed & 1) psg->noise_seed ^= 0x24000; psg->noise_seed >>= 1; psg->noise_count -= psg->noise_freq?psg->noise_freq:(1<<1); } noise = psg->noise_seed & 1;
/* Tone */ for (i = 0; i < 3; i++) { psg->count[i] += incr; if (psg->count[i] & 0x1000) { if (psg->freq[i] > 1) { psg->edge[i] = !psg->edge[i]; psg->count[i] -= psg->freq[i]; } else { psg->edge[i] = 1; } }
if ( (!(psg->mask&PSG_MASK_CH(i))) && (!(psg->mask&PSG_MASK_CH(i+3))))
{
if ((psg->tmask[i]||psg->edge[i]) && (psg->nmask[i]||noise))
{
if (!(psg->volume[i] & 32))
psg->ch_out[i] += (psg->voltbl[psg->volume[i] & 31] << 4);
else
psg->ch_out[i] += (psg->voltbl[psg->env_ptr] << 4);
}
}
if ((psg->mask&PSG_MASK_CH(i)) && !(psg->mask&PSG_MASK_CH(i+3)))
{
if ((noise) && !(psg->nmask[i]))
{
if (!(psg->volume[i] & 32))
psg->ch_out[i] += (psg->voltbl[psg->volume[i] & 31] << 4);
else
psg->ch_out[i] += (psg->voltbl[psg->env_ptr] << 4);
}
}
if ( !(psg->mask&PSG_MASK_CH(i)) && (psg->mask&PSG_MASK_CH(i+3)) )
{
if ((psg->tmask[i]) || (psg->edge[i]))
{
if (!(psg->volume[i] & 32))
psg->ch_out[i] += (psg->voltbl[psg->volume[i] & 31] << 4);
else
psg->ch_out[i] += (psg->voltbl[psg->env_ptr] << 4);
}
}
/*if((psg->mask&PSG_MASK_CH(i)) && !(psg->mask&PSG_MASK_CH(i+3)))
{
if ((noise) && !(psg->nmask[i]))
{
if (!(psg->volume[i] & 32))
psg->ch_out[i] += (psg->voltbl[psg->volume[i] & 31] << 4);
else
psg->ch_out[i] += (psg->voltbl[psg->env_ptr] << 4);
}
}
*/
psg->ch_out[i] >>= 1;
}
}
Greetings