emu2149 icon indicating copy to clipboard operation
emu2149 copied to clipboard

noise channel mask

Open arouge opened this issue 6 years ago • 2 comments

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. ^_^

arouge avatar Nov 10 '17 21:11 arouge

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.

okaxaki avatar Nov 11 '17 21:11 okaxaki

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

arouge avatar Nov 02 '18 15:11 arouge