/* a2freq - convert MIDI note numbers or scientific pitch notations to frequencies */ /* by Antoine Amarilli (2011) */ /* licence: public domain */ /* compilation: cc -lm -o a2freq a2freq.c */ #include #include #include #define E_ARGS 1 #define E_PARSE 2 #define BAD_ACCID 42 float key2freq(int n) { /* Return frequency of midi note number n, inspired per the "Piano key * frequencies" article on wikipedia */ return 440 * pow(2, ((float) (n - 69))/12); } int name2num(char name) { /* Return note number adjustment for upper case scientific pitch * notation note name name. Return <0 on error. */ switch(name) { case 'C': return 0; break; case 'D': return 2; break; case 'E': return 4; break; case 'F': return 5; break; case 'G': return 7; break; case 'A': return 9; break; case 'B': return 11; break; default: return -1; } } int accid2num(char accid) { /* Return note number adjustment for scientific pitch notation note * accidental. Return <0 on error. */ switch (accid) { case 'b': return -1; break; case '#': return 1; break; default: return BAD_ACCID; } } int note2num(int octave, int note) { /* Return MIDI note number for octave and note. */ return (octave + 1)*12 + (note); } float pitch2freq(char* a) { /* Return frequency of scientific pitch notation note a, by converting * it to a key number and using key2freq. Return <0 on parse error. */ int note, octave = 4, accid, num; int octavepos = 1; // position where octave indication is expected /* parse note name */ if (!a[0]) return -1; note = name2num(toupper(a[0])); if (note < 0) return note; /* parse accidental */ if (a[octavepos] && !isdigit(a[octavepos])) { accid = accid2num(a[octavepos]); if (accid == BAD_ACCID) return -1; note += accid; octavepos++; } /* parse octave */ num = !a[octavepos]?note2num(octave, note):note2num(atoi(a + octavepos), note); return key2freq(num); } float do_one(char* a) { int result; if (result = atoi(a)) return key2freq(result); else return pitch2freq(a); } int main(int argc, char** argv) { int i; double result; if (argc <= 1) { fprintf(stderr, "Usage: %s [NOTE]...\n", argv[0]); fprintf(stderr, "Convert MIDI note numbers or scientific pitch notations to frequencies.\n"); fprintf(stderr, "NOTE is either a MIDI note number or a key in scientific pitch notation.\n"); fprintf(stderr, "Scientific pitch notation examples: \"A4\", \"C#2\", \"Bb6\"\n"); return E_ARGS; } for (i=1; i= 0) printf("%f\n", result); else { fprintf(stderr, "a2freq: cannot parse %s\n", argv[i]); return E_PARSE; } } return 0; }