annotate tools/mktables.c @ 0:c84446dfb3f5

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