Previous Thread
Next Thread
Print Thread
Page 30 of 55 1 2 28 29 30 31 32 54 55
Joined: Feb 2008
Posts: 107
D
Senior Member
Senior Member
D Offline
Joined: Feb 2008
Posts: 107
And nowdays conditional jumps (if predictable enough) are faster than CMOVs on x86. Makes you wonder why Intel introduced those in the first place... Then again, I just found a use for BSR instruction, and nothing beats that idea of theirs to remove hardware shifters from P4 smile

Quite frankly I never much liked how AO handles ADPCM decoding (a bit too complicated for my taste) but at least it seemed to work. Are you sure this change will not break the long stream type on loop jumps? It gets a bit tricky if you're doing interpolation and only keep the last computed sample value...

Joined: Mar 2001
Posts: 17,258
Likes: 267
R
Very Senior Member
Very Senior Member
R Offline
Joined: Mar 2001
Posts: 17,258
Likes: 267
Well, the streaming samples in Naomi Toy Fighter seem to be broken with or without the cleanup patch, so I'm assuming it's not harmful for the moment :-) (Fixing the slot monitor address made them closer to working though).

Joined: Jul 2008
Posts: 5
A
Member
Member
A Offline
Joined: Jul 2008
Posts: 5
loop jumps should work without a problems. current sample takes value from previous interpolation pair calculation or calculates from scratch through decoding of current interpolation pair.
i played several .dsf by modified aosdk - and did not find any difference.

to complete code cleanup i decided to remove addr_select and *addr arrays at all. following diff against 1.4.2 based on the fact that we can check only next sample address for exceeding the LSA or LEA bounds.
Code
diff -Nru aosdk_base/eng_dsf/aica.c aosdk/eng_dsf/aica.c
--- aosdk_base/eng_dsf/aica.c	2008-07-28 01:39:46.000000000 +0400
+++ aosdk/eng_dsf/aica.c	2008-07-28 18:39:47.804063500 +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
@@ -951,12 +948,11 @@
 
 INLINE INT32 AICA_UpdateSlot(struct _AICA *AICA, struct _SLOT *slot)
 {
-	INT32 sample;
+	INT32 sample, fpart;
+	int cur_sample;       //current sample
+	int nxt_sample;       //next sample
 	int step=slot->step;
-	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)};
+	UINT32 addr1,addr2;                                   // current and next sample addresses
 
 	if(SSCTL(slot)!=0)	//no FM or noise yet
 		return 0;
@@ -967,12 +963,7 @@
 		step>>=SHIFT;
 	}
 
-	if(PCMS(slot) == 1)
-	{
-		addr1=slot->cur_addr>>SHIFT;
-		addr2=slot->nxt_addr>>SHIFT;
-	}
-	else if(PCMS(slot) == 0) 
+	if(PCMS(slot) == 0) 
 	{
 		addr1=(slot->cur_addr>>(SHIFT-1))&0x7ffffe;
 		addr2=(slot->nxt_addr>>(SHIFT-1))&0x7ffffe;
@@ -987,32 +978,26 @@
 	{
 		INT8 *p1=(signed char *) (AICA->AICARAM+(((SA(slot)+addr1))&0x7fffff));
 		INT8 *p2=(signed char *) (AICA->AICARAM+(((SA(slot)+addr2))&0x7fffff));
-		INT32 s;
-		INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
-		s=(int) (p1[0]<<8)*((1<<SHIFT)-fpart)+(int) (p2[0]<<8)*fpart;
-		sample=(s>>SHIFT);
+		cur_sample = p1[0] << 8;
+		nxt_sample = p2[0] << 8;
 	}
 	else if (PCMS(slot) == 0)	//16 bit signed
 	{
 		INT16 *p1=(signed short *) (AICA->AICARAM+((SA(slot)+addr1)&0x7fffff));
 		INT16 *p2=(signed short *) (AICA->AICARAM+((SA(slot)+addr2)&0x7fffff));
-		INT32 s;
-		INT32 fpart=slot->cur_addr&((1<<SHIFT)-1);
-		s=(int) LE16(p1[0])*((1<<SHIFT)-fpart)+(int) LE16(p2[0])*fpart;
-		sample=(s>>SHIFT);
+		cur_sample = LE16(p1[0]);
+		nxt_sample = LE16(p2[0]);
 	}
 	else	// 4-bit ADPCM
 	{
 		UINT8 *base= slot->adbase;
-		UINT8 *p1=(unsigned char *) (AICA->AICARAM+((SA(slot)+(addr1>>1))&0x7fffff));
-		UINT8 *p2=(unsigned char *) (AICA->AICARAM+((SA(slot)+(addr2>>1))&0x7fffff));
-		INT32 s;
-		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)
+		if (base)
 		{
-			// 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,42 +1009,23 @@
 				{
 					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;
 		}
 		else
 		{
-			s = 0;
+			cur_sample = nxt_sample = 0;
 		}
-
-		sample=(s>>SHIFT);
 	}
-	
+	fpart = slot->cur_addr & ((1<<SHIFT)-1);
+	sample=cur_sample*((1<<SHIFT)-fpart)+nxt_sample*fpart;
+	sample>>=SHIFT;	
+
 	slot->prv_addr=slot->cur_addr;
 	slot->cur_addr+=step;
 	slot->nxt_addr=slot->cur_addr+(1<<SHIFT);
@@ -1073,52 +1039,43 @@
 			slot->EG.state = DECAY1;
 	}
 
