Previous Thread
Next Thread
Print Thread
Page 41 of 55 1 2 39 40 41 42 43 54 55
Re: AO SDK release 1.4.6 available [Re: Knurek] #46235 11/08/08 01:26 AM
Joined: Mar 2001
Posts: 16,445
R
R. Belmont Online Content OP
Very Senior Member
OP Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,445
It's handy that the Afterburner II tracks are all "Ab2_xxxx" smile

Re: AO SDK release 1.4.6 available [Re: R. Belmont] #46236 11/08/08 01:42 AM
Joined: Nov 2003
Posts: 459
K
Knurek Offline
Senior Member
Offline
Senior Member
K
Joined: Nov 2003
Posts: 459
Funny how Ab2_001_0D_00_00.minidsf gets heavily distorted after 15 seconds or so.

Re: AO SDK release 1.4.6 available [Re: Knurek] #46237 11/08/08 02:41 AM
Joined: Mar 2001
Posts: 16,445
R
R. Belmont Online Content OP
Very Senior Member
OP Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,445
Yeah, the crash cymbal in the AB2 sets has a *severe* DC offset. In most of the tracks that voice gets reused pretty soon and it doesn't matter, but on some it doesn't and the overall level gets shoved down against 0dB.

Re: AO SDK release 1.4.6 available [Re: Deunan Knute] #46240 11/08/08 04:30 AM
Joined: Sep 2007
Posts: 56
K
kingshriek Offline
Member
Offline
Member
K
Joined: Sep 2007
Posts: 56
Originally Posted By Deunan Knute
First of all, the equation is wrong. If it was like (1.0 - (f + q)) it'd make more sense, but that's still no good. Most of the result comes from f * in part - if the f is too big it won't do much filtering. If it's too small it will all but mute that channel. Since it's only 13 bits I think that ((filtervalue>>8)^0x1F) is a bit of overkill (shifts up to 31 bits).


(1.0 - f + q) looks right to me. It produces a stable lowpass filter for all values of f and q between 0.0 and 1.0. (1.0 - (f + q)) has more of a bandpass characteristic.

As for the ((filtervalue>>8)^0x1F) part, it looks a bit weird to me, too - causes more than half the filter values to produce filters w/ zero (-infinity dB) gain.

Originally Posted By Deunan Knute
In short: I'm lost. I've said it before that signal processing is not my forte - I don't really get the math behind IIR filters. I've tried some random changes, alas only ended up with unstable vibrato or noise generators smile Any ideas?


Not sure exactly what's going wrong. Are you scaling the f the q values properly (to account for their fixed-point representation)?

Re: AO SDK release 1.4.6 available [Re: kingshriek] #46241 11/08/08 09:35 AM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
I'm going to check again but this filter simply mutes things too much. I don't know, maybe it's another bug somewhere else but some channels are keyed on with infinite (or close to) attack rate, so we can focus on single-value filtering. In this case filtering value looks like 0x1d78 for example, so you can calculate f for it. Q is 0x400 (0x04 scaled to produce 0x1fff from 0x1f range: << 8 in my case).

If the envelope value is 0x1ff8 it's seems to be working. No low-pass filtering (since x * f is gives back more or less x, q can be all but ignored). Now, the way I understand IIR filters it's supposed to be an integrator of sorts? So, for low cut-off frequency it should be adding very little of the current sample and keep adding the previous values. This way for a DC signal the output should reach the input eventually?
Now, let's say f is close to zero. That gets us small x * f, that's what we want. But even if Q is big, the previous values can only be previous x * f and for DC input it's all the same. So that leaves us with:

y = u0 + (1 + q) * v1 - q * v2 = u0 + v1 + q * (v1 - v2)
(where u0 = f * x input (small), v is previous output, and 1 - f can be replaced with 1)

Let's say x is positive. That makes u and v > 0 always. This means v1 - v2 is also > 0, so the y value will only get bigger over time. And will not stop at input level, but go all the way to infinity. This is not a stable filter?

Theory says 2-nd order IIR looks like this:

y = 1/a0 (b0 * x0 + b1 * x1 - a1 * v1)

a0 is usually 1, so we can do away with it. This filter uses previous input values as well... I kinda like it better than using only previous output values. Then again, I know nothing so don't hit me smile

What order filter are we trying to get here? I guess 2nd or 3rd at best, right? Isn't it strange that we only use previous output values (all bn coefficients are zero then)? I've tried some Java scripts out there to get coefficient values for low-pass filters and would always end up with non-zero b1 at least?

EDIT: One shouldn't be doing math so late at night...
I'm not so sure now 1 - f can be simplified with 1. If I don't do that:

