Previous Thread
Next Thread
Print Thread
Page 29 of 55 1 2 27 28 29 30 31 54 55
Re: AO SDK release 1.4.1 available [Re: R. Belmont] #43005 07/18/08 11:23 AM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
Going back to that DSP issue - now, after a few more hours of tests, I'm pretty much convinced this isn't about DSP but rather ADPCM.
See, the DSP works just fine with 8- and 16-bit samples being input:
- it works for Saturn tunes
- it breaks only certain Dreamcast tunes
- hissing/clipping only occurs when ADPCM samples are being routed through DSP

All DSP does (in short) is take the input wave, modify it a bit and add it back time-shifted. However if the output saturates and stays like that it will distort or even mute all sounds during final mixing pass. Non-ADPCM samples eventually integrate to zero, so the adder never overflows. But ADPCM samples seem to have a bias and tend to dive into negative numbers and stay there (loop jumps recover a bit, but not completly). And it's exactly what upsets the DSP - you can test that by inverting the sign of ADPCM samples being written to MIXS. It will create exactly the same output wave but mirrored around time axis. Reducing ADPCM dynamic range (from -/+ 32768 to let's say 24000) helps, but you can still see the output swinging rather then being symmetric.

I'm trying to figure out what's wrong with the decoder and why does it introduce the bias, but not much luck so far. Maybe I'm missing something obvious?
kingshriek, if you have some time could you please look into that as well? All you need to do is extract some raw ADPCM data and convert it to WAV, then view it under some sound editor like Audacity. You should see the problem right away. You can use soa-367-04-00.minidsf as it starts with ADPCM and exibits the symptoms.
I can provide you with longer streams if you want - dialog lines from Soul Reaver. It's very obvious on those:
http://pics.livejournal.com/dknute/pic/000eky4b

EDIT:
Well, I haven't found this to be a problem in a while... anyway - shifting is the culprit. -1 >> 3 is still -1, whereas -1 / 8 is zero. It's consistent with the fact that the bias is towards negative values. I'll see if +1 trick will work and test it further and get back to you smile

Last edited by Deunan Knute; 07/18/08 12:36 PM.
Re: AO SDK release 1.4.1 available [Re: Deunan Knute] #43006 07/18/08 04:43 PM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
Bingo. Update aica.c with this modified decoder and all DSP problems will go away smile

Code:
signed short inline DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant)
{
	int x = *PrevQuant * quant_mul [Delta & 15];
        x = *PrevSignal + ((int)(x + ((UINT32)x >> 29)) >> 3);
	*PrevSignal=ICLIP16(x);
	*PrevQuant=(*PrevQuant*TableQuant[Delta&7])>>ADPCMSHIFT;
	*PrevQuant=(*PrevQuant<0x7f)?0x7f:((*PrevQuant>0x6000)?0x6000:*PrevQuant);
	return *PrevSignal;
}



Re: AO SDK release 1.4.1 available [Re: Deunan Knute] #43019 07/19/08 03:57 AM
Joined: Mar 2001
Posts: 16,337
R
R. Belmont Offline OP
Very Senior Member
OP Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,337
Nice smile

Re: AO SDK release 1.4.1 available [Re: R. Belmont] #43026 07/19/08 02:00 PM
Joined: May 2008
Posts: 2
K
Kaminari Offline
Member
Offline
Member
K
Joined: May 2008
Posts: 2
Great! in_aodsf updated.

http://foobar2000.xrea.jp/up/

Re: AO SDK release 1.4.1 available [Re: Kaminari] #43028 07/19/08 03:48 PM
Joined: Mar 2001
Posts: 16,337
R
R. Belmont Offline OP
Very Senior Member
OP Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,337
Now there's a cart-ahead-of-the-horse moment wink

Re: AO SDK release 1.4.1 available [Re: R. Belmont] #43251 07/26/08 09:32 PM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
You know what's funny? Since this ADPCM decoder originates in Yamaha YMZ280B driver I peeked into MAME sources today, being sure it has the same bug. And it doesn't, Aaron Giles coded it with "/8" and not ">>3" smile
Don't you just love rediscovering the wheel again...