-	for (addr_select=0; addr_select<2; addr_select++)
+	switch(LPCTL(slot))
 	{
-		INT32 rem_addr;
-		switch(LPCTL(slot))
+	case 0:	//no loop
+		if(addr2>=LSA(slot) && addr2>=LEA(slot)) // if next sample exceed then current must exceed too
 		{
-		case 0:	//no loop
-			if(*addr[addr_select]>=LSA(slot) && *addr[addr_select]>=LEA(slot))
-			{
-			//slot->active=0;
+		//slot->active=0;
+		if(slot->mslc) AICA->udata.data[8] |= 0x8000;
+		AICA_StopSlot(slot,0);
+		}
+		break;
+	case 1: //normal loop
+		if(addr2>=LEA(slot))
+		{
+			INT32 rem_addr;
 			if(slot->mslc) AICA->udata.data[8] |= 0x8000;
-			AICA_StopSlot(slot,0);
-			}
-			break;
-		case 1: //normal loop
-			if(*addr[addr_select]>=LEA(slot))
-			{
-				if(slot->mslc) AICA->udata.data[8] |= 0x8000;
-				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)
+			rem_addr = slot->nxt_addr - (LEA(slot)<<SHIFT);
+			slot->nxt_addr = (LSA(slot)<<SHIFT) + rem_addr;
+			if(addr1>=LEA(slot))
+			{
+				rem_addr = slot->cur_addr - (LEA(slot)<<SHIFT);
+				slot->cur_addr = (LSA(slot)<<SHIFT) + rem_addr;
+			}
+				
+			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)];
+				slot->curstep = LSA(slot);
+				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)];
-					slot->curstep = LSA(slot);
-					if (PCMS(slot) == 2)
-					{
-						slot->cur_sample = slot->cur_lpsample;
-						slot->cur_quant = slot->cur_lpquant;
-					}
-
-//					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;
-					}
+					slot->cur_sample = slot->cur_lpsample;
+					slot->cur_quant = slot->cur_lpquant;
 				}
+//printf("Looping: slot_addr %x LSA %x LEA %x step %x base %x\n", slot->cur_addr>>SHIFT, LSA(slot), LEA(slot), slot->curstep, slot->adbase);
 			}
-			break;
 		}
+		break;
 	}
 
 	if(ALFOS(slot)!=0)

Joined: Mar 2001
Posts: 17,258
Likes: 267
R
Very Senior Member
Very Senior Member
R Offline
Joined: Mar 2001
Posts: 17,258
Likes: 267
Thanks. Updated the SDK again, and this time it includes all of the changes I had intended to go into 1.42 smile

Joined: Jul 2008
Posts: 5
A
Member
Member
A Offline
Joined: Jul 2008
Posts: 5
yet another suggestion:
Code
--- aosdk_base/eng_dsf/aica.c	2008-07-28 11:16:04.000000000 +0400
+++ aosdk/eng_dsf/aica.c	2008-07-28 22:59:17.914934500 +0400
@@ -800,7 +800,7 @@
 		case 0x15:
 			{
 				int MSLC = (AICA->udata.data[0xc/2]>>8) & 0x3f;	// which slot are we monitoring?
-				unsigned int CA = AICA->Slots[MSLC].cur_addr>>(SHIFT+12);
+				unsigned int CA = AICA->Slots[MSLC].cur_addr>>(SHIFT/*+12*/);
 
 				AICA->udata.data[0x14/2] = CA;
 			}

Joined: Mar 2001
Posts: 17,258
Likes: 267
R
Very Senior Member
Very Senior Member
R Offline
Joined: Mar 2001
Posts: 17,258
Likes: 267
Hmm, I don't notice any difference anywhere with that change. Is there some test case?

Joined: Feb 2008
Posts: 107
D
Senior Member
Senior Member
D Offline
Joined: Feb 2008
Posts: 107
Why was there +12 in the first place?
BTW: CA should read zero when the sample ends.

Joined: Mar 2001
Posts: 17,258
Likes: 267
R
Very Senior Member
Very Senior Member
R Offline
Joined: Mar 2001
Posts: 17,258
Likes: 267
The +12 is because on the SCSP CA reads back the sample progress in 4096 byte units (which simplifies the 68000 code necessary for streaming). I assume AICA is different? smile

Joined: Jul 2008
Posts: 5
A
Member
Member
A Offline
Joined: Jul 2008
Posts: 5
According to one of aica specs CA register defined as sample position relative to SA. So, an extra +12 shift was a definitely strange piece of code.

CA should read zero when the slot becomes inactive (!Slots[mslc].active) or if the current slot sample position reaches LEA ?

Last edited by ajax16384; 07/29/08 11:26 AM.
Joined: Feb 2008
Posts: 107
D
Senior Member
Senior Member
D Offline
Joined: Feb 2008
Posts: 107
I checked to be sure smile
CA is sample position (and not address as the name would suggest). It's zero if given channel is not playing and that means position is not advancing. It could be because it was never started, reached LEA, or it's AEG counter reaches 960.

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

Moderated by  R. Belmont, Richard Bannister 

Link Copied to Clipboard
Who's Online Now
2 members (nerd4gw, 1 invisible), 115 guests, and 2 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics9,354
Posts122,409
Members5,082
Most Online1,283
Dec 21st, 2022
Our Sponsor
These forums are sponsored by Superior Solitaire, an ad-free card game collection for macOS and iOS. Download it today!

Superior Solitaire
Powered by UBB.threads™ PHP Forum Software 8.0.0