I've finally resolved most of the remaining pitch issues in the SCSP emulation. What was happening was that the remaining fractional play position was not being carried over upon crossing over LSA/LEA resulting in an overall lower pitch for looped samples.
Patch against AOSDK 1.3:
Code
diff -Nru aosdk_base/eng_ssf/scsp.c aosdk/eng_ssf/scsp.c
--- aosdk_base/eng_ssf/scsp.c 2008-01-13 15:33:54.000000000 -0800
+++ aosdk/eng_ssf/scsp.c 2008-01-19 03:45:38.000000000 -0800
@@ -36,7 +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
+#define FM_DELAY 0 // delay in number of slots processed before samples are written to the FM ring buffer
// include the LFO handling code
#include "scsplfo.c"
@@ -939,6 +939,7 @@
for (addr_select=0;addr_select<2;addr_select++)
{
+ INT32 rem_addr;
switch(LPCTL(slot))
{
case 0: //no loop
@@ -950,26 +951,35 @@
break;
case 1: //normal loop
if(*addr[addr_select]>=LEA(slot))
- *slot_addr[addr_select]=LSA(slot)<<SHIFT;
+ {
+ rem_addr = *slot_addr[addr_select] - (LEA(slot)<<SHIFT);
+ *slot_addr[addr_select]=(LSA(slot)<<SHIFT) + rem_addr;
+ }
break;
case 2: //reverse loop
if((*addr[addr_select]>=LSA(slot)) && !(slot->Backwards))
{
- *slot_addr[addr_select]=LEA(slot)<<SHIFT;
+ rem_addr = *slot_addr[addr_select] - (LSA(slot)<<SHIFT);
+ *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
slot->Backwards=1;
}
- if((*addr[addr_select]<=LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)
- *slot_addr[addr_select]=LEA(slot)<<SHIFT;
+ else if((*addr[addr_select]<LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)
+ {
+ rem_addr = (LSA(slot)<<SHIFT) - *slot_addr[addr_select];
+ *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
+ }
break;
case 3: //ping-pong
if(*addr[addr_select]>=LEA(slot)) //reached end, reverse till start
{
- *slot_addr[addr_select]=LEA(slot)<<SHIFT;
+ rem_addr = *slot_addr[addr_select] - (LEA(slot)<<SHIFT);
+ *slot_addr[addr_select]=(LEA(slot)<<SHIFT) - rem_addr;
slot->Backwards=1;
}
- if((*addr[addr_select]<=LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)//reached start or negative
+ else if((*addr[addr_select]<LSA(slot) || (*slot_addr[addr_select]&0x80000000)) && slot->Backwards)//reached start or negative
{
- *slot_addr[addr_select]=LSA(slot)<<SHIFT;
+ rem_addr = (LSA(slot)<<SHIFT) - *slot_addr[addr_select];
+ *slot_addr[addr_select]=(LSA(slot)<<SHIFT) + rem_addr;
slot->Backwards=0;
}
break;