#include #include /* 0 = C1, 84 = C8 */ double note_freq(int note) { double freq; note -= 45; /* Make A4 = 0. A4 is 440Hz */ freq = 440.0 * pow(2.0, (double)note / 12.0); } double ntsc_period(double freq) { return 3579545.0 / 32.0 / freq; } double pal_period(double freq) { return 4000000.0 / 32.0 / freq; } const char *note_names[12] = { "C%d", "C#%d / Db%d", "D%d", "D#%d / Eb%d", "E%d", "F%d", "F#%d / Gb%d", "G%d", "G#%d / Ab%d", "A%d", "A#%d / Bb%d", "B%d", }; const char *note_name(int note) { int octave; static char buf[10]; if (note < 0) { buf[0] = 0; return buf; } octave = 1 + note / 12; note %= 12; sprintf(buf, note_names[note], octave, octave); return buf; } const char *note_labels[12][2] = { { "C%d", NULL }, { "Cs%d","Db%d" }, { "D%d", NULL }, { "Ds%d","Eb%d" }, { "E%d", NULL }, { "F%d", NULL }, { "Fs%d","Gb%d" }, { "G%d", NULL }, { "Gs%d","Ab%d" }, { "A%d", NULL }, { "As%d","Bb%d" }, { "B%d", NULL }, }; const char *note_label(int note, int sf) { int octave; static char buf[10]; if (note < 0 || sf < 0 || sf > 1) return NULL; octave = 1 + note / 12; note %= 12; if (note_labels[note][sf] == NULL) return NULL; sprintf(buf, note_labels[note][sf], octave); return buf; } int main(void) { int i, pi; double p, f, fr, err; const char *lbl, *name; printf(";; This file was autogenerated.\n"); printf(";;\n"); printf(";; The author of the generating program, Joseph Zbiciak\n"); printf(";; hereby puts both the generator and its output in the\n"); printf(";; public domain. The data below is therefore public domain.\n"); printf(";;\n"); printf(";; You can compare the computed frequencies versus the ideal\n"); printf(";; values using this chart online:\n"); printf(";; http://www.phy.mtu.edu/~suits/notefreqs.html\n"); printf("\n\n"); printf("NOTES.NTSC PROC\n"); for (i = 0; i < 85; i++) { p = ntsc_period(f = note_freq(i)); pi = (int)floor(p + 0.5); fr = ntsc_period(pi); err = 100.0 * ((fr / f) - 1.0); /* relative error */ if ((lbl = note_label(i, 1)) != NULL) printf("@@%s\n", lbl); lbl = note_label(i, 0); name = note_name(i); printf( "@@%-4s DECLE $%.4X ; %-10s %7.2f Hz (%+1.3f%% err)\n", lbl, pi, name, fr, err); } printf(" ENDP\n"); printf("\n\n"); printf("NOTES.PAL PROC\n"); for (i = 0; i < 85; i++) { p = pal_period(f = note_freq(i)); pi = (int)floor(p + 0.5); fr = pal_period(pi); err = 100.0 * ((fr / f) - 1.0); /* relative error */ if ((lbl = note_label(i, 1)) != NULL) printf("@@%s\n", lbl); lbl = note_label(i, 0); name = note_name(i); printf( "@@%-4s DECLE $%.4X ; %-10s %7.2f Hz (%+1.3f%% err)\n", lbl, pi, name, fr, err); } printf(" ENDP\n"); printf(";; End of note data\n"); return 0; }