dos33fsprogs/music/ksp_theme/notes.c

149 lines
3.2 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <string.h>
/* https://sourceforge.net/p/ed2midi/code/ */
/* From a spreadsheet from ed2midi */
/* Octave 1 2 3 4 5
A 255 128 64 32 16
A#/B- 240 120 60 30 15
B 228 114 57 28 14
C 216 108 54 27 13
C#/D- 204 102 51 25 12
D 192 96 48 24 12
D#/E- 180 90 45 22 11
E 172 86 43 21 10
F 160 80 40 20 10
F#/G- 152 76 38 19 9
G 144 72 36 18 9
G#/A- 136 68 34 17 8
*/
int note_to_ed(char note, int flat, int sharp, int octave) {
int value=0,result=0;
int octave_divider[5]={1,2,4,8,16};
switch(note) {
case 'A':
if (flat==1) value=272;
else if (sharp==1) value=240;
else value=256;
break;
case 'B':
if (flat==1) value=240;
else if (sharp==1) value=216;
else value=228;
break;
case 'C':
if (flat==1) value=228;
else if (sharp==1) value=204;
else value=216;
break;
case 'D':
if (flat==1) value=204;
else if (sharp==1) value=180;
else value=192;
break;
case 'E':
if (flat==1) value=180;
else if (sharp==1) value=160;
else value=172;
break;
case 'F':
if (flat==1) value=172;
else if (sharp==1) value=152;
else value=160;
break;
case 'G':
if (flat==1) value=152;
else if (sharp==1) value=136;
else value=144;
break;
default:
fprintf(stderr,"Unknown note %c\n",note);
}
if ((octave<1) || (octave>5)) {
fprintf(stderr,"Invalid octave %d\n",octave);
return -1;
}
result=value/octave_divider[octave-1];
if (result>255) result=255;
return result;
}
static struct note_mapping_type {
int freq[12];
} note_mapping[5]={
/* A A# B C C# D D# E F F# G G# */
{{ 255,240,228,216,204,192,180,172,160,152,144,136}}, // 1
{{ 128,120,114,108,102, 96, 90, 86, 80, 76, 72, 68}}, // 2
{{ 64, 60, 57, 54, 51, 48, 45, 43, 40, 38, 36, 34}}, // 3
{{ 32, 30, 28, 27, 25, 24, 22, 21, 20, 19, 18, 17}}, // 4
{{ 16, 15, 14, 13, 12, 12, 11, 10, 10, 9, 9, 8}}, // 5
};
static char notes[12]= {'A','A','B','C','C','D','D','E','F','F','G','G'};
static char sharps[12]={' ','#',' ',' ','#',' ','#',' ',' ','#',' ','#'};
char *ed_to_note(int freq, char *out) {
int i,j;
int note=0,octave=0,notefound=0;;
// printf("Freq=%d\n",freq);
for(i=0;i<5;i++) {
if ((freq<=note_mapping[i].freq[0]) &&
(freq>=note_mapping[i].freq[11])) {
octave=i+1;
break;
}
}
for(j=0;j<12;j++) {
if (freq==note_mapping[i].freq[j]) {
note=j;
notefound=1;
break;
}
}
if ((!notefound) && (freq>28)) {
for(j=0;j<12;j++) {
if ((freq+1)==note_mapping[i].freq[j]) {
note=j;
notefound=1;
break;
}
}
}
if ((!notefound) && (freq>28)) {
for(j=0;j<12;j++) {
if ((freq-1)==note_mapping[i].freq[j]) {
note=j;
notefound=1;
break;
}
}
}
if (!notefound) {
sprintf(out,"%3d",freq);
}
else {
out[0]=notes[note];
out[1]=sharps[note];
out[2]=octave+'0';
}
out[3]=0;
return out;
}