Mercurial > hg > index.fcgi > lj > lj046
comparison tools/mktables.c @ 0:c84446dfb3f5
initial add
author | paulo@localhost |
---|---|
date | Fri, 13 Mar 2009 00:39:12 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:82b9cb16b44a |
---|---|
1 #include <stdlib.h> | |
2 #include <stdio.h> | |
3 #include <math.h> | |
4 | |
5 /* | |
6 Pin Eight standard tuning defines middle C as 2093/8 Hz. | |
7 It uses equal temperament: a semitone difference between two pitches | |
8 is a factor of 2^(1/12) between their frequencies. | |
9 Thus, MIDI 0 = 60, or 2093/256. | |
10 */ | |
11 #define C_IN_OCTAVE(octave) \ | |
12 ((double)((long int)2093 << octave) / 256.0) | |
13 #define TWELFTH_ROOT_OF_TWO 1.0594630943592952645618252949463 | |
14 | |
15 /* | |
16 DS note frequencies for the tone generator at 8 samples per period | |
17 are ((-0x1000000 / (n * 8))) | |
18 */ | |
19 #define FREQ_TO_PSG_PERIOD(freq) \ | |
20 ((unsigned short)(-0x1000000 / (freq * 8))) | |
21 | |
22 | |
23 int writePSG(FILE *fp) { | |
24 | |
25 // write header | |
26 fputs(".section .rodata\n" | |
27 ".balign 4\n" | |
28 ".global midi2psgFreq\n" | |
29 "midi2psgFreq:", fp); | |
30 | |
31 int octave = 0; | |
32 | |
33 for (; octave < 2; ++octave) { | |
34 fprintf(fp, "\n@ unsupported octave %d\n.byte ", octave); | |
35 for (int semitone = 0; semitone < 12; ++semitone) { | |
36 if (semitone) { | |
37 fputs(", ", fp); | |
38 } | |
39 fputs(" 0, 0", fp); | |
40 } | |
41 } | |
42 for (; octave < 10; ++octave) { | |
43 double freq = C_IN_OCTAVE(octave); | |
44 fprintf(fp, "\n@ octave %d\n.byte ", octave); | |
45 for (int semitone = 0; semitone < 12; ++semitone) { | |
46 if (semitone) { | |
47 fputs(", ", fp); | |
48 freq *= TWELFTH_ROOT_OF_TWO; | |
49 } | |
50 unsigned int psgFreq = FREQ_TO_PSG_PERIOD(freq); | |
51 printf("midi %2d = %.2f = psg %5d\n", | |
52 octave * 12 + semitone, | |
53 freq, | |
54 psgFreq); | |
55 fprintf(fp, "%3u,%3u", | |
56 psgFreq & 0xFF, | |
57 (psgFreq >> 8) & 0xFF); | |
58 } | |
59 } | |
60 | |
61 fputs("\n", fp); | |
62 return 0; | |
63 } | |
64 | |
65 /** | |
66 * Writes lookup tables used by the ARM7 code. | |
67 * Currently, these include the PSG pitch values. | |
68 */ | |
69 int writeARM7(const char *filename) { | |
70 FILE *fp = fopen(filename, "wt"); | |
71 if (!fp) { | |
72 return -1; | |
73 } | |
74 if (writePSG(fp) < 0) { | |
75 fclose(fp); | |
76 return -1; | |
77 } | |
78 fclose(fp); | |
79 return 0; | |
80 } | |
81 | |
82 | |
83 int main(void) { | |
84 if (writeARM7("obj/ds/lookup_tables7.s") < 0) { | |
85 return EXIT_FAILURE; | |
86 } | |
87 return EXIT_SUCCESS; | |
88 } |