1 /* vi:set ts=4 sts=4 sw=4: */
4 volatile u8 callbackwait
;
16 /*const u16 freqtable[] = {
17 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165, 0x017a, 0x0191, 0x01a9,
18 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259, 0x027d, 0x02a3, 0x02cb,
19 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3, 0x042f, 0x046f, 0x04b2,
20 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5, 0x070a, 0x0775, 0x07e6,
21 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c, 0x0bd6, 0x0c8b, 0x0d4a,
22 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb, 0x13e9, 0x1518, 0x1659,
23 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b, 0x217c, 0x237a, 0x2596,
24 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528, 0x3851, 0x3bab, 0x3f37,
25 0x42f9, 0x46f5, 0x4b2d, 0x4fa6, 0x5462, 0x5967, 0x5eb7, 0x6459, 0x6a51,
26 0x70a3, 0x7756, 0x7e6f
30 /*const u16 freqtable[] = {
31 0x0085, 0x008d, 0x0096, 0x009f, 0x00a8, 0x00b2, 0x00bd, 0x00c8, 0x00d4,
32 0x00e1, 0x00ee, 0x00fc, 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165,
33 0x017a, 0x0191, 0x01a9, 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259,
34 0x027d, 0x02a3, 0x02cb, 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3,
35 0x042f, 0x046f, 0x04b2, 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5,
36 0x070a, 0x0775, 0x07e6, 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c,
37 0x0bd6, 0x0c8b, 0x0d4a, 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb,
38 0x13e9, 0x1518, 0x1659, 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b,
39 0x217c, 0x237a, 0x2596, 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528,
40 0x3851, 0x3bab, 0x3f37
44 const u16 freqtable
[] = {
45 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003b, 0x003f, 0x0042, 0x0046,
46 0x004b, 0x004f, 0x0054, 0x0059, 0x005e, 0x0064, 0x006a, 0x0070, 0x0077,
47 0x007e, 0x0085, 0x008d, 0x0096, 0x009f, 0x00a8, 0x00b2, 0x00bd, 0x00c8,
48 0x00d4, 0x00e1, 0x00ee, 0x00fc, 0x010b, 0x011b, 0x012c, 0x013e, 0x0151,
49 0x0165, 0x017a, 0x0190, 0x01a8, 0x01c2, 0x01dc, 0x01f9, 0x0217, 0x0237,
50 0x0258, 0x027c, 0x02a2, 0x02ca, 0x02f4, 0x0321, 0x0351, 0x0384, 0x03b9,
51 0x03f2, 0x042e, 0x046e, 0x04b1, 0x04f8, 0x0544, 0x0594, 0x05e9, 0x0643,
52 0x06a3, 0x0708, 0x0773, 0x07e4, 0x085c, 0x08dc, 0x0962, 0x09f1, 0x0a89,
53 0x0b29, 0x0bd3, 0x0c87, 0x0d46, 0x0e10, 0x0ee6, 0x0fc9, 0x10b9, 0x11b8,
54 0x12c5, 0x13e3, 0x1512
57 const s8 sinetable
[] = {
58 0, 12, 25, 37, 49, 60, 71, 81, 90, 98, 106, 112, 117, 122, 125, 126,
59 127, 126, 125, 122, 117, 112, 106, 98, 90, 81, 71, 60, 49, 37, 25, 12,
60 0, -12, -25, -37, -49, -60, -71, -81, -90, -98, -106, -112, -117, -122,
61 -125, -126, -127, -126, -125, -122, -117, -112, -106, -98, -90, -81,
62 -71, -60, -49, -37, -25, -12
88 for(i
= 0; i
< 4; i
++){
95 void runcmd(u8 ch
, u8 cmd
, u8 param
){
101 osc
[ch
].duty
= param
<< 8;
104 channel
[ch
].volumed
= param
;
107 channel
[ch
].inertia
= param
<< 1;
110 channel
[ch
].iptr
= param
;
113 channel
[ch
].bendd
= param
;
116 channel
[ch
].dutyd
= param
<< 6;
119 channel
[ch
].iwait
= (param
*6);
122 osc
[ch
].volume
= param
;
125 osc
[ch
].waveform
= param
;
128 channel
[ch
].inote
= param
+ channel
[ch
].tnote
- 12 * 4;
131 channel
[ch
].inote
= param
;
134 if(channel
[ch
].vdepth
!= (param
>> 4)){
135 channel
[ch
].vpos
= 0;
137 channel
[ch
].vdepth
= param
>> 4;
138 channel
[ch
].vrate
= (param
/2) & 0xf;
139 //channel[ch].vrate = param & 0xf;
142 callbacktime
= -param
;
147 void iedplonk(int note
, int instr
){
148 channel
[0].tnote
= note
;
149 channel
[0].inum
= instr
;
151 channel
[0].iwait
= 0;
153 channel
[0].bendd
= 0;
154 channel
[0].volumed
= 0;
155 channel
[0].dutyd
= 0;
156 channel
[0].vdepth
= 0;
159 void startplaytrack(int t
){
170 void startplaysong(int p
){
178 void playroutine(){ // called at 50 Hz
181 if(playtrack
|| playsong
){
190 if(songpos
>= songlen
){
193 for(ch
= 0; ch
< 4; ch
++){
196 readsong(songpos
, ch
, tmp
);
197 channel
[ch
].tnum
= tmp
[0];
198 channel
[ch
].transp
= tmp
[1];
205 if(playtrack
|| playsong
){
206 for(ch
= 0; ch
< 4; ch
++){
207 if(channel
[ch
].tnum
){
211 readtrack(channel
[ch
].tnum
, trackpos
, &tl
);
213 channel
[ch
].tnote
= tl
.note
+ channel
[ch
].transp
;
214 instr
= channel
[ch
].lastinstr
;
220 channel
[ch
].lastinstr
= instr
;
221 channel
[ch
].inum
= instr
;
222 channel
[ch
].iptr
= 0;
223 channel
[ch
].iwait
= 0;
224 channel
[ch
].bend
= 0;
225 channel
[ch
].bendd
= 0;
226 channel
[ch
].volumed
= 0;
227 channel
[ch
].dutyd
= 0;
228 channel
[ch
].vdepth
= 0;
231 runcmd(ch
, tl
.cmd
[0], tl
.param
[0]);
233 runcmd(ch
, tl
.cmd
[1], tl
.param
[1]);
243 for(ch
= 0; ch
< 4; ch
++){
248 // i dunno if that last condition is correct...........................
249 while((channel
[ch
].inum
&& !channel
[ch
].iwait
) || channel
[0].iptr
== 0){
252 readinstr(channel
[ch
].inum
, channel
[ch
].iptr
, il
);
255 runcmd(ch
, il
[0], il
[1]);
257 if(channel
[ch
].iwait
) channel
[ch
].iwait
--;
259 if(channel
[ch
].inertia
){
262 slur
= channel
[ch
].slur
;
263 diff
= freqtable
[channel
[ch
].inote
] - slur
;
264 //diff >>= channel[ch].inertia;
266 if(diff
> channel
[ch
].inertia
) diff
= channel
[ch
].inertia
;
268 if(diff
< -channel
[ch
].inertia
) diff
= -channel
[ch
].inertia
;
271 channel
[ch
].slur
= slur
;
273 slur
= freqtable
[channel
[ch
].inote
];
278 ((channel
[ch
].vdepth
* sinetable
[channel
[ch
].vpos
& 63]) >> 2);
279 channel
[ch
].bend
+= channel
[ch
].bendd
;
280 vol
= osc
[ch
].volume
+ channel
[ch
].volumed
;
282 if(vol
> 255) vol
= 255;
283 osc
[ch
].volume
= vol
;
285 duty
= osc
[ch
].duty
+ channel
[ch
].dutyd
;
286 if(duty
> 0xe000) duty
= 0x2000;
287 if(duty
< 0x2000) duty
= 0xe000;
290 channel
[ch
].vpos
+= channel
[ch
].vrate
;
310 u8
interrupthandler() // called at 9000 Hz
315 static u32 noiseseed
= 1;
318 if(noiseseed
& 0x80000000L
) newbit
^= 1;
319 if(noiseseed
& 0x01000000L
) newbit
^= 1;
320 if(noiseseed
& 0x00000040L
) newbit
^= 1;
321 if(noiseseed
& 0x00000200L
) newbit
^= 1;
322 noiseseed
= (noiseseed
<< 1) | newbit
;
328 callbackwait
= callbacktime
- 1;
332 for(i
= 0; i
< 4; i
++){
333 s8 value
; // [-32,31]
335 switch(osc
[i
].waveform
){
337 if(osc
[i
].phase
< 0x8000){
338 value
= -32 + (osc
[i
].phase
>> 9);
340 value
= 31 - ((osc
[i
].phase
- 0x8000) >> 9);
344 value
= -32 + (osc
[i
].phase
>> 10);
347 value
= (osc
[i
].phase
> osc
[i
].duty
)? -32 : 31;
350 value
= (noiseseed
& 63) - 32;
353 value
= sinetable
[j
];
354 if(j
>= sizeof(sinetable
)-1) j
= 0;
361 osc
[i
].phase
+= osc
[i
].freq
;
363 acc
+= value
* osc
[i
].volume
; // rhs = [-8160,7905]
366 // acc [-32640,31620]
367 return 128 + (acc
>> 8); // [1,251]