Mercurial > hg > index.fcgi > lj > lj046
diff tools/mktables.c @ 0:c84446dfb3f5
initial add
author | paulo@localhost |
---|---|
date | Fri, 13 Mar 2009 00:39:12 -0700 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/tools/mktables.c Fri Mar 13 00:39:12 2009 -0700 1.3 @@ -0,0 +1,88 @@ 1.4 +#include <stdlib.h> 1.5 +#include <stdio.h> 1.6 +#include <math.h> 1.7 + 1.8 +/* 1.9 +Pin Eight standard tuning defines middle C as 2093/8 Hz. 1.10 +It uses equal temperament: a semitone difference between two pitches 1.11 +is a factor of 2^(1/12) between their frequencies. 1.12 +Thus, MIDI 0 = 60, or 2093/256. 1.13 +*/ 1.14 +#define C_IN_OCTAVE(octave) \ 1.15 + ((double)((long int)2093 << octave) / 256.0) 1.16 +#define TWELFTH_ROOT_OF_TWO 1.0594630943592952645618252949463 1.17 + 1.18 +/* 1.19 +DS note frequencies for the tone generator at 8 samples per period 1.20 +are ((-0x1000000 / (n * 8))) 1.21 +*/ 1.22 +#define FREQ_TO_PSG_PERIOD(freq) \ 1.23 + ((unsigned short)(-0x1000000 / (freq * 8))) 1.24 + 1.25 + 1.26 +int writePSG(FILE *fp) { 1.27 + 1.28 + // write header 1.29 + fputs(".section .rodata\n" 1.30 + ".balign 4\n" 1.31 + ".global midi2psgFreq\n" 1.32 + "midi2psgFreq:", fp); 1.33 + 1.34 + int octave = 0; 1.35 + 1.36 + for (; octave < 2; ++octave) { 1.37 + fprintf(fp, "\n@ unsupported octave %d\n.byte ", octave); 1.38 + for (int semitone = 0; semitone < 12; ++semitone) { 1.39 + if (semitone) { 1.40 + fputs(", ", fp); 1.41 + } 1.42 + fputs(" 0, 0", fp); 1.43 + } 1.44 + } 1.45 + for (; octave < 10; ++octave) { 1.46 + double freq = C_IN_OCTAVE(octave); 1.47 + fprintf(fp, "\n@ octave %d\n.byte ", octave); 1.48 + for (int semitone = 0; semitone < 12; ++semitone) { 1.49 + if (semitone) { 1.50 + fputs(", ", fp); 1.51 + freq *= TWELFTH_ROOT_OF_TWO; 1.52 + } 1.53 + unsigned int psgFreq = FREQ_TO_PSG_PERIOD(freq); 1.54 + printf("midi %2d = %.2f = psg %5d\n", 1.55 + octave * 12 + semitone, 1.56 + freq, 1.57 + psgFreq); 1.58 + fprintf(fp, "%3u,%3u", 1.59 + psgFreq & 0xFF, 1.60 + (psgFreq >> 8) & 0xFF); 1.61 + } 1.62 + } 1.63 + 1.64 + fputs("\n", fp); 1.65 + return 0; 1.66 +} 1.67 + 1.68 +/** 1.69 + * Writes lookup tables used by the ARM7 code. 1.70 + * Currently, these include the PSG pitch values. 1.71 + */ 1.72 +int writeARM7(const char *filename) { 1.73 + FILE *fp = fopen(filename, "wt"); 1.74 + if (!fp) { 1.75 + return -1; 1.76 + } 1.77 + if (writePSG(fp) < 0) { 1.78 + fclose(fp); 1.79 + return -1; 1.80 + } 1.81 + fclose(fp); 1.82 + return 0; 1.83 +} 1.84 + 1.85 + 1.86 +int main(void) { 1.87 + if (writeARM7("obj/ds/lookup_tables7.s") < 0) { 1.88 + return EXIT_FAILURE; 1.89 + } 1.90 + return EXIT_SUCCESS; 1.91 +}