|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
Heh, well, the patch is already in the final release binaries of AO 2.0b9 (which Richard should be posting in the next few hours), but since no rips using FM are released yet that shouldn't be a problem :-) (Although that ASL2 track you posted sounds fine). I'll keep AOSDK at 1.1.6 though.
|
|
|
|
Joined: Sep 2007
Posts: 56
Member
|
Member
Joined: Sep 2007
Posts: 56 |
Well, that will change when I release Shinobi X (if/when I decide to do so). Still doesn't make much of a difference since the FM handling didn't really get worse than what was there before, it just does it wrong in a different way. I've examined FM a bit more while working with Shinobi X, and while I wasn't able to make any significant progress on getting it to sound correct, I was able to get MDXSL and MDYSL working properly. I've verified that these are correct by comparing their values with the fm_layer and fm_gen values given by ssfinfo and they are consistent with the tables in the SCSP manual. To achieve this, I changed the FM ring buffer pointer to decrement rather than increment as well as making it update regardless of whether a slot is active or not. While investigating FM issues, I uncovered a few more (relatively minor) problems. I fixed a small LPSLNK problem (wasn't handling this quite correctly before). Also, I made a change to the DSP input mix level, which improves the effect balance. Previously, DSP output was a bit quiet compared to the direct output. I resolved this by shifting left what was the previous input by 2. I believe this is correct since the LPANTABLE/RPANTABLE calculations contain a multiplier of 4.0, and an additional left shift of 2 is in line with the fact that the MIXS input is 20 bits. Below is a upgraded patch to AOSDK 1.1.6. I've commented out the FM-synth stuff because it isn't correct yet and right now Shinobi X sounds better with it disabled.
diff -Nru aosdk_base/eng_ssf/scsp.c aosdk/eng_ssf/scsp.c
--- aosdk_base/eng_ssf/scsp.c 2007-12-14 09:09:20.000000000 -0800
+++ aosdk/eng_ssf/scsp.c 2007-12-17 07:09:39.000000000 -0800
@@ -73,7 +73,7 @@
#define SDIR(slot) ((slot->udata.data[0x6]>>0x0)&0x0100)
#define TL(slot) ((slot->udata.data[0x6]>>0x0)&0x00FF)
-#define MDL(slot) ((slot->udata.data[0x7]>>0xB)&0x0007)
+#define MDL(slot) ((slot->udata.data[0x7]>>0xC)&0x000F)
#define MDXSL(slot) ((slot->udata.data[0x7]>>0x6)&0x003F)
#define MDYSL(slot) ((slot->udata.data[0x7]>>0x0)&0x003F)
@@ -384,7 +384,7 @@
static UINT32 SCSP_Step(struct _SLOT *slot)
{
int octave=OCT(slot);
- UINT32 Fn;
+ UINT64 Fn;
Fn=(FNS_Table[FNS(slot)]); //24.8
if(octave&8)
@@ -1114,11 +1114,16 @@
addr2=(slot->nxt_addr>>(SHIFT-1))&0x7fffe;
}
- if(MDL(slot)!=0 || MDXSL(slot)!=0 || MDYSL(slot)!=0)
+ /*if(MDL(slot)!=0 || MDXSL(slot)!=0 || MDYSL(slot)!=0)
{
INT32 smp=(SCSP->RINGBUF[(SCSP->BUFPTR+MDXSL(slot))&63]+SCSP->RINGBUF[(SCSP->BUFPTR+MDYSL(slot))&63])/2;
+ INT32 cycle=LEA(slot)-LSA(slot); // cycle corresponds to 2 pi
- smp>>=11;
+ smp*=cycle; // associate cycle with full 16-bit sample range
+ smp>>=0x1A-MDL(slot); // ex. for MDL=0xF, sample range corresponds to +/- 64 pi (32=2^5 cycles) so shift by 11 (16-5 == 0x1A-0xF)
+ while(smp<0) smp+=cycle; smp%=cycle; // keep modulation sampler within a single cycle
+ if(!PCM8B(slot)) smp<<=1;
+
addr1+=smp; addr2+=smp;
if(!PCM8B(slot))
{
@@ -1128,13 +1133,7 @@
{
addr1&=0x7ffff; addr2&=0x7ffff;
}
- }
-
- if(addr1==LSA(slot))
- {
- if(LPSLNK(slot) && slot->EG.state==ATTACK)
- slot->EG.state = DECAY1;
- }
+ }*/
if(PCM8B(slot)) //8 bit signed
{
@@ -1171,6 +1170,12 @@
addr1=slot->cur_addr>>SHIFT;
addr2=slot->nxt_addr>>SHIFT;
+ if(addr1>=LSA(slot) && !(slot->Backwards))
+ {
+ if(LPSLNK(slot) && slot->EG.state==ATTACK)
+ slot->EG.state = DECAY1;
+ }
+
for (addr_select=0;addr_select<2;addr_select++)
{
switch(LPCTL(slot))
@@ -1216,14 +1221,14 @@
sample>>=SHIFT;
}
- if(!STWINH(slot))
- *RBUFDST=sample;
-
if(slot->EG.state==ATTACK)
sample=(sample*EG_Update(slot))>>SHIFT;
else
sample=(sample*EG_TABLE[EG_Update(slot)>>(SHIFT-10)])>>SHIFT;
+ if(!STWINH(slot))
+ *RBUFDST=sample;
+
return sample;
}
@@ -1243,19 +1248,18 @@
for(sl=0;sl<32;++sl)
{
+ RBUFDST=SCSP->RINGBUF+SCSP->BUFPTR;
if(SCSP->Slots[sl].active)
{
struct _SLOT *slot=SCSP->Slots+sl;
unsigned short Enc;
signed int sample;
- RBUFDST=SCSP->RINGBUF+SCSP->BUFPTR;
sample=SCSP_UpdateSlot(SCSP, slot);
- ++SCSP->BUFPTR;
- SCSP->BUFPTR&=63;
+
#ifdef USEDSP
Enc=((TL(slot))<<0x0)|((IMXL(slot))<<0xd);
- SCSPDSP_SetSample(&SCSP->DSP,(sample*SCSP->LPANTABLE[Enc])>>SHIFT,ISEL(slot),IMXL(slot));
+ SCSPDSP_SetSample(&SCSP->DSP,(sample*SCSP->LPANTABLE[Enc])>>(SHIFT-2),ISEL(slot),IMXL(slot));
#endif
Enc=((TL(slot))<<0x0)|((DIPAN(slot))<<0x8)|((DISDL(slot))<<0xd);
{
@@ -1263,7 +1267,8 @@
smpr+=(sample*SCSP->RPANTABLE[Enc])>>SHIFT;
}
}
-
+ --SCSP->BUFPTR;
+ SCSP->BUFPTR&=63;
}
SCSPDSP_Step(&SCSP->DSP);
Changes: -Corrected handling of the FM ring-buffer pointer - MDXSL and MDYSL now handled correctly -Incorporated MDL into modulation code (not yet handled correctly, but it's something to start with) -Changed frequency-step calculation to use UINT64 to fix rollover problems caused by large OCT values -Improved DSP mix (I believe it's correct now) -Fixed a minor LPSLNK problem
|
|
|
|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
As per the above patch. Sounds nice, but it's definitely a more subtle improvement than previous changes 
|
|
|
|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
On the homepage. This time, kingshriek was not involved ;-) It's just the PSF2 improvments from AO 2.0b10 test 1.
|
|
|
|
Joined: Sep 2007
Posts: 56
Member
|
Member
Joined: Sep 2007
Posts: 56 |
Alright, I think I have the SCSP's FM-synthesis working reasonably well. Shinobi X and NiGHTS sound a bit better now for the most part. Patch against AO SDK 1.2.0:
diff -Nru aosdk_base/eng_ssf/scsp.c aosdk/eng_ssf/scsp.c
--- aosdk_base/eng_ssf/scsp.c 2007-12-17 12:45:26.000000000 -0800
+++ aosdk/eng_ssf/scsp.c 2008-01-04 19:39:51.000000000 -0800
@@ -36,6 +36,7 @@
#define EG_SHIFT 16
+#define FM_DELAY 4 // delay in number of slots processed before samples are written to the FM ring buffer
// include the LFO handling code
#include "scsplfo.c"
@@ -181,6 +182,10 @@
struct _SLOT Slots[32];
signed short RINGBUF[64];
unsigned char BUFPTR;
+#if FM_DELAY
+ signed short DELAYBUF[FM_DELAY];
+ unsigned char DELAYPTR;
+#endif
unsigned char *SCSPRAM;
UINT32 SCSPRAM_LENGTH;
char Master;
@@ -1114,31 +1119,23 @@
addr2=(slot->nxt_addr>>(SHIFT-1))&0x7fffe;
}
- /*if(MDL(slot)!=0 || MDXSL(slot)!=0 || MDYSL(slot)!=0)
+ if(MDL(slot)!=0 || MDXSL(slot)!=0 || MDYSL(slot)!=0)
{
INT32 smp=(SCSP->RINGBUF[(SCSP->BUFPTR+MDXSL(slot))&63]+SCSP->RINGBUF[(SCSP->BUFPTR+MDYSL(slot))&63])/2;
INT32 cycle=LEA(slot)-LSA(slot); // cycle corresponds to 2 pi
- smp*=cycle; // associate cycle with full 16-bit sample range
+ smp<<=0xA; // associate cycle with 1024
smp>>=0x1A-MDL(slot); // ex. for MDL=0xF, sample range corresponds to +/- 64 pi (32=2^5 cycles) so shift by 11 (16-5 == 0x1A-0xF)
while(smp<0) smp+=cycle; smp%=cycle; // keep modulation sampler within a single cycle
if(!PCM8B(slot)) smp<<=1;
addr1+=smp; addr2+=smp;
- if(!PCM8B(slot))
- {
- addr1&=0x7fffe; addr2&=0x7fffe;
- }
- else
- {
- addr1&=0x7ffff; addr2&=0x7ffff;
- }
- }*/
+ }
if(PCM8B(slot)) //8 bit signed
{
- INT8 *p1=(signed char *) (SCSP->SCSPRAM+((SA(slot)+addr1)^1));
- INT8 *p2=(signed char *) (SCSP->SCSPRAM+((SA(slot)+addr2)^1));
+ INT8 *p1=(signed char *) (SCSP->SCSPRAM+(((SA(slot)+addr1)^1)&0x7FFFF));
+ INT8 *p2=(signed char *) (SCSP->SCSPRAM+(((SA(slot)+addr2)^1)&0x7FFFF));
//sample=(p[0])<<8;
INT32 s;
INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
@@ -1147,8 +1144,8 @@
}
else //16 bit signed (endianness?)
{
- INT16 *p1=(signed short *) (slot->base+addr1);
- INT16 *p2=(signed short *) (slot->base+addr2);
+ INT16 *p1=(signed short *) (SCSP->SCSPRAM+((SA(slot)+addr1)&0x7FFFE));
+ INT16 *p2=(signed short *) (SCSP->SCSPRAM+((SA(slot)+addr2)&0x7FFFE));
//sample=LE16(p[0]);
INT32 s;
INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
@@ -1248,7 +1245,11 @@
for(sl=0;sl<32;++sl)
{
+#if FM_DELAY
+ RBUFDST=SCSP->DELAYBUF+SCSP->DELAYPTR;
+#else
RBUFDST=SCSP->RINGBUF+SCSP->BUFPTR;
+#endif
if(SCSP->Slots[sl].active)
{
struct _SLOT *slot=SCSP->Slots+sl;
@@ -1267,8 +1268,16 @@
smpr+=(sample*SCSP->RPANTABLE[Enc])>>SHIFT;
}
}
- --SCSP->BUFPTR;
+
+#if FM_DELAY
+ SCSP->RINGBUF[(SCSP->BUFPTR+64-(FM_DELAY-1))&63] = SCSP->DELAYBUF[(SCSP->DELAYPTR+FM_DELAY-(FM_DELAY-1))%FM_DELAY];
+#endif
+ ++SCSP->BUFPTR;
SCSP->BUFPTR&=63;
+#if FM_DELAY
+ ++SCSP->DELAYPTR;
+ if(SCSP->DELAYPTR>FM_DELAY-1) SCSP->DELAYPTR=0;
+#endif
}
SCSPDSP_Step(&SCSP->DSP);
Changes: -Improved/enabled FM-synthesis emulation. Also, I believe the endian XOR in the 8-bit sampler should use BYTE_XOR_BE when incorporating into MAME (I think a simple "^1" is ok for AO since SCSP RAM appears to always be organized in a byte-swapped manner). At least scsp.c before the last MAME SCSP update used BYTE_XOR_BE.
|
|
|
|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
Nice. Any suggested test tracks in NiGHTS?
|
|
|
|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
SDK's updated with these changes. Thanks again!
|
|
|
|
Joined: Sep 2007
Posts: 56
Member
|
Member
Joined: Sep 2007
Posts: 56 |
Nice. Any suggested test tracks in NiGHTS? nights_2b.minissf and nights_5d.minissf among others. The bass channels in these are FM-synthesized. For Shinobi X, shinobix_18.minissf and shinobix_19.minissf (bass channel in these is practically inaudible without FM-synth implemented).
|
|
|
|
Joined: Mar 2001
Posts: 17,250 Likes: 265
Very Senior Member
|
Very Senior Member
Joined: Mar 2001
Posts: 17,250 Likes: 265 |
Ahh. Good old FM bass  I didn't realize Shinobi X had been released - I sort of lost track of SSF over the holidays. Nice.
|
|
|
|
Joined: Mar 2004
Posts: 702 Likes: 2
Senior Member
|
Senior Member
Joined: Mar 2004
Posts: 702 Likes: 2 |
Is it just me, or did rsg01.ssf started to sound much worse, among others? Try Shining Force 3 Main Theme (the beginning of it), for instance. Same goes for AO 2.0b9.
Last edited by Belegdol; 01/06/08 09:54 AM.
|
|
|
2 members (robcfg, Foxhack),
107
guests, and
0
robots. |
Key:
Admin,
Global Mod,
Mod
|
|
Forums9
Topics9,345
Posts122,350
Members5,082
|
Most Online1,283 Dec 21st, 2022
|
|
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!
|
|
|
|