u0 + (1 - f + q) * v1 - q * v2
u0 + v1 - f * v1 + q * (v1 - v2)
v1 + f * (x - v1) + q * (v1 - v2)

q * (v1 - v2) is very small, so we get a fight between x and v1. In the end it should come to an equilibrium when v1 = x... then why the hell I'm getting saturation?

Last edited by Deunan Knute; 11/08/08 10:08 AM.
Re: AO SDK release 1.4.6 available [Re: Deunan Knute] #46242 11/08/08 12:47 PM
Joined: Sep 2007
Posts: 56
K
kingshriek Offline
Member
Offline
Member
K
Joined: Sep 2007
Posts: 56
This particular filter's frequency response spikes up in the passband right before coming to the cutoff frequency. How much it spikes depends mostly on the value of q (f mainly determines where the cutoff frequency happens so it also has a minor affect on the spike). For example, with values f=0.2 and q=0.8, the frequency response gain peaks at about +6.0 dB at 3 kHz, so it definitely has potential to push higher-amplitude tones beyond the saturation range.

I wrote up a quick Python script to examine the impulse and frequency response for this filter for particular values of f and q. Not sure if this will help at all, but here it is just in case:

Code:
from cmath import *

xs = [0.0 for k in range(100)]; xs[0] = 1.0
ys = [0.0, 0.0, 0.0]
ws = [k/100.0 for k in range(101)]

def imp_response(f,q):
	print 'Impulse response'
	i = 0
	for x in xs:
		j = [(i+k)%3 for k in range(3)]
		ys[j[2]] = f*x + (1 - f + q)*ys[j[1]] - q*ys[j[0]]
		print '%02d     %+0.8f' % (i,ys[j[2]])
		i += 1
	
def freq_response(f,q):
	print 'Frequency response'
	for w in ws:
		zi = exp(-1.0j*pi*w)
		H = f / (1 - (1 - f + q)*zi + q*zi*zi)
		print '%7.1f Hz     %+2.3f dB' % (22050.0*w,20.0*log10(abs(H)).real)

if __name__ == '__main__':
	f = 0.2
	q = 0.8
	imp_response(f,q)
	freq_response(f,q)




Re: AO SDK release 1.4.6 available [Re: kingshriek] #46243 11/08/08 03:13 PM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
If an equation doesn't work it means that assumptions are incorrect. In this case I wrote "q * (v1 - v2) is very small" but turns out it was not. More specifically I was getting rather big v1 & v2 and with different sign. That really upset the filter and made it into noise generator. The cause? I messed up the integrator part, I was assigning wrong value to the "prev_out"...
You may kill me now smile

I'm still not sure about some of the envelope stuff, or when exactly I should be doing sample range saturation, but it seems to work now.

Re: AO SDK release 1.4.6 available [Re: Deunan Knute] #46244 11/08/08 03:23 PM
Joined: Mar 2001
Posts: 16,445
R
R. Belmont Online Content OP
Very Senior Member
OP Online Content
Very Senior Member
R
Joined: Mar 2001
Posts: 16,445
So what are the final correct equations for f, q, and out so I can fix my copy of Neill's document? smile

Re: AO SDK release 1.4.6 available [Re: R. Belmont] #46245 11/08/08 03:43 PM
Joined: Feb 2008
Posts: 107
D
Deunan Knute Offline
Senior Member
Offline
Senior Member
D
Joined: Feb 2008
Posts: 107
I went with Corlett's original suggestions for now. I've tried various things, for example:
f = (((filtervalue & 0xFF) | 0x100) * (filtervalue>>8)) >> 1
but this doesn't do enough filtering.
Looking at the graphs in AICA docs, the sensible filter values (cutoff > 100Hz) start at 0x1400 anyway. So maybe it really is shifted like that.
As for q, I just shift it 8 bits left to make all coefficients 13-bit.

Re: AO SDK release 1.4.6 available [Re: Deunan Knute] #47237 01/06/09 12:18 PM
Joined: Nov 2003
Posts: 459
K
Knurek Offline
Senior Member
Offline
Senior Member
K
Joined: Nov 2003
Posts: 459
Managed to find another sequenced game:

Treasure Strike (2000)(h.a.n.d., KID):

http://dsf.hcs64.com/Treasure%20Strike%20(2000)(h.a.n.d.,%20KID).zip

Pretty crappy music compared to other KID games, but they only published this one.

Page 41 of 55 1 2 39 40 41 42 43 54 55

Moderated by  R. Belmont, Richard Bannister 

Who's Online Now
1 registered members (ICEknight), 169 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,750
Posts114,995
Members4,884
Most Online890
Jan 17th, 2020
Powered by UBB.threads™ PHP Forum Software 7.7.3