1 /*---------------------------------------------------------------------------*
2   Project:  SP objects and LPF coefs for axfilter demo
3   File:     lpfdemo.h
4 
5   Copyright (C)1998-2006 Nintendo  All Rights Reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: lpfdemo.h,v $
14   Revision 1.5  2006/11/14 01:46:39  aka
15   Revised comment.
16 
17   Revision 1.4  2006/11/10 01:48:06  aka
18   Updated Biquad IIR filter coefs.
19 
20   Revision 1.3  2006/11/07 05:57:20  aka
21   Added Biquad IIR filter coefs.
22 
23   Revision 1.2  2006/02/02 02:36:39  aka
24   Added copyright.
25 
26   $NoKeywords: $
27 
28  *---------------------------------------------------------------------------*/
29 
30 // -----------------------------------------------------------------
31 // SP table entry indices for lpfdemo.spd
32 // -----------------------------------------------------------------
33 
34 #define MSX_GS_LEFT         0
35 #define MSX_GS_RIGHT        1
36 #define MSX_SPL_LEFT        2
37 #define MSX_SPL_RIGHT       3
38 #define MSX_CAR_LEFT        4
39 #define MSX_CAR_RIGHT       5
40 #define SFX_GUNSHOT         6
41 #define SFX_PINK            7
42 #define SFX_WHITE           8
43 #define SFX_MACHINE_GUN     9
44 #define SFX_EXPLOSION       10
45 #define SFX_FOOTSTEPS       11
46 #define SFX_NGC_MAN         12
47 
48 // -----------------------------------------------------------------
49 // Coefficient table for LPF
50 // -----------------------------------------------------------------
51 // The filter is a simple one-pole function:
52 //
53 //     y(n) = a0*x(n) - b0*y(n-1)
54 //
55 // Where x(n) is the current input sample, and y(n-1) is the previous
56 // output sample. The coefficients a0 and b0 can be calculated thusly:
57 //
58 //     c  = 2.0 - cos(2*pi * freq)
59 //     b0 = sqrt(c^2 - 1) - c
60 //     a0 = 1 + b0
61 //
62 // Where freq is in HZ and must be within the range:
63 //
64 //     0 > freq < 16,000
65 //
66 // The coefficients must be unsigned, 16-bit words in fixed-point
67 // format, having 1 bit of integer and 15 bits of fraction.
68 // Furthermore, the b0 term must be (arithmetically) negated before
69 // being sent to the DSP. This is because of an optimization in the
70 // DSP filter calculation that is afforded by the absence of a sign
71 // bit in the coefficients.
72 //
73 
74 #define NUM_FREQ_CUTOFF 24  // we're using 24 steps in the freq range
75 
76 typedef struct
77 {
78     u16 a0;
79     u16 b0;
80     char *text;
81 
82 } __LPF_COEF;
83 
84 static __LPF_COEF __coefs[] =
85 {
86     {  0x6a09, 0x15f6, "16000 Hz" },
87     {  0x6871, 0x178e, "12800 Hz" },
88     {  0x6463, 0x1b9c, "10240 Hz" },
89     {  0x5db3, 0x224c, "8000 Hz " },
90     {  0x5618, 0x29e7, "6400 Hz " },
91     {  0x4d7a, 0x3285, "5120 Hz " },
92     {  0x4367, 0x3c98, "4000 Hz " },
93     {  0x3a5a, 0x45a5, "3200 Hz " },
94     {  0x31c5, 0x4e3a, "2560 Hz " },
95     {  0x2924, 0x56db, "2000 Hz " },
96     {  0x2244, 0x5dbb, "1600 Hz " },
97     {  0x1c50, 0x63af, "1280 Hz " },
98     {  0x16c0, 0x693f, "1000 Hz " },
99     {  0x1292, 0x6d6d, "800 Hz  " },
100     {  0x0f18, 0x70e7, "640 Hz  " },
101     {  0x0bf5, 0x740a, "500 Hz  " },
102     {  0x09a9, 0x7656, "400 Hz  " },
103     {  0x07ca, 0x7835, "320 Hz  " },
104     {  0x0646, 0x79b9, "256 Hz  " },
105     {  0x04ed, 0x7b12, "200 Hz  " },
106     {  0x03f5, 0x7c0a, "160 Hz  " },
107     {  0x032d, 0x7cd2, "128 Hz  " },
108     {  0x027d, 0x7d82, "100 Hz  " },
109     {  0x01fe, 0x7e01, "80 Hz   " }
110 };
111 
112 // -----------------------------------------------------------------
113 // Coefficient tables for Biquad IIR filter
114 // -----------------------------------------------------------------
115 // Following tables are examples of Biquad IIR filter coefficients.
116 //
117 //           y(n) = b0 * x(n) + b1 * x(n-1) + b2 * x(n-2) + a1 * y(n-1) + a2 * y(n-2)
118 //
119 //    IN--->[+]-------------->+--->[ x b0 ]-->[+]--->OUT
120 //           |                |                |
121 //           |             [ Z^-1 ]            |
122 //           |                |                |
123 //           +<---[ x a1 ]<---+--->[ x b1 ]--->+
124 //           |                |                |
125 //           |             [ Z^-1 ]            |
126 //           |                |                |
127 //           +<---[ x a2 ]<---+--->[ x b2 ]--->+
128 //
129 //
130 //                    b0 + b1(Z^-1) + b2(Z^-2)
131 //           H(z) = ----------------------------
132 //                    1  - a1(Z^-1) - a2(Z^-2)
133 //
134 // The coefficients are calculated by Chebyshev approximation.
135 //
136 // The coefficients must be unsigned, 16-bit words in fixed-point
137 // format, having 2 bit of integer and 14 bits of fraction.
138 //
139 // ex) in case of LPF (fc=80Hz)...
140 //
141 //             orignal coefs      converted coefs for DSP
142 //      b0 =    0.000087f     ->          0x0001
143 //      b1 =    0.000175f     ->          0x0003
144 //      b2 =    0.000087f     ->          0x0001
145 //      a1 =    1.977486f     ->          0x7e8f
146 //      a2 =   -0.977856f     ->          0xc16b
147 //
148 
149 typedef struct
150 {
151     u16  b0;
152     u16  b1;
153     u16  b2;
154     u16  a1;
155     u16  a2;
156     char *text;
157 
158 } __BIQUAD_COEF;
159 
160 static __BIQUAD_COEF __biquad_lpf_coefs[] =
161 {
162     { 0x36fa, 0x6df4, 0x36fa, 0x8c47, 0xcaca, "16000 Hz"}, // actually 15000 Hz
163     { 0x2bf0, 0x57e0, 0x2bf0, 0xa967, 0xdc70, "12800 Hz"},
164     { 0x2071, 0x40e3, 0x2071, 0xcd87, 0xe904, "10240 Hz"},
165     { 0x173d, 0x2e7b, 0x173d, 0xef3d, 0xee4c, " 8000 Hz"},
166     { 0x110d, 0x221a, 0x110d, 0x0903, 0xeec0, " 6400 Hz"},
167     { 0x0c59, 0x18b3, 0x0c59, 0x1eee, 0xecbf, " 5120 Hz"},
168     { 0x087e, 0x10fc, 0x087e, 0x332c, 0xe8d8, " 4000 Hz"},
169     { 0x05f5, 0x0bea, 0x05f5, 0x423b, 0xe487, " 3200 Hz"},
170     { 0x041f, 0x083d, 0x041f, 0x4e96, 0xdff6, " 2560 Hz"},
171     { 0x02b3, 0x0565, 0x02b3, 0x598e, 0xdb05, " 2000 Hz"},
172     { 0x01d1, 0x03a3, 0x01d1, 0x616d, 0xd6df, " 1600 Hz"},
173     { 0x0137, 0x026e, 0x0137, 0x67b7, 0xd325, " 1280 Hz"},
174     { 0x00c5, 0x018a, 0x00c5, 0x6d2e, 0xcf90, " 1000 Hz"},
175     { 0x0082, 0x0103, 0x0082, 0x710d, 0xccce, "  800 Hz"},
176     { 0x0055, 0x00a9, 0x0055, 0x741f, 0xca7b, "  640 Hz"},
177     { 0x0035, 0x0069, 0x0035, 0x76c7, 0xc85a, "  500 Hz"},
178     { 0x0022, 0x0044, 0x0022, 0x78a9, 0xc6c7, "  400 Hz"},
179     { 0x0016, 0x002c, 0x0016, 0x7a27, 0xc57c, "  320 Hz"},
180     { 0x000e, 0x001d, 0x000e, 0x7b57, 0xc46d, "  256 Hz"},
181     { 0x0009, 0x0012, 0x0009, 0x7c5f, 0xc37c, "  200 Hz"},
182     { 0x0006, 0x000b, 0x0006, 0x7d1b, 0xc2ce, "  160 Hz"},
183     { 0x0004, 0x0007, 0x0004, 0x7db0, 0xc241, "  128 Hz"},
184     { 0x0002, 0x0004, 0x0002, 0x7e32, 0xc1c5, "  100 Hz"},
185     { 0x0001, 0x0003, 0x0001, 0x7e8f, 0xc16b, "   80 Hz"}
186 };
187 
188 static __BIQUAD_COEF __biquad_hpf_coefs[] =
189 {
190     { 0x3bf9, 0x880e, 0x3bf9, 0x7f0d, 0xc0f1, "   80 Hz"},
191     { 0x3bdd, 0x8846, 0x3bdd, 0x7ed0, 0xc12c, "  100 Hz"},
192     { 0x3bb5, 0x8896, 0x3bb5, 0x7e7b, 0xc17f, "  128 Hz"},
193     { 0x3b88, 0x88f1, 0x3b88, 0x7e19, 0xc1dd, "  160 Hz"},
194     { 0x3b4f, 0x8962, 0x3b4f, 0x7d9e, 0xc252, "  200 Hz"},
195     { 0x3b00, 0x8a00, 0x3b00, 0x7cf1, 0xc2f5, "  256 Hz"},
196     { 0x3aa6, 0x8ab4, 0x3aa6, 0x7c2b, 0xc3ac, "  320 Hz"},
197     { 0x3a36, 0x8b95, 0x3a36, 0x7b31, 0xc48f, "  400 Hz"},
198     { 0x39aa, 0x8cac, 0x39aa, 0x79f8, 0xc5a5, "  500 Hz"},
199     { 0x38e8, 0x8e31, 0x38e8, 0x783d, 0xc722, "  640 Hz"},
200     { 0x380b, 0x8fea, 0x380b, 0x763e, 0xc8ca, "  800 Hz"},
201     { 0x36fa, 0x920c, 0x36fa, 0x73b9, 0xcaca, " 1000 Hz"},
202     { 0x3580, 0x9500, 0x3580, 0x7027, 0xcd77, " 1280 Hz"},
203     { 0x33d7, 0x9852, 0x33d7, 0x6c03, 0xd05c, " 1600 Hz"},
204     { 0x31ce, 0x9c64, 0x31ce, 0x66c2, 0xd3bc, " 2000 Hz"},
205     { 0x2f06, 0xa1f5, 0x2f06, 0x5f4a, 0xd80d, " 2560 Hz"},
206     { 0x2bf0, 0xa821, 0x2bf0, 0x569a, 0xdc70, " 3200 Hz"},
207     { 0x2836, 0xaf95, 0x2836, 0x4b8b, 0xe12e, " 4000 Hz"},
208     { 0x2334, 0xb998, 0x2334, 0x3bb7, 0xe68e, " 5120 Hz"},
209     { 0x1dbf, 0xc483, 0x1dbf, 0x2913, 0xeb0d, " 6400 Hz"},
210     { 0x173d, 0xd186, 0x173d, 0x10c3, 0xee4c, " 8000 Hz"},
211     { 0x0eab, 0xe2ab, 0x0eab, 0xec30, 0xee0b, "10240 Hz"},
212     { 0x05f5, 0xf416, 0x05f5, 0xbdc5, 0xe487, "12800 Hz"},
213     { 0x00c5, 0xfe77, 0x00c5, 0x92d2, 0xcf90, "16000 Hz"}  // actually 15000 Hz
214 };
215 
216 static __BIQUAD_COEF __biquad_bpf_coefs[] =
217 {
218     { 0x3ff5, 0x0000, 0xc00c, 0x0000, 0x3fea, "   0 - 16000 Hz"},
219     { 0x3c9d, 0x0000, 0xc364, 0x061c, 0x393a, "  80 - 14464 Hz"},
220     { 0x398b, 0x0000, 0xc676, 0x0c2a, 0x3315, "  95 - 12928 Hz"},
221     { 0x36c4, 0x0000, 0xc93d, 0x11b5, 0x2d88, " 101 - 11520 Hz"},
222     { 0x3427, 0x0000, 0xcbd9, 0x16e1, 0x284e, " 113 - 10240 Hz"},
223     { 0x31cc, 0x0000, 0xce35, 0x1b88, 0x2398, " 127 -  9152 Hz"},
224     { 0x2f65, 0x0000, 0xd09b, 0x2044, 0x1eca, " 143 -  8128 Hz"},
225     { 0x2d16, 0x0000, 0xd2eb, 0x24d3, 0x1a2b, " 160 -  7232 Hz"},
226     { 0x2ae2, 0x0000, 0xd51f, 0x2927, 0x15c3, " 180 -  6464 Hz"},
227     { 0x28a0, 0x0000, 0xd760, 0x2d96, 0x1141, " 202 -  5760 Hz"},
228     { 0x2652, 0x0000, 0xd9af, 0x3220, 0x0ca3, " 226 -  5120 Hz"},
229     { 0x2418, 0x0000, 0xdbe9, 0x367d, 0x082f, " 254 -  4576 Hz"},
230     { 0x21b7, 0x0000, 0xde49, 0x3b26, 0x036f, " 286 -  4064 Hz"},
231     { 0x1f59, 0x0000, 0xe0a7, 0x3fcd, 0xfeb3, " 320 -  3616 Hz"},
232     { 0x1d03, 0x0000, 0xe2fd, 0x445e, 0xfa07, " 360 -  3232 Hz"},
233     { 0x1a92, 0x0000, 0xe56e, 0x4927, 0xf525, " 404 -  2880 Hz"},
234     { 0x1807, 0x0000, 0xe7fa, 0x4e25, 0xf00e, " 452 -  2560 Hz"},
235     { 0x157d, 0x0000, 0xea84, 0x531c, 0xeafa, " 508 -  2288 Hz"},
236     { 0x12b6, 0x0000, 0xed4a, 0x588a, 0xe56d, " 572 -  2032 Hz"},
237     { 0x0fdf, 0x0000, 0xf022, 0x5e1d, 0xdfbe, " 640 -  1808 Hz"},
238     { 0x0ce7, 0x0000, 0xf31a, 0x63e8, 0xd9ce, " 720 -  1616 Hz"},
239     { 0x09aa, 0x0000, 0xf657, 0x6a3e, 0xd354, " 808 -  1440 Hz"},
240     { 0x061f, 0x0000, 0xf9e2, 0x7130, 0xcc3e, " 904 -  1280 Hz"},
241     { 0x0239, 0x0000, 0xfdc8, 0x78cc, 0xc472, "1016 -  1144 Hz"}
242 };
243