Re: AO SDK release 1.4.1 available [Re: Deunan Knute] #43261 07/27/08 02:30 AM
Joined: Mar 2001
Posts: 16,337
R
R. Belmont Offline OP
Very Senior Member
OP Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,337
Premature optimization, all evil, etc.

Plus on Northwood-core Pentium 4s the /8 is faster than the >>3 :-)

Re: AO SDK release 1.4.1 available [Re: R. Belmont] #43280 07/27/08 07:03 PM
Joined: Jul 2008
Posts: 5
A
ajax16384 Offline
Member
Offline
Member
A
Joined: Jul 2008
Posts: 5
Interpolation algorithm uses neighbor sample - so we can optimize
ADPCM channel process to use last decoded values. We can rid of "nxt*" variables and second adpcm decode cycles (will speed up ADPCM a little bit). Following diff against aosdk 1.4.1 shows my assumption.

Code:
diff -Nru aosdk_base/eng_dsf/aica.c aosdk/eng_dsf/aica.c
--- aosdk_base/eng_dsf/aica.c	2008-03-07 21:21:32.000000000 +0300
+++ aosdk/eng_dsf/aica.c	2008-07-27 23:05:18.596041500 +0400
@@ -125,12 +125,10 @@
 	struct _LFO ALFO;		//Amplitude LFO
 	int slot;
 	int cur_sample;       //current ADPCM sample
-	int nxt_sample;       //next ADPCM sample
 	int cur_quant;        //current ADPCM step
-	int nxt_quant;        //next ADPCM step
-	int curstep, nxtstep;
+	int curstep;
 	int cur_lpquant, cur_lpsample, cur_lpstep;
-	UINT8 *adbase, *nxtbase, *adlpbase;
+	UINT8 *adbase, *adlpbase;
 	UINT8 mslc;			// monitored?
 };
 
@@ -431,10 +429,9 @@
 		UINT8 *base;
 		UINT32 curstep, steps_to_go;
 
-		slot->curstep = slot->nxtstep = 0;
-		slot->adbase = slot->nxtbase = (unsigned char *) (AICA->AICARAM+((SA(slot))&0x7fffff));
+		slot->curstep = 0;
+		slot->adbase = (unsigned char *) (AICA->AICARAM+((SA(slot))&0x7fffff));
 		InitADPCM(&(slot->cur_sample), &(slot->cur_quant));
-		InitADPCM(&(slot->nxt_sample), &(slot->nxt_quant));
 		InitADPCM(&(slot->cur_lpsample), &(slot->cur_lpquant));
 
 		// walk to the ADPCM state at LSA
@@ -956,7 +953,6 @@
 	UINT32 addr1,addr2,addr_select;                                   // current and next sample addresses
 	UINT32 *addr[2]      = {&addr1, &addr2};                          // used for linear interpolation
 	UINT32 *slot_addr[2] = {&(slot->cur_addr), &(slot->nxt_addr)};    //
-	int    *adpcm_sample[2] = {&(slot->cur_sample), &(slot->nxt_sample)};
 
 	if(SSCTL(slot)!=0)	//no FM or noise yet
 		return 0;
@@ -1007,12 +1003,16 @@
 		UINT8 *p1=(unsigned char *) (AICA->AICARAM+((SA(slot)+(addr1>>1))&0x7fffff));
 		UINT8 *p2=(unsigned char *) (AICA->AICARAM+((SA(slot)+(addr2>>1))&0x7fffff));
 		INT32 s;
+		int cur_sample;       //current ADPCM sample
+		int nxt_sample;       //next ADPCM sample
 		INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
