author | mickeyl <mickeyl> | 2004-01-20 13:07:31 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2004-01-20 13:07:31 (UTC) |
commit | d388324e7b91bdd95553c3849d77cddd5bd0bfc4 (patch) (unidiff) | |
tree | ef660ffd25aa8cabbfa58e6c3b170e7c82511bc6 /noncore/multimedia/powerchord/gs.cpp | |
parent | 105007cca23072ee42a1f36625979966eb8a4854 (diff) | |
download | opie-d388324e7b91bdd95553c3849d77cddd5bd0bfc4.zip opie-d388324e7b91bdd95553c3849d77cddd5bd0bfc4.tar.gz opie-d388324e7b91bdd95553c3849d77cddd5bd0bfc4.tar.bz2 |
initial import of powerchord courtesy Camilo Mesias <mailto:camilo@mesias.co.uk>
modified some bits to be compatible with the opie build system
packaging not complete yet
i hope camilo will maintain this here...
Diffstat (limited to 'noncore/multimedia/powerchord/gs.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/multimedia/powerchord/gs.cpp | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/noncore/multimedia/powerchord/gs.cpp b/noncore/multimedia/powerchord/gs.cpp new file mode 100644 index 0000000..a3e85c9 --- a/dev/null +++ b/noncore/multimedia/powerchord/gs.cpp | |||
@@ -0,0 +1,460 @@ | |||
1 | |||
2 | //#include <FL/Fl.H> | ||
3 | //#include <FL/Fl_Widget.H> | ||
4 | //#include <FL/fl_draw.H> | ||
5 | #include <stdio.h> | ||
6 | //#include <qpixmap.h> | ||
7 | #include "gs.h" | ||
8 | |||
9 | #include <sys/ioctl.h> | ||
10 | #include <unistd.h> | ||
11 | #include <fcntl.h> | ||
12 | #include <sys/soundcard.h> | ||
13 | |||
14 | #include <errno.h> | ||
15 | #include <string.h> | ||
16 | |||
17 | #include <stdlib.h> | ||
18 | |||
19 | //#include <qpainter.h> | ||
20 | #include <qmessagebox.h> | ||
21 | |||
22 | |||
23 | gs::gs() | ||
24 | { | ||
25 | |||
26 | finger[0] = OPEN; | ||
27 | finger[1] = OPEN; | ||
28 | finger[2] = OPEN; | ||
29 | finger[3] = OPEN; | ||
30 | finger[4] = OPEN; | ||
31 | finger[5] = OPEN; | ||
32 | |||
33 | tuning[0] = 0; | ||
34 | tuning[1] = 0; | ||
35 | tuning[2] = 0; | ||
36 | tuning[3] = 0; | ||
37 | tuning[4] = 0; | ||
38 | tuning[5] = 0; | ||
39 | |||
40 | initial_fret = 0; | ||
41 | |||
42 | audio_fd = -1; | ||
43 | |||
44 | pb_rate0 = 0; | ||
45 | pb_rate1 = 0; | ||
46 | pb_rate2 = 0; | ||
47 | pb_rate3 = 0; | ||
48 | pb_rate4 = 0; | ||
49 | pb_rate5 = 0; | ||
50 | pb_rate6 = 0; | ||
51 | |||
52 | pb_oct0 = 0; | ||
53 | pb_oct1 = 0; | ||
54 | pb_oct2 = 0; | ||
55 | pb_oct3 = 0; | ||
56 | pb_oct4 = 0; | ||
57 | pb_oct5 = 0; | ||
58 | pb_oct6 = 0; | ||
59 | |||
60 | // initialise reverb buffer | ||
61 | reverb = (signed short *)malloc(1024 * sizeof(signed short)); | ||
62 | |||
63 | for (reverb_ptr=0;reverb_ptr<1024;reverb_ptr++){ | ||
64 | reverb[reverb_ptr] = 0; | ||
65 | } | ||
66 | reverb_ptr = 0; | ||
67 | reverb_max = 1024; | ||
68 | |||
69 | // load sampled 'E' string | ||
70 | int samplen = 25000; | ||
71 | |||
72 | signed short *dsp_buf = (signed short *)malloc(samplen * sizeof(signed short)); | ||
73 | signed short *dsp_buf_ptr = dsp_buf; | ||
74 | |||
75 | int raw_fd; | ||
76 | raw_fd = open(ACGUITAR_PATH_S, O_RDONLY); | ||
77 | |||
78 | if (raw_fd < 0){ | ||
79 | fprintf(stderr, "Failed to open raw file (%s)\n", strerror(errno)); | ||
80 | exit(-1); | ||
81 | } | ||
82 | |||
83 | int totread = 0; | ||
84 | int i; | ||
85 | |||
86 | while (totread < samplen*2){ | ||
87 | int want = samplen*2 - totread; | ||
88 | |||
89 | int numread = read(raw_fd, dsp_buf_ptr, want); | ||
90 | fprintf(stderr, "read %d bytes\n", numread); | ||
91 | totread += numread; | ||
92 | dsp_buf_ptr += numread/2; | ||
93 | |||
94 | if (numread == 0){ | ||
95 | fprintf(stderr, "failed to read bytes\n"); | ||
96 | exit(-1); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | close(raw_fd); | ||
101 | |||
102 | // scale down a bit for mixing | ||
103 | for (i=0;i<samplen;i++){ | ||
104 | dsp_buf[i] /= 6; | ||
105 | } | ||
106 | |||
107 | set_tonebank(0, dsp_buf, samplen); | ||
108 | set_tonebank(1, dsp_buf, samplen); | ||
109 | set_tonebank(2, dsp_buf, samplen); | ||
110 | set_tonebank(3, dsp_buf, samplen); | ||
111 | set_tonebank(4, dsp_buf, samplen); | ||
112 | set_tonebank(5, dsp_buf, samplen); | ||
113 | set_tonebank(6, dsp_buf, samplen); | ||
114 | |||
115 | } | ||
116 | |||
117 | void gs::set_tonebank(int tb, signed short *buf, int length) | ||
118 | { | ||
119 | switch(tb){ | ||
120 | case 0: | ||
121 | tonebank0 = buf; | ||
122 | tonebank_length0 = length; | ||
123 | break; | ||
124 | case 1: | ||
125 | tonebank1 = buf; | ||
126 | tonebank_length1 = length; | ||
127 | break; | ||
128 | case 2: | ||
129 | tonebank2 = buf; | ||
130 | tonebank_length2 = length; | ||
131 | break; | ||
132 | case 3: | ||
133 | tonebank3 = buf; | ||
134 | tonebank_length3 = length; | ||
135 | break; | ||
136 | case 4: | ||
137 | tonebank4 = buf; | ||
138 | tonebank_length4 = length; | ||
139 | break; | ||
140 | case 5: | ||
141 | tonebank5 = buf; | ||
142 | tonebank_length5 = length; | ||
143 | break; | ||
144 | case 6: | ||
145 | tonebank6 = buf; | ||
146 | tonebank_length6 = length; | ||
147 | break; | ||
148 | |||
149 | } | ||
150 | } | ||
151 | |||
152 | |||
153 | void gs::Finger(int f, int position){ | ||
154 | if (f < 0 || f > 5){ | ||
155 | fprintf(stderr, "Error - finger2 value was %d\n", f); | ||
156 | return; | ||
157 | } | ||
158 | |||
159 | finger[f] = position; | ||
160 | } | ||
161 | |||
162 | void gs::Tuning(int t[6]){ | ||
163 | for (int i=0;i<6;i++){ | ||
164 | tuning[i] = t[i]; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | // length in ps (seconds x 10^-9) of the period of a note. | ||
169 | // we use these as ratios in a breshenham-like algorithm to | ||
170 | // scale a deep note to a higher pitch | ||
171 | // They are derived from f(A) = 440Hz and multiply each successive | ||
172 | // semitone by the 12th root of 2 (such that after 12 multiplications for | ||
173 | // 12 semitones you have a note exactly 2x the frequency of the initial one, | ||
174 | // - an octave higher in other words.) | ||
175 | |||
176 | int gs::note_periods[12] = { | ||
177 | 90703, | ||
178 | 85612, | ||
179 | 80802, | ||
180 | 76272, | ||
181 | 71991, | ||
182 | 67950, | ||
183 | 64137, | ||
184 | 60537, | ||
185 | 57139, | ||
186 | 53932, | ||
187 | 50905, | ||
188 | 48048 | ||
189 | }; | ||
190 | |||
191 | int gs::octave_step[6] = { | ||
192 | 1, | ||
193 | 2, | ||
194 | 4, | ||
195 | 8, | ||
196 | 16, | ||
197 | 32 | ||
198 | }; | ||
199 | |||
200 | int gs::Play(){ | ||
201 | int format; | ||
202 | int channels; | ||
203 | int speed; | ||
204 | |||
205 | frames = 0; | ||
206 | |||
207 | if (audio_fd == -1){ | ||
208 | if ( (audio_fd = open("/dev/dsp", O_WRONLY, 0) ) == -1){ | ||
209 | audio_fd = -1; | ||
210 | return 1; | ||
211 | } | ||
212 | |||
213 | format = AFMT_S16_NE; | ||
214 | |||
215 | if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format) == -1){ | ||
216 | fprintf(stderr, "Error SNDCTL DSP SETFMT, %s\n", strerror(errno)); | ||
217 | exit(0); | ||
218 | } | ||
219 | |||
220 | channels = 1; | ||
221 | |||
222 | if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels) == -1){ | ||
223 | fprintf(stderr, "Error SNDCTL DSP CHANNELS, %s\n", strerror(errno)); | ||
224 | exit(0); | ||
225 | } | ||
226 | |||
227 | speed = 11025; | ||
228 | |||
229 | if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed) == -1){ | ||
230 | fprintf(stderr, "Error SNDCTL DSP SPEED, %s\n", strerror(errno)); | ||
231 | exit(0); | ||
232 | } | ||
233 | |||
234 | // buffering q's | ||
235 | //audio_buf_info info; | ||
236 | //if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) == -1){ | ||
237 | // fprintf(stderr, "Error SNDCTL DSP GETOSPACE, %s\n", strerror(errno)); | ||
238 | // exit(0); | ||
239 | //} | ||
240 | //fprintf(stderr, "fragments %d\nfragstotal %d\nfragsize %d\nbytes %d\n", info.fragments, info.fragstotal, info.fragsize, info.bytes); | ||
241 | |||
242 | |||
243 | |||
244 | // audio math. | ||
245 | // A4 = 440Hz | ||
246 | // +1 octave = 2x freq | ||
247 | // -1 octave = /2 freq. | ||
248 | // +1 semitone = *= 12 root 2; | ||
249 | // ie. * 1.059463094 | ||
250 | |||
251 | // tones, approx Hz, samples at 11025 | ||
252 | // A4 440 25 | ||
253 | // A#4 466 24 | ||
254 | // B4 494 22 | ||
255 | // C4 523 21 | ||
256 | // C#4 554 20 | ||
257 | // D4 587 19 | ||
258 | // D#4 622 18 | ||
259 | // E4 659 17 | ||
260 | // F4 698 16 | ||
261 | // F#4 740 15 | ||
262 | // G4 784 14 | ||
263 | // G#4 831 13 | ||
264 | |||
265 | |||
266 | } | ||
267 | else{ | ||
268 | fprintf(stderr, "Already playing\n"); | ||
269 | } | ||
270 | |||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | void gs::note_start(int chan, int note, int octave) | ||
275 | { | ||
276 | switch (chan){ | ||
277 | |||
278 | case 0: | ||
279 | pb_rate0 = note_periods[note]; | ||
280 | pb_oct0 = octave_step[octave]; | ||
281 | pb_ratio0 = 0; | ||
282 | pb_rsc0 = 0; | ||
283 | break; | ||
284 | case 1: | ||
285 | pb_rate1 = note_periods[note]; | ||
286 | pb_oct1 = octave_step[octave]; | ||
287 | pb_ratio1 = 0; | ||
288 | pb_rsc1 = 0; | ||
289 | break; | ||
290 | case 2: | ||
291 | pb_rate2 = note_periods[note]; | ||
292 | pb_oct2 = octave_step[octave]; | ||
293 | pb_ratio2 = 0; | ||
294 | pb_rsc2 = 0; | ||
295 | break; | ||
296 | case 3: | ||
297 | pb_rate3 = note_periods[note]; | ||
298 | pb_oct3 = octave_step[octave]; | ||
299 | pb_ratio3 = 0; | ||
300 | pb_rsc3 = 0; | ||
301 | break; | ||
302 | case 4: | ||
303 | pb_rate4 = note_periods[note]; | ||
304 | pb_oct4 = octave_step[octave]; | ||
305 | pb_ratio4 = 0; | ||
306 | pb_rsc4 = 0; | ||
307 | break; | ||
308 | case 5: | ||
309 | pb_rate5 = note_periods[note]; | ||
310 | pb_oct5 = octave_step[octave]; | ||
311 | pb_ratio5 = 0; | ||
312 | pb_rsc5 = 0; | ||
313 | break; | ||
314 | case 6: | ||
315 | pb_rate6 = note_periods[note]; | ||
316 | pb_oct6 = octave_step[octave]; | ||
317 | pb_ratio6 = 0; | ||
318 | pb_rsc6 = 0; | ||
319 | break; | ||
320 | default: | ||
321 | fprintf(stderr, "Bad channel\n"); | ||
322 | exit(-1); | ||
323 | } | ||
324 | |||
325 | |||
326 | } | ||
327 | |||
328 | void gs::write_buffer(){ | ||
329 | int num_read; | ||
330 | num_read = write(audio_fd, (void *)audio_buf, BUFSIZE*2); | ||
331 | // fprintf(stderr, "Wrote %d bytes\n", num_read); | ||
332 | } | ||
333 | |||
334 | void gs::fill_buffer() | ||
335 | { | ||
336 | frames ++; | ||
337 | |||
338 | int i; | ||
339 | |||
340 | for (i=0;i<BUFSIZE;i++){ | ||
341 | |||
342 | audio_buf[i] = 0; | ||
343 | |||
344 | if (pb_rate0){ | ||
345 | audio_buf[i] += tonebank0[pb_rsc0]; | ||
346 | pb_rsc0 += pb_oct0; | ||
347 | pb_ratio0 += 90703; | ||
348 | pb_ratio0 -= pb_rate0; | ||
349 | if (pb_ratio0 >= pb_rate0){ | ||
350 | pb_rsc0 += pb_oct0; | ||
351 | pb_ratio0 -= pb_rate0; | ||
352 | |||
353 | } | ||
354 | if (pb_rsc0 >= tonebank_length0) pb_rate0 = 0; | ||
355 | } | ||
356 | |||
357 | if (pb_rate1){ | ||
358 | audio_buf[i] += tonebank1[pb_rsc1]; | ||
359 | pb_rsc1 += pb_oct1; | ||
360 | pb_ratio1 += 90703; | ||
361 | pb_ratio1 -= pb_rate1; | ||
362 | if (pb_ratio1 >= pb_rate1){ | ||
363 | pb_rsc1 += pb_oct1; | ||
364 | pb_ratio1 -= pb_rate1; | ||
365 | |||
366 | } | ||
367 | if (pb_rsc1 >= tonebank_length1) pb_rate1 = 0; | ||
368 | } | ||
369 | |||
370 | if (pb_rate2){ | ||
371 | audio_buf[i] += tonebank2[pb_rsc2]; | ||
372 | pb_rsc2 += pb_oct2; | ||
373 | pb_ratio2 += 90703; | ||
374 | pb_ratio2 -= pb_rate2; | ||
375 | if (pb_ratio2 >= pb_rate2){ | ||
376 | pb_rsc2 += pb_oct2; | ||
377 | pb_ratio2 -= pb_rate2; | ||
378 | |||
379 | } | ||
380 | if (pb_rsc2 >= tonebank_length2) pb_rate2 = 0; | ||
381 | } | ||
382 | |||
383 | if (pb_rate3){ | ||
384 | audio_buf[i] += tonebank3[pb_rsc3]; | ||
385 | pb_rsc3 += pb_oct3; | ||
386 | pb_ratio3 += 90703; | ||
387 | pb_ratio3 -= pb_rate3; | ||
388 | if (pb_ratio3 >= pb_rate3){ | ||
389 | pb_rsc3 += pb_oct3; | ||
390 | pb_ratio3 -= pb_rate3; | ||
391 | |||
392 | } | ||
393 | if (pb_rsc3 >= tonebank_length3) pb_rate3 = 0; | ||
394 | } | ||
395 | |||
396 | if (pb_rate4){ | ||
397 | audio_buf[i] += tonebank4[pb_rsc4]; | ||
398 | pb_rsc4 += pb_oct4; | ||
399 | pb_ratio4 += 90703; | ||
400 | pb_ratio4 -= pb_rate4; | ||
401 | if (pb_ratio4 >= pb_rate4){ | ||
402 | pb_rsc4 += pb_oct4; | ||
403 | pb_ratio4 -= pb_rate4; | ||
404 | |||
405 | } | ||
406 | if (pb_rsc4 >= tonebank_length4) pb_rate4 = 0; | ||
407 | } | ||
408 | |||
409 | if (pb_rate5){ | ||
410 | audio_buf[i] += tonebank5[pb_rsc5]; | ||
411 | pb_rsc5 += pb_oct5; | ||
412 | pb_ratio5 += 90703; | ||
413 | pb_ratio5 -= pb_rate5; | ||
414 | if (pb_ratio5 >= pb_rate5){ | ||
415 | pb_rsc5 += pb_oct5; | ||
416 | pb_ratio5 -= pb_rate5; | ||
417 | |||
418 | } | ||
419 | if (pb_rsc5 >= tonebank_length5) pb_rate5 = 0; | ||
420 | } | ||
421 | |||
422 | if (pb_rate6){ | ||
423 | audio_buf[i] += tonebank6[pb_rsc6]; | ||
424 | pb_rsc6 += pb_oct6; | ||
425 | pb_ratio6 += 90703; | ||
426 | pb_ratio6 -= pb_rate6; | ||
427 | if (pb_ratio6 >= pb_rate6){ | ||
428 | pb_rsc6 += pb_oct6; | ||
429 | pb_ratio6 -= pb_rate6; | ||
430 | |||
431 | } | ||
432 | if (pb_rsc6 >= tonebank_length6) pb_rate6 = 0; | ||
433 | } | ||
434 | |||
435 | // do reverb | ||
436 | signed short rtmp = reverb[reverb_ptr]; | ||
437 | reverb[reverb_ptr] /= 2; | ||
438 | reverb[reverb_ptr] += audio_buf[i]/4; | ||
439 | audio_buf[i] += rtmp; | ||
440 | reverb_ptr++; | ||
441 | if (reverb_ptr >= reverb_max) reverb_ptr = 0; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | |||
446 | void gs::Stop(){ | ||
447 | if (audio_fd == -1){ | ||
448 | fprintf(stderr, "Already stopped\n"); | ||
449 | } | ||
450 | else{ | ||
451 | //ioctl(audio_fd, SNDCTL_DSP_RESET, 0); | ||
452 | |||
453 | close(audio_fd); | ||
454 | audio_fd = -1; | ||
455 | } | ||
456 | |||
457 | } | ||
458 | |||
459 | gs::~gs() | ||
460 | {} | ||