* Mod parser parses patterns, just got to figure out what the period values mean...
[pineappletracker.git] / chip.c
blob758bcb0fb599fc0fcdeba0c4d64be0f5b2378578
1 /* vi:set ts=8 sts=8 sw=8 noexpandtab: */
2 #include "pineapple.h"
4 u8 trackwait;
5 u8 trackpos;
6 u8 songpos;
8 u8 playsong;
9 u8 playtrack;
11 /*const u16 freqtable[] = {
12 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165, 0x017a, 0x0191, 0x01a9,
13 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259, 0x027d, 0x02a3, 0x02cb,
14 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3, 0x042f, 0x046f, 0x04b2,
15 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5, 0x070a, 0x0775, 0x07e6,
16 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c, 0x0bd6, 0x0c8b, 0x0d4a,
17 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb, 0x13e9, 0x1518, 0x1659,
18 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b, 0x217c, 0x237a, 0x2596,
19 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528, 0x3851, 0x3bab, 0x3f37,
20 0x42f9, 0x46f5, 0x4b2d, 0x4fa6, 0x5462, 0x5967, 0x5eb7, 0x6459, 0x6a51,
21 0x70a3, 0x7756, 0x7e6f
22 };*/
24 // for 16kHz
25 /*const u16 freqtable[] = {
26 0x0085, 0x008d, 0x0096, 0x009f, 0x00a8, 0x00b2, 0x00bd, 0x00c8, 0x00d4,
27 0x00e1, 0x00ee, 0x00fc, 0x010b, 0x011b, 0x012c, 0x013e, 0x0151, 0x0165,
28 0x017a, 0x0191, 0x01a9, 0x01c2, 0x01dd, 0x01f9, 0x0217, 0x0237, 0x0259,
29 0x027d, 0x02a3, 0x02cb, 0x02f5, 0x0322, 0x0352, 0x0385, 0x03ba, 0x03f3,
30 0x042f, 0x046f, 0x04b2, 0x04fa, 0x0546, 0x0596, 0x05eb, 0x0645, 0x06a5,
31 0x070a, 0x0775, 0x07e6, 0x085f, 0x08de, 0x0965, 0x09f4, 0x0a8c, 0x0b2c,
32 0x0bd6, 0x0c8b, 0x0d4a, 0x0e14, 0x0eea, 0x0fcd, 0x10be, 0x11bd, 0x12cb,
33 0x13e9, 0x1518, 0x1659, 0x17ad, 0x1916, 0x1a94, 0x1c28, 0x1dd5, 0x1f9b,
34 0x217c, 0x237a, 0x2596, 0x27d3, 0x2a31, 0x2cb3, 0x2f5b, 0x322c, 0x3528,
35 0x3851, 0x3bab, 0x3f37
36 };*/
38 // for 48kHz
39 const u16 freqtable[] = {
40 0x002c, 0x002f, 0x0032, 0x0035, 0x0038, 0x003b, 0x003f, 0x0042, 0x0046,
41 0x004b, 0x004f, 0x0054, 0x0059, 0x005e, 0x0064, 0x006a, 0x0070, 0x0077,
42 0x007e, 0x0085, 0x008d, 0x0096, 0x009f, 0x00a8, 0x00b2, 0x00bd, 0x00c8,
43 0x00d4, 0x00e1, 0x00ee, 0x00fc, 0x010b, 0x011b, 0x012c, 0x013e, 0x0151,
44 0x0165, 0x017a, 0x0190, 0x01a8, 0x01c2, 0x01dc, 0x01f9, 0x0217, 0x0237,
45 0x0258, 0x027c, 0x02a2, 0x02ca, 0x02f4, 0x0321, 0x0351, 0x0384, 0x03b9,
46 0x03f2, 0x042e, 0x046e, 0x04b1, 0x04f8, 0x0544, 0x0594, 0x05e9, 0x0643,
47 0x06a3, 0x0708, 0x0773, 0x07e4, 0x085c, 0x08dc, 0x0962, 0x09f1, 0x0a89,
48 0x0b29, 0x0bd3, 0x0c87, 0x0d46, 0x0e10, 0x0ee6, 0x0fc9, 0x10b9, 0x11b8,
49 0x12c5, 0x13e3, 0x1512
52 const s8 sinetable[] = {
53 0, 12, 25, 37, 49, 60, 71, 81, 90, 98, 106, 112, 117, 122, 125, 126,
54 127, 126, 125, 122, 117, 112, 106, 98, 90, 81, 71, 60, 49, 37, 25, 12,
55 0, -12, -25, -37, -49, -60, -71, -81, -90, -98, -106, -112, -117, -122,
56 -125, -126, -127, -126, -125, -122, -117, -112, -106, -98, -90, -81,
57 -71, -60, -49, -37, -25, -12
60 struct channel {
61 u8 tracknum;
62 s8 transp;
63 u8 tracknote;
64 u8 lastinstr;
65 u8 instrnum;
66 u8 instrptr;
67 u8 instrwait;
68 u8 instrnote;
69 s8 benddelta;
70 s16 bend;
71 s8 volumedelta;
72 s16 dutydelta;
73 u8 vdepth;
74 u8 vrate;
75 u8 vpos;
76 s16 inertia;
77 u16 slur;
78 } channel[4];
80 void runcmd(u8 ch, u8 cmd, u8 param){
81 switch(cmd){
82 case 'd':
83 osc[ch].duty = param << 8;
84 break;
85 case 'f':
86 channel[ch].volumedelta = param;
87 break;
88 case 'i':
89 channel[ch].inertia = param << 1;
90 break;
91 case 's':
92 channel[ch].benddelta = param;
93 break;
94 case 'm':
95 channel[ch].dutydelta = param << 6;
96 break;
97 case 't':
98 channel[ch].instrwait = param;
99 break;
100 case 'v':
101 osc[ch].volume = param;
102 break;
103 case 'w':
104 osc[ch].waveform = param;
105 break;
106 case '@':
107 channel[ch].instrptr = param;
108 break;
109 case '=':
110 channel[ch].instrnote = param;
111 break;
112 case '+':
113 // 12 * 4 = C4;
114 channel[ch].instrnote = param + channel[ch].tracknote - 12 * 4;
115 break;
116 case '~':
117 if(channel[ch].vdepth != (param >> 4)){
118 channel[ch].vpos = 0;
120 channel[ch].vdepth = param >> 4;
121 channel[ch].vrate = param & 0xf;
122 break;
123 case '*':
124 callbacktime = -param;
125 break;
129 void silence(void){
130 for(u8 i = 0; i < 4; i++){
131 osc[i].volume = 0;
133 playsong = 0;
134 playtrack = 0;
137 void iedplonk(int note, int instr){
138 channel[0].tracknote = note;
139 channel[0].instrnum = instr;
140 channel[0].instrptr = 0;
141 channel[0].instrwait = 0;
142 channel[0].bend = 0;
143 channel[0].benddelta = 0;
144 channel[0].volumedelta = 0;
145 channel[0].dutydelta = 0;
146 channel[0].vdepth = 0;
149 void startplaytrack(int t){
150 channel[0].tracknum = t;
151 channel[1].tracknum = 0;
152 channel[2].tracknum = 0;
153 channel[3].tracknum = 0;
154 trackpos = 0;
155 trackwait = 0;
156 playtrack = 1;
157 playsong = 0;
160 void startplaysong(int p){
161 songpos = p;
162 trackpos = 0;
163 trackwait = 0;
164 playtrack = 0;
165 playsong = 1;
168 void initchip(void){
169 trackwait = 0;
170 trackpos = 0;
171 playsong = 0;
172 playtrack = 0;
174 osc[0].volume = 0;
175 channel[0].instrnum = 0;
176 osc[1].volume = 0;
177 channel[1].instrnum = 0;
178 osc[2].volume = 0;
179 channel[2].instrnum = 0;
180 osc[3].volume = 0;
181 channel[3].instrnum = 0;
184 void playroutine(void){
185 if(playsong||playtrack){
189 /*void process_frame(struct trackline *tl, struct oscillator *o){
192 volatile u8 hello = 60;
193 volatile u8 callbackwait = 0;
194 u8 callbacktime = 180;
196 u8 interrupthandler(void){
197 s16 hai = 0; // [-32768, 32767]
199 if(callbackwait){
200 callbackwait--;
201 }else{
202 callbackwait = 0;
203 playroutine();
206 /*for(u8 i=0; i<4; i++){
207 s8 amplitude;
209 switch(osc[i].waveform){
210 case WF_SAW:
211 break;
212 default:
213 break;
215 osc[i].phase += osc[i].freq;
217 if(hello==180){ hello=60; }
218 else{ hello++; }
220 hai = hello;
222 return 128 + (hai >> 8);