-		UINT32 steps_to_go = addr1, curstep = slot->curstep;
+		UINT32 steps_to_go = addr2, curstep = slot->curstep;
 
 		if (slot->adbase)
 		{
-			// seek to the current sample
+			cur_sample = slot->cur_sample; // may already contains current decoded sample 
+
+			// seek to the interpolation sample
 			while (curstep < steps_to_go)
 			{
 				int shift1, delta1;
@@ -1024,33 +1024,15 @@
 				{
 					base++;
 				}
+				if (curstep == addr1)
+					cur_sample = slot->cur_sample;
 			}
+			nxt_sample = slot->cur_sample;
 
 			slot->adbase = base;
 			slot->curstep = curstep;
 
-			base = slot->nxtbase;
-			curstep = slot->nxtstep;
-			steps_to_go = addr2;
-
-			// seek to the interpolation sample
-			while (curstep < steps_to_go)
-			{
-				int shift1, delta1;
-				shift1 = 4*((curstep&1));
-				delta1 = (*base>>shift1)&0xf;
-				DecodeADPCM(&(slot->nxt_sample),delta1,&(slot->nxt_quant));
-				curstep++;
-				if (!(curstep & 1))
-				{
-					base++;
-				}
-			}
-
-			slot->nxtbase = base;
-			slot->nxtstep = curstep;
-
-			s=(int) slot->cur_sample*((1<<SHIFT)-fpart)+(int) slot->nxt_sample*fpart;
+			s=(int)cur_sample*((1<<SHIFT)-fpart)+(int)nxt_sample*fpart;
 		}
 		else
 		{
@@ -1093,7 +1075,7 @@
 				rem_addr = *slot_addr[addr_select] - (LEA(slot)<<SHIFT);
 				*slot_addr[addr_select]=(LSA(slot)<<SHIFT) + rem_addr;
 
-				if(PCMS(slot)>=2 && addr_select==0)
+				if(PCMS(slot)>=2)
 				{
 					// restore the state @ LSA - the sampler will naturally walk to (LSA + remainder)
 					slot->adbase = &AICA->AICARAM[SA(slot)+(LSA(slot)/2)];
@@ -1106,16 +1088,6 @@
 
 //					printf("Looping: slot_addr %x LSA %x LEA %x step %x base %x\n", *slot_addr[addr_select]>>SHIFT, LSA(slot), LEA(slot), slot->curstep, slot->adbase);
 				}
-				else if(PCMS(slot)>=2 && addr_select==1)
-				{
-					slot->nxtbase = &AICA->AICARAM[SA(slot)+(LSA(slot)/2)];
-					slot->nxtstep = LSA(slot);
-					if (PCMS(slot) == 2)
-					{
-						slot->nxt_sample = slot->cur_lpsample;
-						slot->nxt_quant = slot->cur_lpquant;
-					}
-				}
 			}
 			break;
 		}



Last edited by ajax16384; 07/27/08 07:06 PM.
Re: AO SDK release 1.4.1 available [Re: ajax16384] #43284 07/28/08 04:57 AM
Joined: Mar 2001
Posts: 16,337
R
R. Belmont Offline OP
Very Senior Member
OP Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,337
DK: Just got back to my computer after a ton of vacation (had a laptop but no source to test out). The sound quality improvement from that change is amazing and the samples no longer "float" with a DC offset :-)

Ajax: Thanks. I don't see much real-world CPU improvement but the code cleanup is well worth it.

Re: AO SDK release 1.4.2 available [Re: R. Belmont] #43285 07/28/08 06:06 AM
Joined: Mar 2001
Posts: 16,337
R
R. Belmont Offline OP
Very Senior Member
OP Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,337
An updated SDK has been posted. Thanks everyone.

Page 29 of 55 1 2 27 28 29 30 31 54 55

Moderated by  R. Belmont, Richard Bannister 

Who's Online Now
0 registered members (), 29 guests, and 3 spiders.
Key: Admin, Global Mod, Mod
ShoutChat Box
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,693
Posts114,286
Members4,865
Most Online510
Aug 26th, 2019
Powered by UBB.threads™ PHP Forum Software 7.7.3