• Rise from your gwave!

Project : convert yamaha YMxxx FM to saturn scsp FM

Discussion in 'Saturn Dev' started by vbt, Sep 18, 2016.

  1. vbt

    vbt Staff Member

    would someone help on this project? it needs some documentation, dev, testing.
    such stuff would add sound to some emulated games on final burn alpha like :

    - vigilante
    - black tiger
    - pang
    - super pang

    the fm calculation from mame/fba is really too slow for a saturn whereas it would be really fast with a simple conversion to the scsp fm. it would allow to port more games on fba saturn
     
  2. antime

    antime Extra Hard Mid Boss

    Have you looked at the capabilities of the chips you want to simulate, and how they correspond to the SCSP?
     
  3. vbt

    vbt Staff Member

    yes i've discussed with some high skilled french guy and asked also on irc, the idea is something like this for an ym2203 :

    - 3 channels with 4 operators becomes 3x4 pcm voices
    - create a sinusoidal tone for the 12 pcm voices
    - write some stuff directtly to scsp registers
    - merge all to a fm channel to reproduce fm synthesis

    well i don't have such knowledges so i'd need help
     
  4. antime

    antime Extra Hard Mid Boss

    Basic audio playback isn't too difficult, this is some code I experimented with many years ago. The audio data used 16-bit samples, which is why length/2 is used as the loop end address. For FM sounds I assume the process is similar, except that you have to set up the modulation sources, and that the slots used for modulation aren't connected to a mixer.
    Code:
    #include "types.h"
    #include "scsp.h"
    
    #include "sample.h"
    
    int main(void)
    {
      u16  *pSample = (u16*)data;
      
      /* Set up SCSP */
      /* Max volume. */
      SCSP_VERVOL = 0xf;
      
      /* Set slot data. */
      SCSP_SLOT_ARRAY[0].SALow = (u16)((u32)pSample & 0xffff);
      SCSP_SLOT_ARRAY[0].LSA = 0;
      SCSP_SLOT_ARRAY[0].LEA = ARRAY_LEN/2;
      SCSP_SLOT_ARRAY[0].Env1 = 0;
      SCSP_SLOT_ARRAY[0].Env2 = 0;
      SCSP_SLOT_ARRAY[0].Volume = SDIR_ON;  /* Ignore EG, TL, LFO etc. */
      SCSP_SLOT_ARRAY[0].Pitch = 0; /* Should play at 44100 Hz */
      SCSP_SLOT_ARRAY[0].Pan = (7<<13) | (4<<8);  /* Max DISDL */
      SCSP_SLOT_ARRAY[0].SlotCTL = KEY_ON | LPCTL_FWLOOP | (((u32)pSample >> 16) & 0xf);
      SCSP_SLOT_ARRAY[1].SALow = (u16)((u32)pSample & 0xffff);
      SCSP_SLOT_ARRAY[1].LSA = 0;
      SCSP_SLOT_ARRAY[1].LEA = ARRAY_LEN/2;
      SCSP_SLOT_ARRAY[1].Env1 = 0;
      SCSP_SLOT_ARRAY[1].Env2 = 0;
      SCSP_SLOT_ARRAY[1].Volume = SDIR_ON;  /* Ignore EG, TL, LFO etc. */
      SCSP_SLOT_ARRAY[1].Pitch = (-1 & 0xf << 11); /* Should play at 22050 Hz */
      SCSP_SLOT_ARRAY[1].Pan = (7<<13) | (0x14 << 8);  /* Max DISDL */
      SCSP_SLOT_ARRAY[1].SlotCTL = KYONEX | KEY_ON | LPCTL_FWLOOP | (((u32)pSample >> 16) & 0xf);
    #if 0
      /* Test LFO effect. */
      SCSP_SLOT_ARRAY[1].SALow = (u16)((u32)pSample & 0xffff);
      SCSP_SLOT_ARRAY[1].LSA = 0;
      SCSP_SLOT_ARRAY[1].LEA = ARRAY_LEN/2;
      SCSP_SLOT_ARRAY[1].Env1 = EGHOLD_ON;
      SCSP_SLOT_ARRAY[1].Env2 = 0;
      SCSP_SLOT_ARRAY[1].Volume = SDIR_ON;
      SCSP_SLOT_ARRAY[1].Pitch = (-1 & 0xf << 11); /* Should play at 22050 Hz */
      SCSP_SLOT_ARRAY[1].Pan = (7<<13);  /* Max DISDL */
      SCSP_SLOT_ARRAY[1].LFOCTL = (4<<5) | (2<<8) | (0xf<<10);/* Max PLFOS (pitch), triangle waveform(PLFOWS), max LFO frequency */
      SCSP_SLOT_ARRAY[1].SlotCTL = KYONEX | KEY_ON | LPCTL_FWLOOP | (((u32)pSample >> 16) & 0xf);
    #endif
      while(1)
      {
      ;
      }
      
      return 0;
    }
    
    
     
    dibz likes this.

Share This Page